How to Freeze an Object on Raycast

EDIT: Sorry for the double post, I made a mistake with the previous post.

Hello. I’m trying to make a mechanic for my FPS where the player presses their primary mouse button and the resulting Raycast hits the Enemy and freezes them in place. After a few seconds, the enemy resumes.

My enemies don’t have Rigidbodies on them and even if they did, RigidbodyConstraints does not and refuses to work for me. Currently, the enemy object is only being moved by the script controlling the entire agent. Here is the code for that:

public void agentTrack()
    {
        _distance = Vector3.Distance(_player.transform.position, this.transform.position);

        if (_distance <= 12)
        {
            _isAlert = true;
        }

        else
        {
            _isAlert = false;
        }

        if (_isAlert)
        {
            _agent.isStopped = false;
            _agent.SetDestination(_player.transform.position);
            Shoot();
        }

        else if (!_isAlert)
        {
            _agent.isStopped = true;
        }
    }

where isAlert is a boolean tracking to see if player is in range.

I’ve also tried _agent.isStopped in the script controlling my Raycast, yet that’s not working either. Here is the main, important function of that script:

void Shoot()
    {
        _gunFlash.Play();
        Debug.Log("Calling this function 0.");

        RaycastHit hitInfo;
         if (Physics.Raycast(FPSCamera.transform.position, FPSCamera.transform.forward, out hitInfo, _range))
        {
            Debug.Log("Calling this function 90.");

            Debug.Log(hitInfo.transform.name);
            //Enemy_AI target = hitInfo.transform.GetComponent<Enemy_AI>();
            Target target = hitInfo.transform.GetComponent<Target>();
            if (target != null)
            {
                Debug.Log("Calling this function 70.");
                target.TakeDamage();
            }

            if (hitInfo.rigidbody != null)
            {
                hitInfo.rigidbody.AddForce(-hitInfo.normal * _impactForce);
            }

            GameObject impact = Instantiate(_impactEffect, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
            Destroy(impact, 2f);
        }
    }

along with the TakeDamage function of the Target class:

public IEnumerator TakeDamage()
    {
        Debug.Log("Freezed");

        _enemy._agent.isStopped = true;

        yield return new WaitForSeconds(5);

        _enemy._agent.isStopped = false;
    }

Any help or clues will be appreciated. Thank you.

Hey there,

the issue you have is that you need a seperate flag to indicate that the enemy is “frozen”. The way that you currently have it is that you set

 _enemy._agent.isStopped = true;

but in the next frame the enemy script will pass:

   if (_isAlert)
     {
         _agent.isStopped = false;
         _agent.SetDestination(_player.transform.position);
         Shoot();
     }

and thus overwrite the “isStopped” value.

Your enemy needs a

    public bool frozen = false;

and the code should change to:

if(!frozen)
{
         if (_isAlert)
         {
             _agent.isStopped = false;
             _agent.SetDestination(_player.transform.position);
             Shoot();
         }
         else if (!_isAlert)
         {
             _agent.isStopped = true;
         }
}

and the take damage function is then:

public IEnumerator TakeDamage()
     {
         Debug.Log("Freezed");
 
         _enemy.frozen = true;
 
         yield return new WaitForSeconds(5);
 
         _enemy.frozen = false;
     }

This way the enemy will not “free itself” anymore.