Instantiate of gameobject doesn't change value of other scripts

Hello, Im new to unity and C#. Im making a special type of grenade and what i do is that i Instantiate grenade prefab and check if enemies are in range then i want to tell my enemy to stop attacking player and instead go to grenade position. i have a problems right now. i change a public bool from my enemy script called “grenadeActive” in my grenade script but it doesnt change in my enemy script . i check it on other gameobjects that are not instantiate and it works and even i change the bool variable from the prefab of grenade and it works without problem. so what is wrong here? am i doing something wrong or its not possible to change it from an instantiate?

here is my code:
the first one for spawning the
grenade (its on a empty gameobject)

public class grenadeThrower : MonoBehaviour
{
    [HideInInspector] public GameObject grenadeInstance;
    [SerializeField] GameObject grenadeRefrence;
    [SerializeField] int grenadeNumber = 3;
    [SerializeField] int grenadeForce = 10;

    private void Awake()
    {
        grenadeInstance = null;
    }
    
    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Fire1") && grenadeNumber > 0)
        {
            grenadeNumber--;
            grenadethrower();
        }
        if (grenadeNumber == 0) transform.GetChild(0).gameObject.SetActive(false);
        else transform.GetChild(0).gameObject.SetActive(true);
        
    }

    void grenadethrower()
    {
        grenadeInstance = Instantiate(grenadeRefrence, transform.position, transform.rotation);
        Rigidbody rb = grenadeInstance.GetComponent<Rigidbody>();
        rb.AddForce(transform.forward * grenadeForce, ForceMode.VelocityChange);
    }
}

the second one is on the grenade

public class grenade : MonoBehaviour
{
    public enemy Enemy;
    float countdown = 2f;
    bool hasExploded;
    [SerializeField] float despawnTime = 2f;
    [SerializeField] float enemyRadius = 10f;



    void Update()
    {
        despawnTime -= Time.deltaTime;
        countdown -= Time.deltaTime;
        if (countdown <= 0f && !hasExploded)
        {
            grenadeForEnemy();
            if (countdown + despawnTime <= 0f)
            {
                Destroy(gameObject);
                hasExploded = true;
                Enemy.grenadeActive = false;
            }
        }

    }


    void grenadeForEnemy()
    {
        Collider[] colliders = Physics.OverlapSphere(transform.position, enemyRadius);
        foreach (Collider nearbyobject in colliders)
        {
            enemy checkEnemy = nearbyobject.GetComponent<enemy>();
            if (checkEnemy != null) Enemy.grenadeActive = true;
        }
    }
}

and the last one is on the enemy

public class enemy : MonoBehaviour
{
    public bool grenadeActive;
    [SerializeField] grenadeThrower GrenadeThrower;   
    bool isPlayerVisible;
    bool playerInSightRange, playerInAttackRange;
    [SerializeField] Transform player;
    [SerializeField] float sightRange, attackRange;
    [SerializeField] float health = 5f;

    private void Awake()
    {
        health *= 10;
        player = GameObject.Find("player").transform;   
    }

    private void Update()
    {
        
        //Check for sight and attack range
        playerInSightRange  = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
        playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);

        if (!playerInSightRange && !playerInAttackRange && !isPlayerVisible && !grenadeActive) Patroling();
        if (playerInSightRange  && !playerInAttackRange &&  isPlayerVisible && !grenadeActive) ChasePlayer();
        if (playerInAttackRange &&  isPlayerVisible && !grenadeActive) AttackPlayer();
        if (grenadeActive) attackGrenade();

    }

    private void FixedUpdate()
    {
        RaycastHit hit;
        Vector3 fromPosition = transform.position;
        Vector3 toPosition = player.position;
        Vector3 direction = toPosition - fromPosition;

        if (Physics.Raycast(transform.position, direction, out hit))
        {
                if (hit.collider.gameObject.name == "player") isPlayerVisible = true;
                else isPlayerVisible = false;
        }
    }
    
    void attackGrenade()
    {
        agent.SetDestination(GrenadeThrower.grenadeInstance.transform.position);
    }

and i even tried to put grenadeActive on my grenade script and access it from enemy and that didnt work as well.

A simple way of doing it with what you already know might be (in your enemy script):

 [SerializeField] float grenadeRange;
    [SerializeField] LayerMask grenadeLayer;

    private void Update()
    {
        // This is just to avoid checking three times the value (for performance)
        Vector3 transformPosition = transform.position;     

        // Check first if a grenade is on range
        if (Physics.CheckSphere(transformPosition, grenadeRange, grenadeLayer))
        {
            attackGrenade();
        }
        else 
        {
            // No grenade on sight, let's check for player
            if (Physics.CheckSphere(transformPosition, attackRange, whatIsPlayer) && isPlayerVisible)  
            {
                // Player is on attack range so Attack!
                AttackPlayer();

            } 
            else if (Physics.CheckSphere(transformPosition, sightRange, whatIsPlayer) && isPlayerVisible)
            {
                // Player is not within attack range but it's on sight range
                ChasePlayer();
            }
            else
            {
                // No player or grenade on sight
                Patroling();
            }
        }
    }

This solution implies setting a special layer for greandes or any object you want your enemies to look for.

Some notes on your code:

· I don’t know how or when you change isPlayerVisible value. I leave it to you.

· Also I guess whatIsPlayer is the LayerMask for the player gameObject?

· You have some inconsistencies on your naming, consider tanking some extra time to fix them and take a look to the C# coding conventions. It will help you big time in the long run.

A more complex solution might be using delegates or interfaces. You can learn more about them in the documentation, so remember to check them out whenever you feel ready :slight_smile: