namespace Zinnia.Tracking.Follow.Modifier.Property.Rotation
{
using UnityEngine;
using Zinnia.Data.Type;
using Zinnia.Extension;
using Zinnia.Tracking.Velocity;
///
/// Rotates the target around the applied axes based on the angular velocity provided by a source .
///
public class RotateAroundAngularVelocity : PropertyModifier
{
[Tooltip("The VelocityTracker that is the source of the angular velocity.")]
[SerializeField]
private VelocityTracker angularVelocitySource;
///
/// The that is the source of the angular velocity.
///
public VelocityTracker AngularVelocitySource
{
get
{
return angularVelocitySource;
}
set
{
angularVelocitySource = value;
}
}
[Tooltip("Multiplies the AngularVelocitySource by this value.")]
[SerializeField]
private Vector3 sourceMultiplier = Vector3.one;
///
/// Multiplies the by this value.
///
public Vector3 SourceMultiplier
{
get
{
return sourceMultiplier;
}
set
{
sourceMultiplier = value;
}
}
[Tooltip("The axes to apply the angular velocity to.")]
[SerializeField]
private Vector3State applyToAxis;
///
/// The axes to apply the angular velocity to.
///
public Vector3State ApplyToAxis
{
get
{
return applyToAxis;
}
set
{
applyToAxis = value;
}
}
[Tooltip("When true, transforms the angular velocity to be in target's space instead of world space.")]
[SerializeField]
private bool inTargetSpace;
///
/// When true, transforms the angular velocity to be in target's space instead of world space.
///
public bool InTargetSpace
{
get
{
return inTargetSpace;
}
set
{
inTargetSpace = value;
}
}
///
/// Clears .
///
public virtual void ClearAngularVelocitySource()
{
if (!this.IsValidState())
{
return;
}
AngularVelocitySource = default;
}
///
/// Sets the x value.
///
/// The value to set to.
public virtual void SetSourceMultiplierX(float value)
{
SourceMultiplier = new Vector3(value, SourceMultiplier.y, SourceMultiplier.z);
}
///
/// Sets the y value.
///
/// The value to set to.
public virtual void SetSourceMultiplierY(float value)
{
SourceMultiplier = new Vector3(SourceMultiplier.x, value, SourceMultiplier.z);
}
///
/// Sets the z value.
///
/// The value to set to.
public virtual void SetSourceMultiplierZ(float value)
{
SourceMultiplier = new Vector3(SourceMultiplier.x, SourceMultiplier.y, value);
}
///
/// Sets the x value.
///
/// The value to set to.
public virtual void SetApplyToAxisX(bool value)
{
ApplyToAxis = new Vector3State(value, ApplyToAxis.yState, ApplyToAxis.zState);
}
///
/// Sets the y value.
///
/// The value to set to.
public virtual void SetApplyToAxisY(bool value)
{
ApplyToAxis = new Vector3State(ApplyToAxis.xState, value, ApplyToAxis.zState);
}
///
/// Sets the z value.
///
/// The value to set to.
public virtual void SetApplyToAxisZ(bool value)
{
ApplyToAxis = new Vector3State(ApplyToAxis.xState, ApplyToAxis.yState, value);
}
///
/// Modifies the target rotation to match the given source rotation.
///
/// The source is unused in this implementation.
/// The target to modify.
/// The offset of the target against the source when modifying.
protected override void DoModify(GameObject source, GameObject target, GameObject offset = null)
{
if (AngularVelocitySource == null)
{
return;
}
Vector3 input = InTargetSpace
? target.transform.parent.InverseTransformVector(AngularVelocitySource.GetAngularVelocity())
: AngularVelocitySource.GetAngularVelocity();
input.Scale(SourceMultiplier);
input.Scale(ApplyToAxis.ToVector3());
Vector3 point = offset != null ? offset.transform.position : target.transform.position;
target.transform.RotateAround(point, target.transform.right, input.x);
target.transform.RotateAround(point, target.transform.up, input.y);
target.transform.RotateAround(point, target.transform.forward, input.z);
}
}
}