I am trying to make multiple instances of my “Fly” object so that I can control the position and movement of each one independently. I am new to C# and I think I am missing something critical in my understanding here. Any light shining would be VERY appreciated.
I have my Fly.cs:
using UnityEngine;
using System.Collections;
public class Fly : MonoBehaviour {
public float myX,myY,myZ;
public float targetX,targetY,targetZ;
public Transform myFly;
}
Then I have my FlySystem.cs where I am trying to control multiple instances of Fly.
using UnityEngine;
using System.Collections;
public class FlySystem : MonoBehaviour {
public int numberOfFlies = 5;
private Fly[] flyList;
void Start(){
flyList = new Fly[numberOfFlies];
CreateFlies ();
}
void CreateFlies(){
for (int i=0; i < numberOfFlies; i++) {
flyList[i] = GetComponent<Fly>();
Debug.Log (flyList[i]);
}
}
}
Problem is, flyList is coming back Null, which means if I try to reference it obviously I get errors saying it isn’t an object. I do not really understand where to go from here.
The problem is this line flyList[i] = GetComponent<Fly>();
This method assumes there is a monobehaviour called Fly on the same object as your FlySystem, which you obviously don’t have as it is returning null. It would also always just return the same Fly, so you would end up with an array where all the elements were the same Fly.
Instead, you could just make your flyList public, and then just assign all the flies in the inspector. This way, you wouldn’t need any of the code you have in your FlySystem class other than public Fly[ ] flyList;
Another way to solve this, is to create the flies as children of your FlySystem object in the editor, and then use GetComponentsInChildren to get all the flies like so
public class FlySystem : MonoBehaviour {
private Fly[] flyList;
void Start() {
flyList = GetComponentsInChildren<Fly>();
}
}
Either way should work fine, but having the flies as children might make more sense.
I see what you are saying, and that makes sense. I think my end goal may be a bit foggy here.
Maybe if I show you my original code before I created Fly.cs it would make a bit more sense, you could also see my desired end results a little better.
using UnityEngine;
using System.Collections;
public class FlySystem : MonoBehaviour {
public Transform flyVis;
public int numberOfFlies = 5;
private Transform obj;
private BoxCollider container;
private float maxX, maxY, maxZ;
private bool created = false;
private Transform[] flyList;
void Start(){
obj = GetComponent<Transform> ();
container = obj.GetChild (0).GetComponent<BoxCollider>();
flyList = new Transform[numberOfFlies];
maxX = container.bounds.extents.x;
maxY = container.bounds.extents.y;
maxZ = container.bounds.extents.z;
CreateFlies ();
}
void CreateFlies(){
Vector3 myPos;
float myX, myY, myZ;
Transform f;
for (int i=0; i < numberOfFlies; i++) {
myX = container.bounds.center.x - Random.Range(-maxX,maxX);
myY = container.bounds.center.y - Random.Range(-maxY,maxY);
myZ = container.bounds.center.z - Random.Range(-maxZ,maxZ);
myPos = new Vector3(myX,myY,myZ);
f = Instantiate(flyVis, myPos, Quaternion.identity) as Transform;
flyList[i] = f;
}
created = true;
}
void FixedUpdate(){
if(created){
moveFlies();
}
}
void moveFlies(){
for (int i=0; i < numberOfFlies; i++) {
Debug.Log(flyList[i]);
/*How to set each one on it's own random path?
this method will have all of them going to the same
random position all the time, which isn't what I want.
So I created Fly.cs to try and set a custom Paramater for
each Fly, "targetPos" that would be unique for each fly
*/
}
}
}
Well if you really want to create them from code, you can do it something like this
void CreateFlies(){
for (int i=0; i < numberOfFlies; i++) {
GameObject go = new GameObject("Fly " + i.ToString());
flyList[i] = go.AddComponent<Fly>();
Debug.Log (flyList[i]);
}
}
1 Like