namespace UnityEngine.Animations.Rigging { /// /// The MultiAim constraint data. /// [System.Serializable] public struct MultiAimConstraintData : IAnimationJobData, IMultiAimConstraintData { /// /// Axis type for MultiAimConstraint. /// public enum Axis { /// Positive X Axis (1, 0, 0) X, /// Negative X Axis (-1, 0, 0) X_NEG, /// Positive Y Axis (0, 1, 0) Y, /// Negative Y Axis (0, -1, 0) Y_NEG, /// Positive Z Axis (0, 0, 1) Z, /// Negative Z Axis (0, 0, -1) Z_NEG } /// /// Specifies how the world up vector used by the Multi-Aim constraint is defined. /// public enum WorldUpType { /// Neither defines nor uses a world up vector. None, /// Uses and defines the world up vector as the Unity Scene up vector (the Y axis). SceneUp, /// Uses and defines the world up vector as a vector from the constrained object, in the direction of the up object. ObjectUp, /// Uses and defines the world up vector as relative to the local space of the object. ObjectRotationUp, /// Uses and defines the world up vector as a vector specified by the user. Vector }; internal const float k_MinAngularLimit = -180f; internal const float k_MaxAngularLimit = 180f; [SerializeField] Transform m_ConstrainedObject; [SyncSceneToStream, SerializeField, WeightRange(0f, 1f)] WeightedTransformArray m_SourceObjects; [SyncSceneToStream, SerializeField] Vector3 m_Offset; [SyncSceneToStream, SerializeField, Range(k_MinAngularLimit, k_MaxAngularLimit)] float m_MinLimit; [SyncSceneToStream, SerializeField, Range(k_MinAngularLimit, k_MaxAngularLimit)] float m_MaxLimit; [NotKeyable, SerializeField] Axis m_AimAxis; [NotKeyable, SerializeField] Axis m_UpAxis; [NotKeyable, SerializeField] WorldUpType m_WorldUpType; [SyncSceneToStream, SerializeField] Transform m_WorldUpObject; [NotKeyable, SerializeField] Axis m_WorldUpAxis; [NotKeyable, SerializeField] bool m_MaintainOffset; [NotKeyable, SerializeField] Vector3Bool m_ConstrainedAxes; /// public Transform constrainedObject { get => m_ConstrainedObject; set => m_ConstrainedObject = value; } /// public WeightedTransformArray sourceObjects { get => m_SourceObjects; set => m_SourceObjects = value; } /// public bool maintainOffset { get => m_MaintainOffset; set => m_MaintainOffset = value; } /// /// Post-Rotation offset applied to the constrained Transform. /// public Vector3 offset { get => m_Offset; set => m_Offset = value; } /// /// Minimum and maximum value of the rotation permitted for the constraint. The values are in degrees. /// public Vector2 limits { get => new Vector2(m_MinLimit, m_MaxLimit); set { m_MinLimit = Mathf.Clamp(value.x, k_MinAngularLimit, k_MaxAngularLimit); m_MaxLimit = Mathf.Clamp(value.y, k_MinAngularLimit, k_MaxAngularLimit); } } /// public Axis aimAxis { get => m_AimAxis; set => m_AimAxis = value; } /// public Axis upAxis { get => m_UpAxis; set => m_UpAxis = value; } /// public WorldUpType worldUpType { get => m_WorldUpType; set => m_WorldUpType = value; } /// public Axis worldUpAxis { get => m_WorldUpAxis; set => m_WorldUpAxis = value; } /// public Transform worldUpObject { get => m_WorldUpObject; set => m_WorldUpObject = value; } /// public bool constrainedXAxis { get => m_ConstrainedAxes.x; set => m_ConstrainedAxes.x = value; } /// public bool constrainedYAxis { get => m_ConstrainedAxes.y; set => m_ConstrainedAxes.y = value; } /// public bool constrainedZAxis { get => m_ConstrainedAxes.z; set => m_ConstrainedAxes.z = value; } /// Vector3 IMultiAimConstraintData.aimAxis => Convert(m_AimAxis); /// Vector3 IMultiAimConstraintData.upAxis => Convert(m_UpAxis); /// int IMultiAimConstraintData.worldUpType => (int) m_WorldUpType; /// Vector3 IMultiAimConstraintData.worldUpAxis => Convert(m_WorldUpAxis); /// string IMultiAimConstraintData.offsetVector3Property => ConstraintsUtils.ConstructConstraintDataPropertyName(nameof(m_Offset)); /// string IMultiAimConstraintData.minLimitFloatProperty => ConstraintsUtils.ConstructConstraintDataPropertyName(nameof(m_MinLimit)); /// string IMultiAimConstraintData.maxLimitFloatProperty => ConstraintsUtils.ConstructConstraintDataPropertyName(nameof(m_MaxLimit)); /// string IMultiAimConstraintData.sourceObjectsProperty => ConstraintsUtils.ConstructConstraintDataPropertyName(nameof(m_SourceObjects)); /// bool IAnimationJobData.IsValid() { if (m_ConstrainedObject == null || m_SourceObjects.Count == 0) return false; foreach (var src in m_SourceObjects) if (src.transform == null) return false; return true; } /// void IAnimationJobData.SetDefaultValues() { m_ConstrainedObject = null; m_UpAxis = Axis.Y; m_AimAxis = Axis.Z; m_WorldUpType = WorldUpType.None; m_WorldUpAxis = Axis.Y; m_WorldUpObject = null; m_SourceObjects.Clear(); m_MaintainOffset = false; m_Offset = Vector3.zero; m_ConstrainedAxes = new Vector3Bool(true); m_MinLimit = -180f; m_MaxLimit = 180f; } static Vector3 Convert(Axis axis) { switch (axis) { case Axis.X: return Vector3.right; case Axis.X_NEG: return Vector3.left; case Axis.Y: return Vector3.up; case Axis.Y_NEG: return Vector3.down; case Axis.Z: return Vector3.forward; case Axis.Z_NEG: return Vector3.back; default: return Vector3.up; } } } /// /// MultiAim constraint. /// [DisallowMultipleComponent, AddComponentMenu("Animation Rigging/Multi-Aim Constraint")] [HelpURL("https://docs.unity3d.com/Packages/com.unity.animation.rigging@1.3/manual/constraints/MultiAimConstraint.html")] public class MultiAimConstraint : RigConstraint< MultiAimConstraintJob, MultiAimConstraintData, MultiAimConstraintJobBinder > { /// protected override void OnValidate() { base.OnValidate(); var weights = m_Data.sourceObjects; WeightedTransformArray.OnValidate(ref weights); m_Data.sourceObjects = weights; var limits = m_Data.limits; limits.x = Mathf.Clamp( limits.x, MultiAimConstraintData.k_MinAngularLimit, MultiAimConstraintData.k_MaxAngularLimit ); limits.y = Mathf.Clamp( limits.y, MultiAimConstraintData.k_MinAngularLimit, MultiAimConstraintData.k_MaxAngularLimit ); m_Data.limits = limits; } } }