How to move enemy with physics based movement?

Fairly new to Unity/C#. I’m doing an FPS. I’ve gotten all the animations down, but when it comes to actually having the enemy move, I’m having some issues. I’d like a physics based locomotion so the creature doesn’t just clip through walls. I’m aware of Rigidbody,AddForce and CharacterController.Move but I have no idea how to “phrase” them given my current setup or what values to put where.

I’ve tried the AddForce page, but again, I’m unsure how to phrase it in a way, so that when the Walking animation starts, and the enemy has spotted the player, that it moves toward them.

public class WastrelChase : MonoBehaviour {

    public Transform player;
    static Animator anim;
    
    

    // Use this for initialization
    void Start ()
    {
        anim = GetComponent<Animator>();
        
    }
	
	// Update is called once per frame
	void Update () {

        
        if (Vector3.Distance(player.position, this.transform.position) < 5)
        {
            Vector3 direction = player.position - this.transform.position;
            direction.y = 0;

            this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
                                        Quaternion.LookRotation(direction), 0.1f);

            anim.SetBool("IsIdle", false);
            if (direction.magnitude > .8)
            {
                anim.SetBool("IsWalking", true);
                anim.SetBool("IsStriking", false);
            }
            else
            {
                anim.SetBool("IsStriking", true);
                anim.SetBool("IsWalking", false);
            }


        }
        else
        {
            anim.SetBool("IsIdle", true);
            anim.SetBool("IsWalking", false);
            anim.SetBool("IsStriking", false);
        }
    }
}

Is there a reason your anim variable is static? This means that all instances of “WastrelChase” will share the same Animator component, which surely won’t end well. I would recommend removing the static. keyword and replacing it with private, so it becomes

     private Animator anim;

Back to the question, you need a reference to your Rigidbody. You can add it to the top of the script and assign it just like your anim component:

     private Rigidbody myRigidbody;
    
     // Use this for initialization
     void Start ()
     {
         myRigidbody = GetComponent<Rigidbody >();
     }

Next, make sure your object has some collider attached to it.

Depending on your enemy type, it may be a good idea to lock the X and Z rotation of the Rigidbody component, to prevent it from rolling around.

Next is to apply the force to the rigidbody. AddForce should be used in the FixedUpdate function, so what we will do is create a new Vector3 variable in our MonoBehaviour called “moveDirection”, which we will use in the Fixed update function.

The top of your class should now look something like:

     public Transform player;
     private Animator anim;
     private Rigidbody myRigidbody;
     private Vector3 moveDirection;

Set it to be zero at the very start of your Update function:

     void Update () {
 
         moveDirection = Vector3.zero;

         if (Vector3.Distance(player.position, this.transform.position) < 5)
         {

And assign it the direction you wish your object to move in, where you set IsWalking to true:

             if (direction.magnitude > .8)
             {
                 moveDirection = direction.normalized;
                 anim.SetBool("IsWalking", true);
                 anim.SetBool("IsStriking", false);
             }

Then, add your FixedUpdate function:

void FixedUpdate()
{
    myRigidbody.AddForce(myDirection * 50f);
}

the 50f is the movement force. You will need to adjust it to get movement working right. If it doesn’t appear to be moving, try increasing this to very large numbers (e.g. 50000f) to see if its just due to the force being to low.

The finished script will look something like:

 public class WastrelChase : MonoBehaviour {
 
     public Transform player;
     private Animator anim;
     private Rigidbody myRigidbody;
     private Vector3 moveDirection;
 
     // Use this for initialization
     void Start ()
     {
         anim = GetComponent<Animator>();
         myRigidbody = GetComponent<Rigidbody>();
     }
     
     // Update is called once per frame
     void Update () {
 
         moveDirection = Vector3.zero;

         if (Vector3.Distance(player.position, this.transform.position) < 5)
         {
             Vector3 direction = player.position - this.transform.position;
             direction.y = 0;
 
             this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
                                         Quaternion.LookRotation(direction), 0.1f);
 
             anim.SetBool("IsIdle", false);
             if (direction.magnitude > .8)
             {
                 moveDirection = direction.normalized;
                 anim.SetBool("IsWalking", true);
                 anim.SetBool("IsStriking", false);
             }
             else
             {
                 anim.SetBool("IsStriking", true);
                 anim.SetBool("IsWalking", false);
             }
 
 
         }
         else
         {
             anim.SetBool("IsIdle", true);
             anim.SetBool("IsWalking", false);
             anim.SetBool("IsStriking", false);
         }
     }

    void FixedUpdate()
    {
        myRigidbody.AddForce(moveDirection * 50f);
    }
 }