I'm making an enemy in my game. He stands at the side of road with a rocket launcher and fires when you get close. It nearly all works fine, except I just need a reference to the players position so that I can make his rocket explode when it reaches the same height on the map as the player car.

The enemy is a prefab which is NOT instanced at build-time, there a several spawn-points all with n% chance of spawning a guy there using the prefab. The player IS instanced at build-time. And here is my problem..

Although I have put a "public GameObject player" into my variables in the script on the prefab, it doesnt let me drag the already instanced player into it. I've read about a bit, and I see that Unity will not allow this (or at least thats what I gathered!)

So after much searching I came up with

player = GameObject.FindGameObjectWithTag("Player");

But i havent even tested yet because the source where i got that advice in the very next comment the guy says I shouldnt do this because it takes too much system resources up.

EDIT: I have tested it with that line, it does work. But is there a better way

But he doesnt say the way that it should be done! And the thread is about 6 years old. So I thought I'd write here again and ask you fine folks for more help.

I hope I explained the problem clearly enough, I think i got the terminology right. Basically, the RocketerEnemy prefab is going to be instantiated in runtime, but the PlayerCar is already instantiated by my dragging it into the heirarchy at the beginning of the project. This is stopping me from dragging the PlayerCar object into the box in the Inspector (for the Enemy prefab) . All I really need is the PlayerCar.transform.position.Y value for each frame.



You can't and shouldn't

Prefabs don't exist until they've been instantiated. As such, they cannot hold references to anything in a scene (things that do exist) because when they are instantiated those things might not exist any more! It could have been destroyed, it might be in a different scene, etc. etc.

You have to find the object you want to reference (the player) either when you instantiate the object, eg.:

GameObject go = Instantiate(myPrefab);
go.GetComponent<MyAwesomeScript>().thePlayer = someRefToPlayer;

Or figure out what it is in that prefab's script's Start() method:

Start() {
    thePlayer = GameObject.Find("Player");

Note that Find() is slow (you may also want to use FindWithTag() instead).

| improve this answer | |
  • \$\begingroup\$ Hi there, thanks for the reply. I didnt use Find() i used FindGameObjectWithTag(). But i read that its still slow. .. BTW I was aware of what you have written, but i just figured I could manager that myself, like if it didnt exist as I was using a different scene, I could just drag the new player onto it. But I do realise it is wrong. The thing is your first example there seems to instantiate a new player prefab, i dont want that i just want to read the position values for the existing player. The second example looks very interesting , well its exactly what I am doing now actually. So is... \$\endgroup\$ – Big T Larrity Jul 21 '17 at 20:41
  • \$\begingroup\$ ...that the accepted solution? \$\endgroup\$ – Big T Larrity Jul 21 '17 at 20:41
  • \$\begingroup\$ This is my scripts Start() method: void Start () { rb = rocket.GetComponent<Rigidbody>(); audioSource = GetComponent<AudioSource>(); playerCar = GameObject.FindGameObjectWithTag("Player"); } \$\endgroup\$ – Big T Larrity Jul 21 '17 at 20:42
  • 1
    \$\begingroup\$ @SuperMegaBroBro It's "slow" in the sense that you shouldn't use it during Update() or FixedUpdate(). During Start() is fine. \$\endgroup\$ – Draco18s no longer trusts SE Jul 21 '17 at 20:44
  • \$\begingroup\$ nice thanks @Draco18s . Thats really helped me, most of my game is falling into place now im happy :) \$\endgroup\$ – Big T Larrity Jul 21 '17 at 20:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.