using UnityEngine; using System; namespace MoreMountains.Tools { /// /// Quaternion property setter /// public class MMPropertyLinkQuaternion : MMPropertyLink { public Func GetQuaternionDelegate; public Action SetQuaternionDelegate; protected Quaternion _initialValue = Quaternion.identity; protected Quaternion _newValue; /// /// On init we grab our initial initialization /// /// public override void Initialization(MMProperty property) { base.Initialization(property); _initialValue = (Quaternion)GetPropertyValue(property); } /// /// Creates cached getter and setters for properties /// /// public override void CreateGettersAndSetters(MMProperty property) { base.CreateGettersAndSetters(property); if (property.MemberType == MMProperty.MemberTypes.Property) { object firstArgument = (property.TargetScriptableObject == null) ? (object)property.TargetComponent : (object)property.TargetScriptableObject; if (property.MemberPropertyInfo.GetGetMethod() != null) { GetQuaternionDelegate = (Func)Delegate.CreateDelegate(typeof(Func), firstArgument, property.MemberPropertyInfo.GetGetMethod()); } if (property.MemberPropertyInfo.GetSetMethod() != null) { SetQuaternionDelegate = (Action)Delegate.CreateDelegate(typeof(Action), firstArgument, property.MemberPropertyInfo.GetSetMethod()); } _getterSetterInitialized = true; } } /// /// Gets the raw value of the property, a normalized float value, caching the operation if possible /// /// /// /// public override object GetValue(MMPropertyEmitter emitter, MMProperty property) { return GetValueOptimized(property); } /// /// Sets the raw property value, float normalized, caching the operation if possible /// /// /// /// public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue) { SetValueOptimized(property, (Quaternion)newValue); } /// /// Returns this property link's level between 0 and 1 /// /// /// /// /// public override float GetLevel(MMPropertyEmitter emitter, MMProperty property) { float axisValue = 0f; Quaternion propertyQuaternion = GetValueOptimized(property); switch (emitter.Vector3Option) { case MMPropertyEmitter.Vector3Options.X: axisValue = propertyQuaternion.eulerAngles.x; break; case MMPropertyEmitter.Vector3Options.Y: axisValue = propertyQuaternion.eulerAngles.y; break; case MMPropertyEmitter.Vector3Options.Z: axisValue = propertyQuaternion.eulerAngles.z; break; } axisValue = MMMaths.Clamp(axisValue, emitter.QuaternionRemapMinToZero, emitter.QuaternionRemapMaxToOne, emitter.ClampMin, emitter.ClampMax); float returnValue = MMMaths.Remap(axisValue, emitter.QuaternionRemapMinToZero, emitter.QuaternionRemapMaxToOne, 0f, 1f); emitter.Level = returnValue; return returnValue; } /// /// Sets the level, based on remap zero and remap one, angles in degree /// /// /// /// public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level) { base.SetLevel(receiver, property, level); _newValue = (receiver.RelativeValue) ? _initialValue : Quaternion.identity; if (receiver.ModifyX) { float newX = MMMaths.Remap(level, 0f, 1f, receiver.QuaternionRemapZero.x, receiver.QuaternionRemapOne.x); _newValue = _newValue * Quaternion.AngleAxis(newX, Vector3.right); } if (receiver.ModifyY) { float newY = MMMaths.Remap(level, 0f, 1f, receiver.QuaternionRemapZero.y, receiver.QuaternionRemapOne.y); _newValue = _newValue * Quaternion.AngleAxis(newY, Vector3.up); } if (receiver.ModifyZ) { float newZ = MMMaths.Remap(level, 0f, 1f, receiver.QuaternionRemapZero.z, receiver.QuaternionRemapOne.z); _newValue = _newValue * Quaternion.AngleAxis(newZ, Vector3.forward); } SetValueOptimized(property, _newValue); } /// /// Gets either the cached value or the raw value /// /// /// protected virtual Quaternion GetValueOptimized(MMProperty property) { return _getterSetterInitialized ? GetQuaternionDelegate() : (Quaternion)GetPropertyValue(property); } /// /// Sets either the cached value or the raw value /// /// /// protected virtual void SetValueOptimized(MMProperty property, Quaternion newValue) { if (_getterSetterInitialized) { SetQuaternionDelegate(_newValue); } else { SetPropertyValue(property, _newValue); } } } }