Help. I can't make my enemy face the Player (Video 184. Zombie Runner)

Hi!
I can’t figure out what I’m doing wrong. My enemy does not rotate at all. The enemy behaves exactly the way Ricks does, except it stays facing a constant direction. I’m unsure if it is something in my code because I replaced mine with Rick’s and the enemy still suffered with the same problem.

When playing the game, the rotation values remain at 0 regardless of where I place the player.

I’ve pasted my code below. Please may someone be kind enough to help me find out what I’ve done wrong? I’m really stumped this time lol

Thank you! :slight_smile:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyAI : MonoBehaviour
{
    [SerializeField] Transform target;
    [SerializeField] float chaseRange = 5f;
    [SerializeField] float turnSpeed = 5f;


    NavMeshAgent navMeshAgent;
    float distanceToTarget = Mathf.Infinity;
    bool isProvoked = false;


    void Start()
    {
        navMeshAgent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        distanceToTarget = Vector3.Distance(target.position, transform.position);

        if (isProvoked)
        {
            EngageTarget();
        }
        else if (distanceToTarget <= chaseRange)
        {
            isProvoked = true;     
        }

    }

    private void EngageTarget()
    {
        FaceTarget();

        if (distanceToTarget >= navMeshAgent.stoppingDistance)
        {
            ChaseTarget();
        }

        if (distanceToTarget <= navMeshAgent.stoppingDistance)
        {
            AttackTarget();
        }
    }

    private void ChaseTarget()
    {
        GetComponent<Animator>().SetBool("Attack", false);
        GetComponent<Animator>().SetTrigger("Move");
        navMeshAgent.SetDestination(target.position);

    }

    private void AttackTarget()
    {
        GetComponent<Animator>().SetBool("Attack", true);
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(transform.position, chaseRange);
    }

    private void FaceTarget()
    {
        Vector3 direction = (target.position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed);
    }
}

Hi Sombra,

Are there any error messages in your console?

1 Like

Hi Nina!

No, none at all. Everything runs fine.

I’m trying to figure out what may be happening, so I wrote a very simple “LookAtPlayer” script to test:

public class LookAtPlayer : MonoBehaviour
{
    [SerializeField] GameObject target;

    // Start is called before the first frame update
    void Start()
    {
        target = GameObject.Find("Player");
    }

    // Update is called once per frame
    void Update()
    {
        transform.LookAt(target.transform);
    }
}

I placed this script on a simple 3D cube to test & it looks at the player as expected. However, when I put the same LookAtPlayer script on the enemy, it still only ever faces a constant direction.

I’m not sure how helpful that is, but it seems like such strange behaviour from the “Enemy” :confused:

Comment out the code in FaceTarget() in the EnemyAI class and replace it with your working solution transform.LookAt(target.transform);. Does the enemy look at the target?

1 Like

Okay, I’ve done the following (below) but still no change in behaviour, unfortunately

    private void FaceTarget()
    {
        transform.LookAt(target.transform);

        /*Vector3 direction = (target.position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed);*/
    }

Further testing on the Cube, I’ve added a Nav Mesh Agent and the EnemyAI script to it. The Cube still looks at the Player as intended, but does not chase the Player (due to not having an Animator to access the bools and triggers).

When I put an Animator on the Cube, it begins chasing the Player, but it no longer looks at the player.

So given that, it seems like the animator (or something within it) is causing the Face Player to not operate correctly.

:thinking:

Yes, so I’ve now tested this on the enemy. I removed the Animator component and it faces the Player correctly. However, removing the Animator stops the Enemy from chasing and attacking the player. I can confirm that our FaceTarget() method does work as intended:

    private void FaceTarget()
    {
        Vector3 direction = (target.position - transform.position).normalized;
        Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
        transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed);
    }

Hopefully this gets us closer to a solution :slight_smile:

Nina, I think I figured it out!

Given that the issue seems to stem from the Animator, I thought it would be best to start there. Everything looked normal, however I noticed a little info hint which said “Root position or rotation are controlled by curves”. There was a little check mark above it called “Apply Root Motion” which was unchecked. As it was hinting toward rotation, I checked the check mark & ran the game.

The Enemy now behaves correctly & no cautions or warnings are flagging up in the console.

Thank you so much for your help!

I’ll look more into Root Motion so that I can better understand it going forward!

:blush::blush::blush:

4 Likes

Awesome! Thanks a lot for sharing your solution! :slight_smile:

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms