Currently, I am trying to set up a simple script where an enemy will move towards and rotate towards the player. The rotation & running animations play just fine, but the enemy that is supposed to move is stuck in place.
I have tried Debugging it with logs as well as baking the navmesh, the issue could have somthing to do with velocity but I’m just not sure. Thanks for reading this.
Here is the Code as well as the inspector:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyLocomotionManager : MonoBehaviour
{
private BoxCollider boxCollider;
private Rigidbody[] RDrigidbodies;
private Collider[] colliders;
public float moveSpeed = 10f;
public Rigidbody enemyRb;
NavMeshAgent navMeshAgent;
EnemyAnimatorManager enemyAnimatorManager;
EnemyManager enemyManager;
public CharacterStats currentTarget;
[SerializeField] LayerMask detectionLayer;
public float rotationSpeed = 25;
public float distanceFromTarget;
public float stoppingDistance = 0.5f;
private void Awake()
{
RDrigidbodies = GetComponentsInChildren<Rigidbody>();
colliders = GetComponentsInChildren<Collider>();
boxCollider= GetComponent<BoxCollider>();
enemyRb = GetComponent<Rigidbody>();
enemyManager = GetComponent<EnemyManager>();
enemyAnimatorManager= GetComponent<EnemyAnimatorManager>();
navMeshAgent = GetComponentInChildren<NavMeshAgent>();
//DisableRagdoll
SetCollidersEnabled(false);
SetRigidBodiesKinematic(false);
boxCollider.enabled = true ;
}
private void Start()
{
navMeshAgent.enabled = false;
enemyRb.isKinematic= false;
}
public void HandleDetection()
{
Collider[] colliders = Physics.OverlapSphere(transform.position, enemyManager.detectionRadius, detectionLayer);
for (int i = 0; i < colliders.Length; i++)
{
CharacterStats characterStats = colliders[i].transform.GetComponent<CharacterStats>();
if(characterStats != null )
{
Debug.Log("HaSDetectedDertc");
//Check for team ID
//Direction towards the object that has that script
Vector3 targetDirection = characterStats.transform.position - transform.position;
//returns the angle between current direction & target direction
float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
//check if its in our FOV
// if( viewableAngle > enemyManager.minimumDetectionAngle && viewableAngle< enemyManager.maximumDetectionAngle)
// {
currentTarget = characterStats;
// }
}
}
}
public void HandleMoveToTarget()
{
Debug.Log("Handling Move To Target"); // Add a log to indicate this function is being executed
Vector3 targetDirection = currentTarget.transform.position - transform.position;
float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
distanceFromTarget = Vector3.Distance(currentTarget.transform.position, transform.position);
// Log values to see what's happening
Debug.Log($"Viewable Angle: {viewableAngle}, Distance From Target: {distanceFromTarget}");
if (enemyManager.isPerformingAction)
{
Debug.Log("Performing Action, Stopping Movement");
enemyAnimatorManager.anim.SetFloat("Vertical", 0, 0.1f, Time.deltaTime);
navMeshAgent.enabled = false;
}
else
{
if (distanceFromTarget > stoppingDistance)
{
Debug.Log("Moving Towards Target");
enemyAnimatorManager.anim.SetFloat("Vertical", 1, 0.1f, Time.deltaTime);
}
else if (distanceFromTarget <= stoppingDistance)
{
Debug.Log("Reached Stopping Distance");
enemyAnimatorManager.anim.SetFloat("Vertical", 0, 0.1f, Time.deltaTime);
}
}
HandleRotateToTarget(); // Add a log inside HandleRotateToTarget to check if it's being executed
navMeshAgent.transform.localPosition = Vector3.zero;
navMeshAgent.transform.localRotation = Quaternion.identity;
}
private void HandleRotateToTarget()
{
//Rotate manually
if(enemyManager.isPerformingAction)
{
Vector3 direction = currentTarget.transform.position - transform.position;
direction.y = 0;
direction.Normalize();
if(direction == Vector3.zero)
{
direction = transform.forward;
}
Quaternion targetRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed/Time.deltaTime);
}
//rotate with pathfinding
else
{
//this function
//navmesh agents
Vector3 relativeDirection = transform.InverseTransformDirection(navMeshAgent.desiredVelocity);
Vector3 targetVelocity = enemyRb.velocity;
navMeshAgent.enabled = true;
navMeshAgent.SetDestination(currentTarget.transform.position);
Debug.Log("Set Destination");
enemyRb.velocity = targetVelocity;
transform.rotation = Quaternion.Slerp(transform.rotation, navMeshAgent.transform.rotation, rotationSpeed / Time.deltaTime);
}
}
private void SetCollidersEnabled(bool enabled)
{
foreach(Collider col in colliders)
{
col.enabled = enabled;
}
}
private void SetRigidBodiesKinematic(bool kinematic)
{
foreach(Rigidbody rb in RDrigidbodies)
{
rb.isKinematic= kinematic;
}
}
private void ActivateRagdoll()
{
boxCollider.enabled = false;
enemyRb.isKinematic = true;
enemyAnimatorManager.anim.enabled = false;
SetCollidersEnabled(true);
SetRigidBodiesKinematic(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
EnemyLocomotionManager enemyLocomotionManager;
public bool isPerformingAction;
public float detectionRadius = 20;
public float maximumDetectionAngle = 50;
public float minimumDetectionAngle = -50;
// Start is called before the first frame update
void Awake()
{
enemyLocomotionManager= GetComponent<EnemyLocomotionManager>();
}
private void FixedUpdate()
{
HandleCurrentAction();
}
// Update is called once per frame
void HandleCurrentAction()
{
if (enemyLocomotionManager.currentTarget == null)
{
enemyLocomotionManager.HandleDetection();
}
else
{
enemyLocomotionManager.HandleMoveToTarget();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAnimatorManager : AnimatorManager
{
EnemyLocomotionManager enemyLocomotionManager;
private void Awake()
{
enemyLocomotionManager = GetComponentInParent<EnemyLocomotionManager>();
anim= GetComponent<Animator>();
}
void OnAnimatorMove()
{
float delta = Time.deltaTime;
enemyLocomotionManager.enemyRb.drag = 0;
Vector3 deltaPosition = anim.deltaPosition;
deltaPosition.y = 0;
Vector3 velocity = deltaPosition / delta;
enemyLocomotionManager.enemyRb.velocity = velocity;
}
}
>Solution :
Remember that for the OnAnimatorMove() to work correctly, the Animator component’s Apply Root Motion checkbox should be checked in the Unity editor.