handras
handras

Reputation: 1628

Mark position of spawnpoints in editor

I am creating a digital boardgame, which consits of muliple boards, between which the gamepieces are moved by the players.

The script of the game board needs a 2D array of positions to know where to move a gamepiece when it recives one. Currently to mark the positions on the game boards, I added placeholder gameobjects to the prefab and named them "spawnpoint\d".In the Awake() method I use Transform.Find() to search for those gameobjects. Then, after I save their positions I call Destroy() on them, so they do not show up in the game.

I see two problems:

  1. This is done for all Instantiated game board, altough the positions are the same on all of them.
  2. I read that using Transform.Find() is heavily discourged by the experts in the community.

I wish to store the spawnpoint positions in a static array, so all instances refer to the same data. Furthermore I wish to easily modify these positions in the editor with visual help.

I tried serializing static members, but those do not show up in the editor to be able to modify.

    [SerializeField]
    public static int TestNumber;

TLDR: How to make static members visually changeable from the Unity editor?

Upvotes: 1

Views: 99

Answers (1)

derHugo
derHugo

Reputation: 90683

tl;dr you can't, static fields are not serialized.


You can do e.g.

[SerializeField] private Transform[] spawnPoints;
public static Transform[] SpawnPoints;

private void Awake ()
{
    SpawnPoints = spawnPoints;
}

In general I would suggest rather using something like this:

// Simply attach this class to each GameObject that shall be a spawn point 
// MAKE SURE IT IS ACTIVE AND ENABLED BY DEFAULT
public class SpawnPoint : MonoBehaviour
{
    // Each SpawnPoint (un)registers itself here
    private static readonly HasSet<SpawnPoint> _instances = new HashSet<SpawnPoint>();

    // For the public return a new HashSet to make sure nobody can modify the 
    // original _instances from the outside
    public static HashSet<SpawnPoint>() Instances => new HashSet<SpawnPoint>(_instancea);

    private void Awake()
    {
        // Register yourself to the existing instances
        _instances.Add(this);

        // Optional: make sure this object is not destroyed when a new scene is loaded
        DontDestroyOnLoad (gameObject);

        // simply hide the entire gameObject
        gameObject.SetActive(false);
    }

    private void Destroy ()
    {
        // Unregister yourself from the instances
        _instances.Remove(this);
    }
}

This way

  • each spawn point Auto-Registers itself to the Instances so you don't even need to serialize this via the Inspector -> you also can't forget any

  • the spawn points don't get Destroyed when a new scene is loaded (if you use the DontDestroyOnLoad - otherwise they are destroyed and auto-removed from the instances)

  • you disable the objects (though actually if they have nothing attached except this script it wouldn't matter anyway)

  • you can easily access all the spawn points without using expensive stuff like Find or FindObjectsOfType but rather simply via the property

     var availableSpawnPoints = SpawnPoint.Instances;
    

Upvotes: 1

Related Questions