(I'm new to Unity and probably jumping the gun a bit here) -
I'm getting myself a bit confused regarding instantiating prefabs. I have a GameObject (gameManager) that instantiates a prefab, and then sets the reference of the instantiated object to my LevelManager (stores a static gameObject)
I call on the reference to the instantiated object using the LevelManager (LevelManager.enemyPrefabInstance) in other scripts (for reasons such as grabbing the animator component). Because it is stored as static, I think every instantiation has shared components. If I instantiate two enemies and kill one at runtime (once dead the gameObject destroys itself), the 2nd looses its components because they've also been destroyed. I know I could change the prefab reference from static to non-static but I am trying to teach myself about static objects and how they work, so that defeats my purpose.
Is there a way to store all instantiated objects as a single static gameobject, so they all keep have their own individual components?
Many thanks in advance
EDIT - I'm being told instances do not share components regardless if they are stored as static or not. The exact error I get when I try and destory a 2nd instantiated clone is:
MissingReferenceException: The object of type "Animator" has been destroyed but you are still trying to access it. Your script should either check if it is null or not destroy the object.
GameManager Script:
Void Awake()
{
GameObject enemyPrefabInstantiated = Instantiate(enemyPrefab, position, rotation);
//instantiate gameObject
LevelManager.enemyPrefabInstantiated = enemyPrefabInstantiated;
//Set reference for LevelManager
}
LevelManager:
public static GameObject enemyPrefabInstantiated; //Stores static GameObject
Animator Script:
public Animator enemyAnim;
void Start()
{
enemyAnim = LevelManager.enemyPrefabInstantiated.GetComponent<Animator>();
//Gets animator component off instantiated prefab
}
void OnDestroy()
{
Destroy(enemyAnim.gameObject);
//destroy gameobject
}
Your reference is:
GameObject prefab; //your prefab you want to instantiate
GameObject obj1 =Instantiate(prefab);
//create your first gameobject
GameObject obj2 =Instantiate(prefab);
//and the second
The obj2 variable now only references the instantiated copy of the prefab.
Related
If that is not possible, can I at least find it using raytracing?
I want to make some enemy GameObjects (which are instantiated from a prefab, which spawn randomly) always look towards the player.
I don't think I can just call it's xyz coordinates, but maybe I can find them using raytracing? How exactly do I do that? Even if I know what raytracing is and used it before in other non-unity projects, I have no idea how to implement it in unity.
Your enemies should be able to get reference to player somehow (probably Singleton for entry level, or Dependency Injection for pros) and use player.transform.position
So basically your player should look like that:
public class Player : MonoBehaviour
{
public static Player Instance;
void Awake()
{
Instance = this;
}
}
And then enemy can use:
Player.Instance.transform.position
to get players position.
This question already has answers here:
How to access a variable from another script in another gameobject through GetComponent?
(3 answers)
Closed 25 days ago.
I am in no way a coding novice but I just picked up unity and I'm trying "get it"
My question involves this code. it is not part of an active project. it is simply an attempt to understand the system
private SpriteRenderer beans2;
public Sprite beanimmage;
// Start is called before the first frame update
void Start()
{
beans2 = gameObject.GetComponent<SpriteRenderer>();
beans2.sprite = beanimmage;
}
from what I understand this code allows me to manipulate the SpriteRenderer of the game object this code is attached to by assigning it to beans2 and then changing the Sprite of beans2 to beanimmage and works fine in the system
My question is -
Is their a way to assign beans2 to the spriterenderer of a diffident game object? The object i have this code attached to is just a game object called test is their a way to assign the beans2 variable to the SpriteRenderer of my test2 object instead ?
something like this ?
beans2 = test2.gameObject.GetComponent<SpriteRenderer>();
beans2 = gameObject.test2.GetComponent<SpriteRenderer>();
The GetComponent() Function is apart of every gameobject so to get components on other gameobjects you need to reference that gameobject in a variable, something like this:
public GameObject test2;
private SpriteRenderer test2Renderer;
public Sprite beanImage;
void Awake()
{
test2Renderer = test2.GetComponent<SpriteRenderer>();
test2Renderer.sprite = beanImage;
}
Alternatively, you can just get the component of the test2 object from the inspector because you are using public variables. To do this make a sprite renderer variable field and make it public so it is shown in the inspector, then drag the test2 object into the field and it will automatically get the sprite renderer component off that object.
Finally, you could also just do this with one field. This method would be used when you only want to access the GameObject and nothing else:
public GameObject test2;
public Sprite beansImage;
void Awake
{
test2.GetComponent<SpriteRenderer>().sprite = beansImage;
}
Any way works and you should do it the second way if you want to work with public variables and rely on the inspector but if you only need the gameobject then go with method 3. Method 1 is probably the best way to do it so you can change the sprite later if you want.
I have a gameObject as a sprite in my 2D game, and then in a different script I have an array of 2d textures, in a sprite array. I simple want to change the sprite's sprite property but get the error 'object reference not set to an instance of a object'.
Here is the line throwing the error, which is in one script.:
this.gameObject.GetComponent<SpriteRenderer> ().sprite = GameObject.Find ("UIM").GetComponent<Manager> ().spriteImages [1];
While the array, is in a different script, attached to the object 'UIM' in a different scene to the one I am trying to access it from (not sure if this causes the problem), is defined with:
public Sprite[] spriteImages = new Sprite[5];
Why am I getting this error? I have filled the array with the textures so cannot see the problem.
You are trying to access a script & variable from another scene. In unity whenever you load a new scene your old scene values will be destroyed and that will lead to 'object reference not set to an instance of a object' error. You can bring the tell the unity not to destroy the object which you will need in future scenes by calling DontDestroyOnLoad. This will allow the gameobject to persist across the scene.
One more thing you have to keep in mind is that if you are returning to the old scene where you marked the Object UIManager as dontdestroyonload then make sure the next instances are deleted and managed from the scene which is reloaded else whenever you keep on reloading the old scene with UImanager it will keep on piling up the instances of it across the scenes. The example in the unity with dontdestroyonload should be more than enough to solve your problems. Here is a snippet shown in Unity API which you can refer:
void Awake()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("music");
if (objs.Length > 1)
{
Destroy(this.gameObject);
}
DontDestroyOnLoad(this.gameObject);
}
You can try:
public GameObject[] objs =
SceneManager.GetSceneByName(sceneToLoad).GetRootGameObjects();
foreach(GameObject go in objs)
{
if(go.name == "UIM")
{
this.gameObject.GetComponent<SpriteRenderer> ().sprite =
go.GetComponent<Manager> ().spriteImages [1];
break;
}
}
I am trying to develop a small 2D Unity platformer to learn to work with Unity's interface. I have been having an issue trying to make a gameobject track clones of an enemy and follow it. The function is to make it so when you hover on the enemy clone, it shows the enemy's health. But when I hover on the enemy, it tracks the position of the original enemy, not the clone. Both gameobjects have the same name. What I want is the GameObject HoverDataDisplay (as shown in the screenshot) to track its sibling, Enemy.
The current code that I have for the tracking script is as shown:
private GameObject Enemy;
void Start() {
Enemy = GameObject.Find ("Enemy");
}
void Update(){
transform.position = new Vector3 (Enemy.transform.position.x - 0.57f, Enemy.transform.position.y + 1.5f, Enemy.transform.position.z);
}
But the GameObject (HoverDataDisplay) Only follows the original enemy.
Thanks for your help!
In Unity, you can use the forward slash "/" to find a Child of an Object. Since the name of the parents are different, you can easily find them like this:
GameObject.Find("EnemyObject/Enemy");
And the second HoverDataDisplay:
GameObject.Find("EnemyObject(Clone)/Enemy");
It's not really a good idea to let your GameObject use the default "Clone" name. You should rename it after instantiating it so that it will be easy to find. Only do this if you need to find the Object after instantiating it.
This script is attached to the HoverDataDisplay GameObject
You can actually get it's parent Object which is either EnemyObject or EnemyObject(Clone) with transform.parent then use the FindChild to find the enemy Object.
//First, Find the Parent Object which is either EnemyObject or EnemyObject(Clone)
Transform parent = transform.parent;
//Now, Find it's Enemy Object
GameObject enemy = parent.FindChild("Enemy").gameObject;
I recommend you use this method instead of the first one I mentioned. The first one is mentioned so that you will know it can be done.
EDIT:
Transform.FindChild is now deprecated. You can use Transform.Find to do that same exact thing.
You can get a reference to the parent then search through the parents children
// get a reference to the rb of the parent
parentRigidbody = gameObject.GetComponentInParent<Rigidbody>();
// a reference to the camera in a sibling object
playerCam = rigRigidbody.gameObject.GetComponentInChildren<Camera>();
The function I'm currently working on instantiates a GameObject (using a prefab). I store this GameObject in a local variable
GameObject tmpObject;
Works flawlessly. Next I try to assign this GameObject to my GameObject representation of my Vive controller, which looks like this:
tmpObject = tmpController.gameObject.AddComponent<GameObject>() as GameObject;
The error that I get is that UnityEngine.GameObject cannot be converted to UnityEngine.Component.
Am I missing a simple / basic there? I tried adding a SphereCollider as per Unity's official guidline and it did work, so why can't I add GameObject? Is there a workaround to adding GameObjects to another GameObject? Any help is greatly appreciated!
You can't add GameObject to a GameObject. That doesn't even make sense to begin with.You can only attach components. I think that you want to make a GameObject a child of another GameObject... You can use the SetParent function for that. See below for examples how to create a GameObject and of what you can do:
Create a new GameOBject named "BallObject"
GameObject a = new GameObject("BallObject");
Create a new GameOBject named "BrickObject"
GameObject b = new GameObject("BrickObject");
Make "BrickObject" Object parent of "BallObject" Object
a.transform.SetParent(b.transform);
Make the "BallObject" Object to be by itself. "BrickObject" Object is not it's parent anymore
a.transform.parent = null;
Add script/component to your "BrickObject" Object
b.AddComponent<Rigidbody>();