diff --git a/Assets/Virtual Agents Framework/Runtime/Scripts/FundamentalAgentTasks/AgentRotationTask.cs b/Assets/Virtual Agents Framework/Runtime/Scripts/FundamentalAgentTasks/AgentRotationTask.cs index 87e1dd6..8e5e3c0 100644 --- a/Assets/Virtual Agents Framework/Runtime/Scripts/FundamentalAgentTasks/AgentRotationTask.cs +++ b/Assets/Virtual Agents Framework/Runtime/Scripts/FundamentalAgentTasks/AgentRotationTask.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using UnityEngine; namespace i5.VirtualAgents.AgentTasks @@ -15,29 +15,42 @@ public class AgentRotationTask : AgentBaseTask, ISerializable public Quaternion TargetRotation { get; protected set; } /// - /// Used to determine if the agent should rotate by a specific angle or towards a specific angle. + /// Used to determine if the agent should rotate by a specific angle /// - public bool IsRotationByAngle{ get; protected set; } + public bool IsRotationByAngle { get; protected set; } + + /// + /// Used to determine if the agent should rotate towards a specific angle. + /// + public bool IsRotationTowardsAngle { get; protected set; } /// /// The angle the agent should rotate by or towards /// public float Angle { get; protected set; } + /// + /// The transform the agent should rotate towards + /// + public Transform TargetTransform { get; protected set; } + /// /// The speed at which the agent should rotate /// public float Speed { get; protected set; } /// - /// Create an AgentRotationTask using a target object to turn towards + /// The angle difference at which the task is considered finished + /// + public float AngleThreshold = 0.03f; + + /// + /// Create an AgentRotationTask using a target object to turn towards, position will be evaluated when task is started /// /// Target object of the rotation task - public AgentRotationTask(GameObject target, float speed = 10f) + public AgentRotationTask(GameObject target, float speed = 0.8f) { - Vector3 position = target.transform.position; - position.y = 0; - TargetRotation = Quaternion.LookRotation(position); + TargetTransform = target.transform; IsRotationByAngle = false; Speed = speed; } @@ -46,10 +59,10 @@ public AgentRotationTask(GameObject target, float speed = 10f) /// Create an AgentRotationTask using the destination coordinates /// /// Coordinates of the rotation task - public AgentRotationTask(Vector3 coordinates, float speed = 10f) + public AgentRotationTask(Vector3 coordinates, float speed = 0.8f) { - coordinates.y = 0; - TargetRotation = Quaternion.LookRotation(coordinates); + TargetTransform = new GameObject().transform; + TargetTransform.position = coordinates; IsRotationByAngle = false; Speed = speed; } @@ -62,12 +75,13 @@ public AgentRotationTask(Vector3 coordinates, float speed = 10f) /// /// The angle to rotate by or towards, in degrees /// True if agent should rotate by "angle" degrees, false if the rotation value of the agent should be set to "angle" - public AgentRotationTask(float angle, bool isRotationByAngle = true, float speed= 10f) + public AgentRotationTask(float angle, bool isRotationByAngle = true, float speed = 0.8f) { IsRotationByAngle = isRotationByAngle; if (!isRotationByAngle) { TargetRotation = Quaternion.Euler(0, angle, 0); + IsRotationTowardsAngle = true; } else { @@ -85,8 +99,18 @@ public override void StartExecution(Agent agent) { Animator animator = agent.GetComponent(); base.StartExecution(agent); + + // For target and coordinates rotation + if (!IsRotationTowardsAngle && !IsRotationByAngle) + { + Vector3 newTargetPosition = new Vector3(TargetTransform.position.x, 0, TargetTransform.position.z); + Vector3 newAgentPosition = new Vector3(agent.transform.position.x, 0, agent.transform.position.z); + float angle = Vector3.SignedAngle(agent.transform.forward, newTargetPosition - newAgentPosition, Vector3.up); + TargetRotation = agent.transform.rotation * Quaternion.Euler(0, angle, 0); + } + //For Angle rotation - if(IsRotationByAngle) + if (IsRotationByAngle) { TargetRotation = agent.transform.rotation * Quaternion.Euler(0, Angle, 0); } @@ -96,14 +120,14 @@ public override void StartExecution(Agent agent) private IEnumerator Rotate(Transform transform) { float time = 0; - while (Vector3.Distance(transform.rotation.eulerAngles, TargetRotation.eulerAngles) > 0.01f) + while (Quaternion.Angle(transform.rotation, TargetRotation) > AngleThreshold) { - time += Time.deltaTime/Speed; //to control the speed of rotation + time += Time.deltaTime * Speed; //to control the speed of rotation // Rotate the agent a step closer to the target transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, time); yield return null; } - if (Quaternion.Angle(transform.rotation, TargetRotation) <= 0.01f) + if (Quaternion.Angle(transform.rotation, TargetRotation) <= AngleThreshold) { FinishTask(); } @@ -129,4 +153,4 @@ public void Deserialize(SerializationDataContainer serializer) Speed = serializer.GetSerializedFloat("Speed"); } } -} \ No newline at end of file +}