[C#] InstanceID Isn't Working How I Thought, Using It Wrong?

Hi, I’m currently developing a stealth AI, I’m currently at the stage of the AI looking into hiding (Container) positions, to do this I have the NavMesh check to see if any of the hiding places are surrounding it using the OverlapSphere. Once it finds one, it moves towards it. This works just fine. So, when the player enters a hiding spot, it saves a variable called “ContainerID” and sets it to the InstanceID. When the AI approaches the hiding spot, it takes the Index that it found the container on, and checks its InstanceID. I used Debug.Log() and it has confirmed that the two Instance ID’s don’t match, even though it’s checking the same thing. I’m confused.

Here’s my code:

AI Script -
AI Script

Excuse the messy code & half commentedness
Function at 177 is where the main processing goes on in this scenario.

using UnityEngine;
using System.Collections;

public class AIMain : MonoBehaviour {
   
    //Classes the AI uses
    public Animator Anim;
    public NavMeshAgent Nav;
    public AudioSource Audio;
    public PlayerMovement PM;
    HidingLook HL;
   
    //Variables used to "catch" the player
    public Transform Player;
    public Transform AIEyes;
    public int ViewDistance;
    Vector3 LookDirection;
    RaycastHit Hit;
    Collider[] Vicinity;

    //Variables used within functions to make decisions
    public Transform[] Waypoints;
    public float IdleTime;
    Vector3 Destination;
    int Index;
    int CurrentWaypoint;
    int WanderCount;

    //Status variables for actions taken by the AI
    bool PlayerSeen;
    bool AISpoke;

    //Status variables for movement and patterns
    bool Moving;
    bool Waiting;
    bool Chasing;
    bool Wandering;
   
    public GameObject NewDestination;
   
    GameObject[] Containers;
    GameObject Closest;
    float Distance;
    Vector3 Difference;
    float CurrentDistance;
    bool MovingToContainer;
    int CheckingID;
    int WanderIndex;
   
    void Start () {
       
        //Sets values to "default" values
        CurrentWaypoint = 0;
        MovingToContainer = false;
       
        //Starts coroutines to begin the loop
        StartCoroutine(NextDestination());
        StartCoroutine(Wander());
       
        Containers = GameObject.FindGameObjectsWithTag("Container");
   
    } // Closes Start;
   
   
    void Update () {

        //SECTION: This section decides whether or not to begin to chase the player and chases the player if so

        //Draws a ray to see if it can find the player through it's eye
        LookDirection = (Player.position - AIEyes.position).normalized;
        Physics.Raycast(AIEyes.position,LookDirection,out Hit,ViewDistance);
       
        //null is to avoid an error which spammed the console if there was no collision
        if(Hit.collider != null){
           
            if(Hit.collider.name == "Player"){
               
                PlayerSeen = true;
               
            }
           
        }

        //Checks to see what's surrounding the AI and runs through the array list to see if the Player is around
        Vicinity = Physics.OverlapSphere(transform.position,10f);

        while(Index < Vicinity.Length){
           
            if(Vicinity[Index].name == "Player"){
           
                PlayerSeen = true;
                break;
           
            } else{
               
                Index++;
           
            }
       
        } // Closes While Loop

        if(PlayerSeen == true){
           
            if(AISpoke == false){
           
                Audio.Play();
                AISpoke = true;
           
            }

            //The AI begins to chase the player
            Chasing = true;
            Nav.SetDestination(Player.position);
            PlayerSeen = false;
           
        }
       
        //This is here to prevent the bug where the Audio Source would spam the AI's speach
        if(Chasing == false){
       
            AISpoke = false;
            Nav.speed = 5;
       
        }

        //Runs Coroutine to check to see if AI is done chasing and to transition
        if(Chasing == true){
       
            StartCoroutine(ChaseToWander());
            Nav.speed = 10;
       
        }
       
        //Checks to see if the AI is moving and chances variable accordingly
        if(Nav.velocity != Vector3.zero){
       
            Moving = true;
       
        } else{
       
            Moving = false;
       
        }
       
        Anim.SetBool("Running",Moving);
       
        NewDestination.transform.position = Nav.destination;
       
    } // Closes Update;
   
   
    IEnumerator NextDestination(){

        yield return new WaitForSeconds (IdleTime);

        //Sets the next waypoint
        if (Chasing == false && Wandering == false && Waiting == false) {

            CurrentWaypoint++;
           
            if (CurrentWaypoint > Waypoints.Length - 1) {
               
                CurrentWaypoint = 0;
               
            }
           
            //Calls Coroutine to loop
            Nav.SetDestination (Waypoints [CurrentWaypoint].position);
       
        }

        StartCoroutine(NextDestination());

    } // Closes NextDestination;
IEnumerator Wander(){

    yield return new WaitForSeconds(1);
   
    if(WanderCount < 3 && Chasing == false && Wandering == true && Waiting == false){
       
        if(MovingToContainer == false){
       
            Vicinity = Physics.OverlapSphere(transform.position,25f);
           
            WanderIndex = 0;

            while(WanderIndex < Vicinity.Length && MovingToContainer == false){

                if(Vicinity[WanderIndex].tag == "Container"){
           
                    Nav.SetDestination(Vicinity[WanderIndex].transform.position);
                    Wandering = false;
                    MovingToContainer = true;
                    break;
                   
                }
               
                WanderIndex++;
               
            }
           
            if(MovingToContainer == false){

                Wandering = true;
                Physics.Raycast(AIEyes.position,LookDirection,out Hit,ViewDistance);
                Destination = Hit.transform.position;
                Destination.x += Random.Range(-15,15);
                Destination.z = Random.Range(2,6);
               
                NewDestination.transform.position = Destination;
                Nav.SetDestination(Destination);
               
                WanderCount++;
           
            }
       
        } else {
       
            if(Nav.remainingDistance < 2.5f){
           
                CheckingID = Vicinity[WanderIndex].gameObject.GetInstanceID();
               
                if(CheckingID == PM.ContainerID){
                   
                    HL = Vicinity[WanderIndex].gameObject.GetComponent<HidingLook>();
                    HL.PromptLeave = true;
                   
                }
               
                MovingToContainer = false;
           
            }
       
        }
       
    } else{
   
        Wandering = false;
   
    }

    StartCoroutine(Wander());

} // Closes Wander;


IEnumerator ChaseToWander(){

    if(Nav.remainingDistance < 2.5f){
       
        Chasing = false;
        Waiting = true;
        yield return new WaitForSeconds(IdleTime);
        Waiting = false;
        WanderCount = 0;
        Wandering = true;
       
    }

} // Closes to ChaseToWander;

} // Closes Class


Here's the HidingLook script, which is attached to the Container
HidingLook

[spoiler]

If statement at 26 is where it happens

```csharp
using UnityEngine;
using System.Collections;

public class HidingLook : MonoBehaviour {
   
    public Transform CamTransform;
    public Camera Cam;
    public bool PromptHide;
    public bool PromptLeave;
    public PlayerMovement PM;
    float NewY;
    float Sensitivity;
    int ID;


    void Start () {
   
        Sensitivity = 5;
        Cam.gameObject.SetActive (false);
   
    }


    void Update () {

        if (PromptHide == true) {

            Cam.gameObject.SetActive (true);
            Cam.gameObject.transform.localEulerAngles = Vector3.zero;
            PromptHide = false;
            PM.ContainerID = GetInstanceID();
           
        }
       
        if(PromptLeave == true){
       
            Cam.gameObject.SetActive(false);
            PromptLeave = false;
       
        }

        if (PM.Hiding == true) {

            NewY += Input.GetAxis("Mouse X") * Sensitivity;
            NewY = Mathf.Clamp(NewY,-30,30);
            Cam.gameObject.transform.localEulerAngles = transform.TransformDirection(new Vector3(0,NewY,0));


        }
   
   
    }
   

}

[/spoiler]

Any help would be greatly appreciated
[/spoiler]

CheckingID = Vicinity[WanderIndex].gameObject.GetInstanceID();

PM.ContainerID=GetInstanceID();

might be worth checking that the second line (from the second script you’ve posted) isn’t getting the instance ID of the script instead of the gameobject it’s attached to?

@LeftyRighty is right.

in “CheckingID” you are saving the gameobjects InstanceID.
int PM.ContainerID you are saving the InstanceID of the HidingLook Script.

Every Element in Unity has his own InstanceID, so the instance ID of a gameojbect does not match the instance ID of any component of this gameobejct. (instance id is unique to every object (Object: GameObject, Component etc.))

I’d normally suggest not relying on Unity’s ids and simply making your own. Or better yet, simply store a reference to the actual instance of concern.

I am confused, is it not saving the instance ID of the script that it’s in? I am wanting to keep it as saving the instance ID of the script it’s attached to, because that “PM” is the Player script, which there is only one of. If the AI were to check any other box, each of which have the script that I posted, I’d want them to check the instance ID of that script, am I doing something else here?

I’m not sure how I’d go about making my own Unity ID system, how would that be done? I normally would set a direct reference, but I can’t do that since there’s so many of these objects that the player can hide in, and I want the AI to pick up them on their own, considering this AI will be across multiple levels. Or am I misinterpreting your suggestion?

in the first script you are getting the instanceID of the gameobject, in the second script you are getting the instanceID of the script. They aren’t going to be equal.

2 Likes

Oh my goodness I now see the light thank you