Search Unity

Question Why cant i find the other objects?

Discussion in 'Scripting' started by epochplus5, Nov 11, 2022.

  1. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    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?
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,187
    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.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    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?
     
    Brathnann likes this.
  4. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    My bad!!! Sorry, i thought it was WithTag that ws frowned upon....lol
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    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.
     
  6. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    "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.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    You really should read Starmanta's post above. You're fighting city hall as far as the design of Unity goes.
     
  8. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    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?
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    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.
     
    epochplus5 likes this.
  10. DragonCoder

    DragonCoder

    Joined:
    Jul 3, 2015
    Posts:
    1,698
    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.
     
  11. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,911
    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
     
  12. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    As Spiney says above, reference it by a master script, like this one I might use for my player:

    Code (csharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. // @kurtdekker - put this on the root of your player.
    6. // It does NOTHING except give you quick access
    7. // to other parts of the player.
    8. //
    9. // For instance, your player hierarchy might look like:
    10. //
    11. //    PlayerPrefab
    12. //        VisibleAnimatedGeometry
    13. //        Weapon1
    14. //        Weapon2
    15. //        DialogPopup
    16.  
    17. public class Player : MonoBehaviour
    18. {
    19.     // each of these things must be located
    20.     // somewhere on this same hierarchy of GameObjects
    21.     public PlayerMovement movement;
    22.  
    23.     public PlayerWeapon weapon;
    24.  
    25.     public PlayerDialog dialog;
    26.  
    27.     // any other stuff your player or enemy or whatever this thing is must do
    28. }
    NOTE: The above script has no code, just references to OTHER scripts that do the actual work.

    In your spawner code:

    Code (csharp):
    1. // drag player prefab in here
    2. public Player PlayerPrefab;
    3. private Player PlayerInstance;
    To instantiate:

    Code (csharp):
    1. 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.
     
    epochplus5 likes this.
  13. epochplus5

    epochplus5

    Joined:
    Apr 19, 2020
    Posts:
    677
    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.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CameraFollow : MonoBehaviour
    6. {
    7.     public float cameraDistOffset;
    8.     public Camera mainCamera;
    9.     public Player playerPrefab;
    10.  
    11.     void Update()
    12.     {
    13.         Vector3 playerInfo = playerPrefab.transform.transform.position;
    14.         mainCamera.transform.position = new Vector3(playerInfo.x, playerInfo.y, playerInfo.z - cameraDistOffset);
    15.     }
    16. }
     
    Last edited: Nov 20, 2022
  14. Skullkid09

    Skullkid09

    Joined:
    May 31, 2023
    Posts:
    3
    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:

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class CameraFollow : MonoBehaviour
    4. {
    5.     public Vector3 offset;
    6.     private float smoothTime = 0.25f;
    7.     private Vector3 velocity = Vector3.zero;
    8.  
    9.     public GameObject player;
    10.  
    11.     public GameObject camera;
    12.     [SerializeField] private Transform target;
    13.  
    14.     private void Update()
    15.     {
    16.         Vector3 targetPosition = target.position + offset;
    17.         transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
    18.     }
    19. }
    I then edit all the values in the editor, it works for both 3D and 2D games.