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); } } }