Why cant i find the other objects?

I have three GameObjects in my tree on the same level, they are in a column
im using
sectorAObject = GameObject.Find(“SectorA”);

to find the objects

it finds this one, but not the other 2, i have checked and the name is correct.
Any idea why unity cant find them?

While I’d suggest moving away from GameObject.Find, if it can’t find them they are either turned off or the name doesn’t exactly match. (Caps, spaces, etc). Unless you have multiple objects named SectorA and trying to get all 3, which it doesn’t work like that. It will return 1 item and most likely it will always return the same item.

You probably need to share a bit more.

Epoch, you’ve been here WAAAAAAAY too long to be still using GameObject.Find() !!!

Remember the first rule of GameObject.Find():

Do not use GameObject.Find();

More information: https://starmanta.gitbooks.io/unitytipsredux/content/first-question.html

Reading the docs for GAmeObject.Find(), why would you think it would ever find anything else?

1 Like

My bad!!! Sorry, i thought it was WithTag that ws frowned upon…lol

All Find()s are bad. Use proper resource location / specification techniques for Unity.

GetComponent is less bad but still gets a ton of people into trouble because they expect Components where they aren’t, usually because they’re searching on the wrong Object.

All of this noisy-noise is fixed by making a public field and dragging what you want in.

One and done.

"All of this noisy-noise is fixed by making a public field and dragging what you want in.

One and done." - yes but this presents problems when using prefabs.

You really should read Starmanta’s post above. You’re fighting city hall as far as the design of Unity goes.

I dont understand, i know and like dragging objects into a public space in the inspector, but that doesnt work when objects havent been instantiated yet, and you need to put a reference in start and even worse you have to invoke it a second later as start or awake doesnt work either and you get reference errors. As it says in that doc, so i been using FindWithtag mostly to link a reference when the game starts running, what am i meant to do?

The prefab should have all local references in local scripts.

When you Instantiate it you get a reference back.

Use that reference to get to the other local references.

For instance if you need to get at the head of every object, make a script that goes on the prefab root and has the correct child dragged in. After Instantiation, those references will be now pointing to the live versions.

1 Like

The “problem” with prefabs is, if you instantiate via code, how do you get any component within that freshly created prefab?
The instantiate method only returns the game object so you will have to call GetComponent on it.

You can actually reference prefabs by any component on the root game object, instantiate that, and immediately get the component returned.

Take a look at the overloads further down on Instantiate: https://docs.unity3d.com/ScriptReference/Object.Instantiate.html

As Spiney says above, reference it by a master script, like this one I might use for my player:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// @kurtdekker - put this on the root of your player.
// It does NOTHING except give you quick access
// to other parts of the player.
//
// For instance, your player hierarchy might look like:
//
//    PlayerPrefab
//        VisibleAnimatedGeometry
//        Weapon1
//        Weapon2
//        DialogPopup

public class Player : MonoBehaviour
{
    // each of these things must be located
    // somewhere on this same hierarchy of GameObjects
    public PlayerMovement movement;

    public PlayerWeapon weapon;

    public PlayerDialog dialog;

    // any other stuff your player or enemy or whatever this thing is must do
}

NOTE: The above script has no code, just references to OTHER scripts that do the actual work.

In your spawner code:

// drag player prefab in here
public Player PlayerPrefab;
private Player PlayerInstance;

To instantiate:

PlayerInstance = Instantiate<Player>( PlayerPrefab, position, rotation);

That’s it. If you are not using this ultra ultra ultra simple strategy to keep stuff centralized and concentrated, you’re probably making things unnecessarily complicated for yourself.

Extend the above to each broad type of object: enemy, projectile, trap, door, etc.

Note how there is no “finding” going on.

1 Like

I cant get my camera script to follow my player

here is my camera script:

But it doesnt follow the player when i drag the player prefab into the slot in the inspector,
When i drag the player clone in, then it works. So i still dont fully understand this.
It does work for me perfectly on spawning the player though.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    public float cameraDistOffset;
    public Camera mainCamera;
    public Player playerPrefab;

    void Update()
    {
        Vector3 playerInfo = playerPrefab.transform.transform.position;
        mainCamera.transform.position = new Vector3(playerInfo.x, playerInfo.y, playerInfo.z - cameraDistOffset);
    }
}

When I make a script that makes the camera follow the player, I don’t attach it to the player, I attach a script with the following code to my camera:

using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    public Vector3 offset;
    private float smoothTime = 0.25f;
    private Vector3 velocity = Vector3.zero;

    public GameObject player;

    public GameObject camera;
    [SerializeField] private Transform target;

    private void Update()
    {
        Vector3 targetPosition = target.position + offset;
        transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
    }
}

I then edit all the values in the editor, it works for both 3D and 2D games.