71 lines
3.2 KiB
C#
71 lines
3.2 KiB
C#
![]() |
using UnityEngine;
|
||
|
|
||
|
namespace BehaviorDesigner.Runtime.Tasks.Movement
|
||
|
{
|
||
|
[TaskDescription("Rotates towards the specified rotation. The rotation can either be specified by a transform or rotation. If the transform "+
|
||
|
"is used then the rotation will not be used.")]
|
||
|
[TaskCategory("Movement")]
|
||
|
[HelpURL("https://www.opsive.com/support/documentation/behavior-designer-movement-pack/")]
|
||
|
[TaskIcon("04fb8138ea905c04ea39265f778fe1a4", "9bded0edc8b2a2f478fc28396fa41df2")]
|
||
|
public class RotateTowards : Action
|
||
|
{
|
||
|
[Tooltip("Should the 2D version be used?")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("usePhysics2D")]
|
||
|
public bool m_UsePhysics2D;
|
||
|
[Tooltip("The agent is done rotating when the angle is less than this value")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("rotationEpsilon")]
|
||
|
public SharedFloat m_RotationEpsilon = 0.5f;
|
||
|
[Tooltip("The maximum number of angles the agent can rotate in a single tick")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("maxLookAtRotationDelta")]
|
||
|
public SharedFloat m_MaxLookAtRotationDelta = 1;
|
||
|
[Tooltip("Should the rotation only affect the Y axis?")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("onlyY")]
|
||
|
public SharedBool m_OnlyY;
|
||
|
[Tooltip("The GameObject that the agent is rotating towards")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("target")]
|
||
|
public SharedGameObject m_Target;
|
||
|
[Tooltip("If target is null then use the target rotation")]
|
||
|
[UnityEngine.Serialization.FormerlySerializedAs("targetRotation")]
|
||
|
public SharedVector3 m_TargetRotation;
|
||
|
|
||
|
public override TaskStatus OnUpdate()
|
||
|
{
|
||
|
var rotation = Target();
|
||
|
// Return a task status of success once we are done rotating
|
||
|
if (Quaternion.Angle(transform.rotation, rotation) < m_RotationEpsilon.Value) {
|
||
|
return TaskStatus.Success;
|
||
|
}
|
||
|
// We haven't reached the target yet so keep rotating towards it
|
||
|
transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation, m_MaxLookAtRotationDelta.Value);
|
||
|
return TaskStatus.Running;
|
||
|
}
|
||
|
|
||
|
// Return targetPosition if targetTransform is null
|
||
|
private Quaternion Target()
|
||
|
{
|
||
|
if (m_Target == null || m_Target.Value == null) {
|
||
|
return Quaternion.Euler(m_TargetRotation.Value);
|
||
|
}
|
||
|
var position = m_Target.Value.transform.position - transform.position;
|
||
|
if (m_OnlyY.Value) {
|
||
|
position.y = 0;
|
||
|
}
|
||
|
if (m_UsePhysics2D) {
|
||
|
var angle = Mathf.Atan2(position.y, position.x) * Mathf.Rad2Deg;
|
||
|
return Quaternion.AngleAxis(angle, Vector3.forward);
|
||
|
}
|
||
|
return Quaternion.LookRotation(position);
|
||
|
}
|
||
|
|
||
|
// Reset the public variables
|
||
|
public override void OnReset()
|
||
|
{
|
||
|
m_UsePhysics2D = false;
|
||
|
m_RotationEpsilon = 0.5f;
|
||
|
m_MaxLookAtRotationDelta = 1f;
|
||
|
m_OnlyY = false;
|
||
|
m_Target = null;
|
||
|
m_TargetRotation = Vector3.zero;
|
||
|
}
|
||
|
}
|
||
|
}
|