0

I'm trying to find objects with "Creature" tag and fill an GameObject array to get a Turn Order.

In one script I created this:

public PlayerOrder[] playerOrder;

public void CalculateTurnOrder()
{
    GameObject[] creatures = GameObject.FindGameObjectsWithTag("Creature");
    playerOrder = new PlayerOrder[creatures.Length];

    int index = 0;
    foreach (GameObject creature in creatures)
    {
        playerOrder[index].playerObject = creature;

        index++;
    }

    
}

void Start()
{
    CalculateTurnOrder();
}

Then I went and created a class for my array:

[System.Serializable]
public class PlayerOrder
{
    public GameObject playerObject;

    // For now I'm disabling these, same error.
    // public string playerName;
    // public int dexMod;

}

The problem is that, I can get creatures with GameObject[] creatures = GameObject.FindGameObjectsWithTag("Creature"); , and it successfully exits foreach loop if I store GameObject information inside a variable. I think my problem is filling array with playerOrder[index].playerObject = creature; is not correct, but I don't know better.

I'm just stuck.

  • `new PlayerOrder[4];` creates an array with (for example) 4 _empty spaces_ (`null`) in which you can place instances of `PlayerOrder`. You're not creating any instances of `PlayerOrder` / you're not filling those empty spaces in the array with `PlayerOrder` instances. – ProgrammingLlama Jan 07 '22 at 03:12
  • Generally you want to avoid trying to find objects by _tag_ because **1)** tag names are **case-sensitive** **2)** it isn't type-safe. (as opposed to `FindObjectOfType`, though suffers from #3... ) e.g. you might ask for a camera and end up with a _red herring_. **3)** you won't know if your scene is correct until you run your code. **Alternatives:** consider using `[SerializeField] private Creature[] creatures;` instead where `Creature` is a `MonoBehaviour` attached to the creature game objects. Otherwise you won't know exaclty what type of game objects you are dealing with... –  Jan 07 '22 at 05:48
  • ...and override `Awake` and perform object validation there to ensure the required fields have been populated –  Jan 07 '22 at 05:49
  • As Llama pointed out you would need a new PlayerOrder() and once you have a new one you can assign creature to its playerObject field. So in the foreach loop do this: playerOrder[index] = new PlayerOrder() { playerObject = creature }; – Juri Knauth Jan 07 '22 at 07:51
  • 1
    Thank you for your responses, I couldn't get my head around how lists and arrays behaved in c#; after Llama commented I understand it more. I'll created what MickyD said for awake, and used what Juri Knauth said. It works like a charm. – Engin Bayram Jan 07 '22 at 13:33

0 Answers0