- Home /
Getting an object from another script...
I'm using a script that was written by someone else. In this script, the player is instantiated and the main camera follows this instance of the player model. When the player dies, that instance is destroyed and a new instance is created when the level restarts. I need to setup some items that follow the player but I'd like to put them in another script. How can I access the player that's instantiated by the first script so that I can read its position to set the following objects to have the same position (which I can then move to where I need it)?
I've tried using:
player = firstScript.Find("ThePlayer");
or
player = firstScript.Find("PlayerChar_01(Clone)"); (this is what the GameObject is labelled as in the project on runtime)
How can I do this? I keep getting errors about needing to create objects for non-static members and I have no idea what that means... Help!!
playerScript = GameObject.Find( "ThePlayer" ).GetComponent( PlayerScript );
playerScript.someVar = 10.0;
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.Find.html
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.GetComponent.html
Answer by ThePunisher · Nov 27, 2012 at 09:24 PM
Use the code that alucardj gave you, BUT first you will need to find the code that instantiates the player's prefab then rename the object to "ThePlayer" or whatever suits your needs.
You can do this with the following code.
//Somewhere there will be code that looks similar to the following.
GameObject go = GameObject.Instantiate(playerPrefab) as GameObject;
go.name = "ThePlayer"; //* Add this line of code.
Then in the script where you are making modifications to the player, use:
GameObject player = GameObject.Find("ThePlayer");
An alternative is to find the playerPrefab and set its Tag (which can be found as a drop down in the inspector when you have the playerPrefab selected) and choosing the "Player" tag. Then in your new script all you have to do is:
GameObject player = GameObject.FindGameObjectWithTag("Player");
Let me know if you have any questions.
Hey Rob... I've already tried something similar to this but GameObject.Find("Player"); always yields a "null" result. I don't get any errors except for a NullReferenceException when I use this. I've got a Debug.Log(player) setup and it always reads "null".
I can see that the player is now named "Player" but how do I get this current script to see things from the other one? It seems like Script2 isn't able to find a GameObject that was instantiated in Script1... :(
Ok... I did a little testing and it looks like the reason that I'm getting a "null" result is that the layer GameObject is created in Script1's Start() function. The Find command is also being run in Script2's Start() function so that I can make changes to "player" like you have in your script. Since Script1 and Script2 are both running their Start() commands at the same time, Script2 gets a null result from Script1. If I move the definition to the Update() function, I no longer get a null result.
So...how do I only run this assignment once but do it after Script1 finishes its Start() function???
Thanks, Rob!! I really appreciate the help!!
Sorry for the rush of updates. I added a delay to the script with the Script Execution Order settings but I'm not sure if that's the right way to do it. It's working but I want to make sure that this is the most efficient way to do this...
You need to be using Awake and Start methods properly to avoid complications like the one you have.
Awake and Start are only called once per script, BUT Awake is always called before Start. Use Awake for initialization of all your scripts, then Start for transfering/modifying data between other scripts. This methodology ensures that you always initialize every component before perfor$$anonymous$$g any actions to them.
So with that in $$anonymous$$d, change the script that instantiates your player so that the Start method is now an Awake, and you should be fine. Let me know if that presents other errors.