chore: initial commit
This commit is contained in:
8
Assets/Feel/MMTools/Core/MMRadio/MMEmitterReceiver.meta
Normal file
8
Assets/Feel/MMTools/Core/MMRadio/MMEmitterReceiver.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5820c9edef53d494881bfde92df4adb7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// This component lets you very easily have one property drive the value of another property.
|
||||
/// To do so, drag the object with the property you want to "read" from into the Emitter Property slot, then select the component the property is on, and finally the property itself.
|
||||
/// Then drag the object with the property you want to "write" to into the ReceiverProperty slot, and pick the property you want to drive with the emitter's value.
|
||||
/// </summary>
|
||||
public class MMEmmiterReceiver : MonoBehaviour
|
||||
{
|
||||
[MMInformation(
|
||||
"This component lets you very easily have one property drive the value of another property. " +
|
||||
"To do so, drag the object with the property you want to 'read' from into the Emitter Property slot, then select the component the property is on, and finally the property itself." +
|
||||
"Then drag the object with the property you want to 'write' to into the ReceiverProperty slot, and pick the property you want to drive with the emitter's value.",
|
||||
MoreMountains.Tools.MMInformationAttribute.InformationType.Info, false)]
|
||||
public bool Emitting = true;
|
||||
|
||||
[Header("Emitter")]
|
||||
/// the property whose value you want to read and to have drive the ReceiverProperty's value
|
||||
[Tooltip("the property whose value you want to read and to have drive the ReceiverProperty's value")]
|
||||
public MMPropertyEmitter EmitterProperty;
|
||||
|
||||
[Header("Receiver")]
|
||||
/// the property whose value you want to be driven by the EmitterProperty's value
|
||||
[Tooltip("the property whose value you want to be driven by the EmitterProperty's value")]
|
||||
public MMPropertyReceiver ReceiverProperty;
|
||||
|
||||
/// a delegate to handle value changes
|
||||
public delegate void OnValueChangeDelegate();
|
||||
/// what to do on value change
|
||||
public OnValueChangeDelegate OnValueChange;
|
||||
|
||||
protected float _levelLastFrame;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake we initialize both properties
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
EmitterProperty.Initialization(EmitterProperty.TargetComponent.gameObject);
|
||||
ReceiverProperty.Initialization(ReceiverProperty.TargetComponent.gameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update we emit our value to our receiver
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
EmitValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If needed, reads the current level of the emitter and sets it to the receiver
|
||||
/// </summary>
|
||||
protected virtual void EmitValue()
|
||||
{
|
||||
if (!Emitting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float level = EmitterProperty.GetLevel();
|
||||
|
||||
if (level != _levelLastFrame)
|
||||
{
|
||||
// we trigger a value change event
|
||||
OnValueChange?.Invoke();
|
||||
|
||||
ReceiverProperty?.SetLevel(level);
|
||||
}
|
||||
|
||||
_levelLastFrame = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fe23ce5bc9554f46aebd960ab58b9eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Feel/MMTools/Core/MMRadio/MMProperty.meta
Normal file
8
Assets/Feel/MMTools/Core/MMRadio/MMProperty.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 556746a88058ca94bbcbd62da24a1f6f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
94
Assets/Feel/MMTools/Core/MMRadio/MMProperty/MMProperty.cs
Normal file
94
Assets/Feel/MMTools/Core/MMRadio/MMProperty/MMProperty.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
public class MMProperty
|
||||
{
|
||||
public enum MemberTypes { Property, Field }
|
||||
public Component TargetComponent;
|
||||
public ScriptableObject TargetScriptableObject;
|
||||
public MemberTypes MemberType;
|
||||
public PropertyInfo MemberPropertyInfo;
|
||||
public FieldInfo MemberFieldInfo;
|
||||
public Type PropertyType;
|
||||
public string MemberName;
|
||||
|
||||
public MMProperty(Component targetComponent, MemberTypes type, PropertyInfo propertyInfo, FieldInfo fieldInfo, string memberName, ScriptableObject targetScriptable)
|
||||
{
|
||||
TargetComponent = targetComponent;
|
||||
TargetScriptableObject = targetScriptable;
|
||||
MemberType = type;
|
||||
MemberPropertyInfo = propertyInfo;
|
||||
MemberFieldInfo = fieldInfo;
|
||||
MemberName = memberName;
|
||||
}
|
||||
|
||||
public static MMProperty FindProperty(string propertyName, Component targetComponent, GameObject source, ScriptableObject scriptable)
|
||||
{
|
||||
FieldInfo fieldInfo = null;
|
||||
PropertyInfo propInfo = null;
|
||||
MMProperty TargetProperty = null;
|
||||
|
||||
if (scriptable == null)
|
||||
{
|
||||
propInfo = targetComponent.GetType().GetProperty(propertyName);
|
||||
if (propInfo == null)
|
||||
{
|
||||
fieldInfo = targetComponent.GetType().GetField(propertyName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldInfo = scriptable.GetType().GetField(propertyName);
|
||||
}
|
||||
|
||||
if (propInfo != null)
|
||||
{
|
||||
TargetProperty = new MMProperty(targetComponent, MemberTypes.Property, propInfo, null, propertyName, scriptable);
|
||||
}
|
||||
if (fieldInfo != null)
|
||||
{
|
||||
TargetProperty = new MMProperty(targetComponent, MemberTypes.Field, null, fieldInfo, propertyName, scriptable);
|
||||
}
|
||||
if (propertyName == "")
|
||||
{
|
||||
if (source != null)
|
||||
{
|
||||
Debug.LogError("The MMProperty on " + source.name + " : you need to pick a property from the Property list");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if ((propInfo == null) && (fieldInfo == null))
|
||||
{
|
||||
if (source != null)
|
||||
{
|
||||
Debug.LogError("The MMProperty on " + source.name + " couldn't find any property or field named " + propertyName + " on " + targetComponent.name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (scriptable == null)
|
||||
{
|
||||
if (TargetProperty.MemberType == MemberTypes.Property)
|
||||
{
|
||||
TargetProperty.MemberPropertyInfo = targetComponent.GetType().GetProperty(TargetProperty.MemberName);
|
||||
TargetProperty.PropertyType = TargetProperty.MemberPropertyInfo.PropertyType;
|
||||
}
|
||||
else if (TargetProperty.MemberType == MemberTypes.Field)
|
||||
{
|
||||
TargetProperty.MemberFieldInfo = targetComponent.GetType().GetField(TargetProperty.MemberName);
|
||||
TargetProperty.PropertyType = TargetProperty.MemberFieldInfo.FieldType;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetProperty.MemberFieldInfo = scriptable.GetType().GetField(TargetProperty.MemberName);
|
||||
TargetProperty.PropertyType = TargetProperty.MemberFieldInfo.FieldType;
|
||||
}
|
||||
|
||||
return TargetProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e5da26383e93e941be7bdbcd7b5d940
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3a1806a84d8016419f53c93976ff64c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class, meant to be extended, used to control a MMProperty and get/set its value
|
||||
/// </summary>
|
||||
public abstract class MMPropertyLink
|
||||
{
|
||||
protected bool _getterSetterInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initialization method
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public virtual void Initialization(MMProperty property)
|
||||
{
|
||||
CreateGettersAndSetters(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method used to cache getter and setter for properties, not fields (sadly)
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public virtual void CreateGettersAndSetters(MMProperty property)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the "level" of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public virtual float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the property's level, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public virtual void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
receiver.Level = level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public virtual object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public virtual void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the selected property
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual object GetPropertyValue(MMProperty property)
|
||||
{
|
||||
object target = (property.TargetScriptableObject == null) ? (object)property.TargetComponent : (object)property.TargetScriptableObject;
|
||||
|
||||
if (property.MemberType == MMProperty.MemberTypes.Property)
|
||||
{
|
||||
return property.MemberPropertyInfo.GetValue(target);
|
||||
}
|
||||
else if (property.MemberType == MMProperty.MemberTypes.Field)
|
||||
{
|
||||
return property.MemberFieldInfo.GetValue(target);
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the selected property
|
||||
/// </summary>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetPropertyValue(MMProperty property, object newValue)
|
||||
{
|
||||
object target = (property.TargetScriptableObject == null) ? (object)property.TargetComponent : (object)property.TargetScriptableObject;
|
||||
|
||||
if (property.MemberType == MMProperty.MemberTypes.Property)
|
||||
{
|
||||
property.MemberPropertyInfo.SetValue(target, newValue);
|
||||
}
|
||||
else if (property.MemberType == MMProperty.MemberTypes.Field)
|
||||
{
|
||||
property.MemberFieldInfo.SetValue(target, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1ca607d01430f9419336e2d59ee639b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Bool property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkBool : MMPropertyLink
|
||||
{
|
||||
public Func<bool> GetBoolDelegate;
|
||||
public Action<bool> SetBoolDelegate;
|
||||
|
||||
protected bool _initialValue;
|
||||
protected bool _newValue;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our initial value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (bool)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetBoolDelegate = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetBoolDelegate = (Action<bool>)Delegate.CreateDelegate(typeof(Action<bool>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (bool)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
bool boolValue = GetValueOptimized(property);
|
||||
float returnValue = (boolValue == true) ? emitter.BoolRemapTrue : emitter.BoolRemapFalse;
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the level (more than the link's Threshold > true, less > false)
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
_newValue = (level > receiver.Threshold) ? receiver.BoolRemapOne : receiver.BoolRemapZero;
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetBoolDelegate() : (bool)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, bool newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetBoolDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d260fd7dcadc0284a8d734805d374223
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Color property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkColor : MMPropertyLink
|
||||
{
|
||||
public Func<Color> GetColorDelegate;
|
||||
public Action<Color> SetColorDelegate;
|
||||
|
||||
protected Color _initialValue;
|
||||
protected Color _newValue;
|
||||
protected Color _color;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our initial color
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (Color)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetColorDelegate = (Func<Color>)Delegate.CreateDelegate(typeof(Func<Color>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetColorDelegate = (Action<Color>)Delegate.CreateDelegate(typeof(Action<Color>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (Color)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
_color = _getterSetterInitialized ? GetColorDelegate() : (Color)GetPropertyValue(property);
|
||||
|
||||
return _color.MeanRGB();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level, lerping between ColorRemapZero and One
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue = Color.LerpUnclamped(receiver.ColorRemapZero, receiver.ColorRemapOne, level);
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Color GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetColorDelegate() : (Color)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, Color newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetColorDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 991ae4d843392bc4e9ec4e7d8649d94e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,141 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Float property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkFloat : MMPropertyLink
|
||||
{
|
||||
public Func<float> GetFloatDelegate;
|
||||
public Action<float> SetFloatDelegate;
|
||||
|
||||
protected float _initialValue;
|
||||
protected float _newValue;
|
||||
|
||||
/// <summary>
|
||||
/// On init, grabs the initial float value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (float)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetFloatDelegate = (Func<float>)Delegate.CreateDelegate(typeof(Func<float>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetFloatDelegate = (Action<float>)Delegate.CreateDelegate(typeof(Action<float>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (float)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
float returnValue = GetValueOptimized(property);
|
||||
|
||||
returnValue = MMMaths.Clamp(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, emitter.ClampMin, emitter.ClampMax);
|
||||
returnValue = MMMaths.Remap(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, 0f, 1f);
|
||||
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue = MMMaths.Remap(level, 0f, 1f, receiver.FloatRemapZero, receiver.FloatRemapOne);
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual float GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetFloatDelegate() : (float)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, float newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetFloatDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2efa1b899c8751046b9617c7268d54f8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,142 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Int property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkInt : MMPropertyLink
|
||||
{
|
||||
public Func<int> GetIntDelegate;
|
||||
public Action<int> SetIntDelegate;
|
||||
|
||||
protected int _initialValue;
|
||||
protected int _newValue;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our initial value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (int)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetIntDelegate = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetIntDelegate = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (int)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
float returnValue = GetValueOptimized(property);
|
||||
|
||||
returnValue = MMMaths.Clamp(returnValue, emitter.IntRemapMinToZero, emitter.IntRemapMaxToOne, emitter.ClampMin, emitter.ClampMax);
|
||||
returnValue = MMMaths.Remap(returnValue, emitter.IntRemapMinToZero, emitter.IntRemapMaxToOne, 0f, 1f);
|
||||
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified level
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue = (int)MMMaths.Remap(level, 0f, 1f, receiver.IntRemapZero, receiver.IntRemapOne);
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual int GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetIntDelegate() : (int)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, int newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetIntDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6dcec9f2c4bea14baa2582a1bae072a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,169 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Quaternion property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkQuaternion : MMPropertyLink
|
||||
{
|
||||
public Func<Quaternion> GetQuaternionDelegate;
|
||||
public Action<Quaternion> SetQuaternionDelegate;
|
||||
|
||||
protected Quaternion _initialValue = Quaternion.identity;
|
||||
protected Quaternion _newValue;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our initial initialization
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (Quaternion)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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<Quaternion>)Delegate.CreateDelegate(typeof(Func<Quaternion>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetQuaternionDelegate = (Action<Quaternion>)Delegate.CreateDelegate(typeof(Action<Quaternion>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (Quaternion)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level, based on remap zero and remap one, angles in degree
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Quaternion GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetQuaternionDelegate() : (Quaternion)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, Quaternion newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetQuaternionDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dc025857430aa041b4588942e1f27d7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,117 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// String property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkString : MMPropertyLink
|
||||
{
|
||||
public Func<string> GetStringDelegate;
|
||||
public Action<string> SetStringDelegate;
|
||||
|
||||
protected string _initialValue;
|
||||
protected string _newValue;
|
||||
|
||||
/// <summary>
|
||||
/// On initialization we grab our initial value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (string)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetStringDelegate = (Func<string>)Delegate.CreateDelegate(typeof(Func<string>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetStringDelegate = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (string)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level (above threshold : remap one, under threshold : remap zero)
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
_newValue = (level > receiver.Threshold) ? receiver.StringRemapOne : receiver.StringRemapZero;
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual string GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetStringDelegate() : (string)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, string newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetStringDelegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac8f4e19669836447b70ca22e908a10c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,163 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Vector2 property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkVector2 : MMPropertyLink
|
||||
{
|
||||
public Func<Vector2> GetVector2Delegate;
|
||||
public Action<Vector2> SetVector2Delegate;
|
||||
|
||||
protected Vector2 _initialValue;
|
||||
protected Vector2 _newValue;
|
||||
protected Vector2 _vector2;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our vector2
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (Vector2)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetVector2Delegate = (Func<Vector2>)Delegate.CreateDelegate(typeof(Func<Vector2>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetVector2Delegate = (Action<Vector2>)Delegate.CreateDelegate(typeof(Action<Vector2>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (Vector2)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
_vector2 = _getterSetterInitialized ? GetVector2Delegate() : (Vector2)GetPropertyValue(property);
|
||||
|
||||
float newValue = 0f;
|
||||
|
||||
switch (emitter.Vector2Option)
|
||||
{
|
||||
case MMPropertyEmitter.Vector2Options.X:
|
||||
newValue = _vector2.x;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector2Options.Y:
|
||||
newValue = _vector2.y;
|
||||
break;
|
||||
}
|
||||
|
||||
float returnValue = newValue;
|
||||
returnValue = MMMaths.Clamp(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, emitter.ClampMin, emitter.ClampMax);
|
||||
returnValue = MMMaths.Remap(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, 0f, 1f);
|
||||
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified level
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue.x = receiver.ModifyX ? MMMaths.Remap(level, 0f, 1f, receiver.Vector2RemapZero.x, receiver.Vector2RemapOne.x) : 0f;
|
||||
_newValue.y = receiver.ModifyY ? MMMaths.Remap(level, 0f, 1f, receiver.Vector2RemapZero.y, receiver.Vector2RemapOne.y) : 0f;
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetVector2Delegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Vector2 GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetVector2Delegate() : (Vector2)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, Vector2 newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetVector2Delegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c074591fd378046418957bf77882defc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,159 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Vector3 property setter
|
||||
/// </summary>
|
||||
public class MMPropertyLinkVector3 : MMPropertyLink
|
||||
{
|
||||
public Func<Vector3> GetVector3Delegate;
|
||||
public Action<Vector3> SetVector3Delegate;
|
||||
|
||||
protected Vector3 _initialValue;
|
||||
protected Vector3 _newValue;
|
||||
protected Vector3 _vector3;
|
||||
|
||||
/// <summary>
|
||||
/// On init we grab our initial value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (Vector3)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetVector3Delegate = (Func<Vector3>)Delegate.CreateDelegate(typeof(Func<Vector3>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetVector3Delegate = (Action<Vector3>)Delegate.CreateDelegate(typeof(Action<Vector3>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (Vector3)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
_vector3 = GetValueOptimized(property);
|
||||
|
||||
float newValue = 0f;
|
||||
|
||||
switch (emitter.Vector3Option)
|
||||
{
|
||||
case MMPropertyEmitter.Vector3Options.X:
|
||||
newValue = _vector3.x;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector3Options.Y:
|
||||
newValue = _vector3.y;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector3Options.Z:
|
||||
newValue = _vector3.z;
|
||||
break;
|
||||
}
|
||||
|
||||
float returnValue = newValue;
|
||||
returnValue = MMMaths.Clamp(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, emitter.ClampMin, emitter.ClampMax);
|
||||
returnValue = MMMaths.Remap(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, 0f, 1f);
|
||||
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue.x = receiver.ModifyX ? MMMaths.Remap(level, 0f, 1f, receiver.Vector3RemapZero.x, receiver.Vector3RemapOne.x) : 0f;
|
||||
_newValue.y = receiver.ModifyY ? MMMaths.Remap(level, 0f, 1f, receiver.Vector3RemapZero.y, receiver.Vector3RemapOne.y) : 0f;
|
||||
_newValue.z = receiver.ModifyZ ? MMMaths.Remap(level, 0f, 1f, receiver.Vector3RemapZero.z, receiver.Vector3RemapOne.z) : 0f;
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Vector3 GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetVector3Delegate() : (Vector3)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, Vector3 newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetVector3Delegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f28b7b1842189d04f8eb2c7093835fc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,150 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
public class MMPropertyLinkVector4 : MMPropertyLink
|
||||
{
|
||||
public Func<Vector4> GetVector4Delegate;
|
||||
public Action<Vector4> SetVector4Delegate;
|
||||
|
||||
protected Vector4 _initialValue;
|
||||
protected Vector4 _newValue;
|
||||
protected Vector4 _vector4;
|
||||
|
||||
public override void Initialization(MMProperty property)
|
||||
{
|
||||
base.Initialization(property);
|
||||
_initialValue = (Vector4)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates cached getter and setters for properties
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
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)
|
||||
{
|
||||
GetVector4Delegate = (Func<Vector4>)Delegate.CreateDelegate(typeof(Func<Vector4>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetGetMethod());
|
||||
}
|
||||
if (property.MemberPropertyInfo.GetSetMethod() != null)
|
||||
{
|
||||
SetVector4Delegate = (Action<Vector4>)Delegate.CreateDelegate(typeof(Action<Vector4>),
|
||||
firstArgument,
|
||||
property.MemberPropertyInfo.GetSetMethod());
|
||||
}
|
||||
_getterSetterInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw value of the property, a normalized float value, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="emitter"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
public override object GetValue(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
return GetValueOptimized(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the raw property value, float normalized, caching the operation if possible
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
public override void SetValue(MMPropertyReceiver receiver, MMProperty property, object newValue)
|
||||
{
|
||||
SetValueOptimized(property, (Vector4)newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this property link's level between 0 and 1
|
||||
/// </summary>
|
||||
/// <param name="receiver"></param>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="level"></param>
|
||||
/// <returns></returns>
|
||||
public override float GetLevel(MMPropertyEmitter emitter, MMProperty property)
|
||||
{
|
||||
_vector4 = GetValueOptimized(property);
|
||||
|
||||
float newValue = 0f;
|
||||
|
||||
switch (emitter.Vector4Option)
|
||||
{
|
||||
case MMPropertyEmitter.Vector4Options.X:
|
||||
newValue = _vector4.x;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector4Options.Y:
|
||||
newValue = _vector4.y;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector4Options.Z:
|
||||
newValue = _vector4.z;
|
||||
break;
|
||||
case MMPropertyEmitter.Vector4Options.W:
|
||||
newValue = _vector4.w;
|
||||
break;
|
||||
}
|
||||
|
||||
float returnValue = newValue;
|
||||
returnValue = MMMaths.Clamp(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, emitter.ClampMin, emitter.ClampMax);
|
||||
returnValue = MMMaths.Remap(returnValue, emitter.FloatRemapMinToZero, emitter.FloatRemapMaxToOne, 0f, 1f);
|
||||
|
||||
emitter.Level = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public override void SetLevel(MMPropertyReceiver receiver, MMProperty property, float level)
|
||||
{
|
||||
base.SetLevel(receiver, property, level);
|
||||
|
||||
_newValue.x = receiver.ModifyX ? MMMaths.Remap(level, 0f, 1f, receiver.Vector4RemapZero.x, receiver.Vector4RemapOne.x) : 0f;
|
||||
_newValue.y = receiver.ModifyY ? MMMaths.Remap(level, 0f, 1f, receiver.Vector4RemapZero.y, receiver.Vector4RemapOne.y) : 0f;
|
||||
_newValue.z = receiver.ModifyZ ? MMMaths.Remap(level, 0f, 1f, receiver.Vector4RemapZero.z, receiver.Vector4RemapOne.z) : 0f;
|
||||
_newValue.w = receiver.ModifyW ? MMMaths.Remap(level, 0f, 1f, receiver.Vector4RemapZero.w, receiver.Vector4RemapOne.w) : 0f;
|
||||
|
||||
if (receiver.RelativeValue)
|
||||
{
|
||||
_newValue = _initialValue + _newValue;
|
||||
}
|
||||
|
||||
SetValueOptimized(property, _newValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Vector4 GetValueOptimized(MMProperty property)
|
||||
{
|
||||
return _getterSetterInitialized ? GetVector4Delegate() : (Vector4)GetPropertyValue(property);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets either the cached value or the raw value
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
/// <param name="newValue"></param>
|
||||
protected virtual void SetValueOptimized(MMProperty property, Vector4 newValue)
|
||||
{
|
||||
if (_getterSetterInitialized)
|
||||
{
|
||||
SetVector4Delegate(_newValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValue(property, _newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96afd1836702fcc4297951d56333a9e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 467c2b48eb6f08b478d8ed7a178f5b55
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to pick a property, and remap its value for emission/broadcast
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MMPropertyEmitter : MMPropertyPicker
|
||||
{
|
||||
/// the min value to clamp this property value to
|
||||
public bool ClampMin = true;
|
||||
/// the max value to clamp this property value to
|
||||
public bool ClampMax = true;
|
||||
|
||||
// vectors ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the possible axis to look for on a Vector2
|
||||
public enum Vector2Options { X, Y }
|
||||
/// the possible axis to look for on a Vector3
|
||||
public enum Vector3Options { X, Y, Z }
|
||||
/// the possible axis to look for on a Vector4
|
||||
public enum Vector4Options { X, Y, Z, W }
|
||||
/// the selected axis on Vector2
|
||||
public Vector2Options Vector2Option;
|
||||
/// the selected axis on Vector3
|
||||
public Vector3Options Vector3Option;
|
||||
/// the selected axis on Vector4
|
||||
public Vector4Options Vector4Option;
|
||||
|
||||
// bool ----------------------------------------------------------------------------------------------------------------------
|
||||
/// what to remap a false value to
|
||||
public float BoolRemapFalse = 0f;
|
||||
/// what to remap a true value to
|
||||
public float BoolRemapTrue = 1f;
|
||||
|
||||
// int ----------------------------------------------------------------------------------------------------------------------
|
||||
/// what to remap the int min to
|
||||
public int IntRemapMinToZero = 0;
|
||||
/// what to remap the int max to
|
||||
public int IntRemapMaxToOne = 1;
|
||||
|
||||
// float ----------------------------------------------------------------------------------------------------------------------
|
||||
/// what to remap the float min to
|
||||
public float FloatRemapMinToZero = 0f;
|
||||
/// what to remap the float max to
|
||||
public float FloatRemapMaxToOne = 1f;
|
||||
|
||||
// quaternion ----------------------------------------------------------------------------------------------------------------------
|
||||
/// what to remap the quaternion min to
|
||||
public float QuaternionRemapMinToZero = 0f;
|
||||
/// what to remap the quaternion max to
|
||||
public float QuaternionRemapMaxToOne = 360f;
|
||||
/// this property's current level
|
||||
public float Level = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets this property's level
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual float GetLevel()
|
||||
{
|
||||
return _propertySetter.GetLevel(this, _targetMMProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dc665c3421b61d40bd0c4c6eaab763f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to pick a property on a target object / component / scriptable object
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MMPropertyPicker
|
||||
{
|
||||
/// the target object to look for a property on
|
||||
public UnityEngine.Object TargetObject;
|
||||
/// the component to look for a property on | storage only, not displayed in the inspector
|
||||
public Component TargetComponent;
|
||||
/// the component to look for a property on | storage only, not displayed in the inspector
|
||||
public ScriptableObject TargetScriptableObject;
|
||||
/// the name of the property to link to
|
||||
public string TargetPropertyName;
|
||||
/// whether or not this property has been found
|
||||
public virtual bool PropertyFound { get; protected set; }
|
||||
|
||||
protected MMProperty _targetMMProperty;
|
||||
protected bool _initialized = false;
|
||||
protected MMPropertyLink _propertySetter;
|
||||
|
||||
/// <summary>
|
||||
/// When the property picker gets initialized, it grabs the stored property or field
|
||||
/// and initializes a MMProperty and MMPropertyLink
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public virtual void Initialization(GameObject source)
|
||||
{
|
||||
if ((TargetComponent == null) && (TargetScriptableObject == null))
|
||||
{
|
||||
PropertyFound = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_targetMMProperty = MMProperty.FindProperty(TargetPropertyName, TargetComponent, source, TargetScriptableObject);
|
||||
|
||||
if (_targetMMProperty == null)
|
||||
{
|
||||
PropertyFound = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_targetMMProperty.TargetComponent == null) && (_targetMMProperty.TargetScriptableObject == null))
|
||||
{
|
||||
PropertyFound = false;
|
||||
return;
|
||||
}
|
||||
if ((_targetMMProperty.MemberPropertyInfo == null) && (_targetMMProperty.MemberFieldInfo == null))
|
||||
{
|
||||
PropertyFound = false;
|
||||
return;
|
||||
}
|
||||
PropertyFound = true;
|
||||
_initialized = true;
|
||||
|
||||
// if succession because pattern matching isn't supported before C# 7
|
||||
if (_targetMMProperty.PropertyType == typeof(string))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkString();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(float))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkFloat();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(Vector2))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkVector2();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(Vector3))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkVector3();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(Vector4))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkVector4();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(Quaternion))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkQuaternion();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(int))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkInt();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(bool))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkBool();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
if (_targetMMProperty.PropertyType == typeof(Color))
|
||||
{
|
||||
_propertySetter = new MMPropertyLinkColor();
|
||||
_propertySetter.Initialization(_targetMMProperty);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the raw value of the target property
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual object GetRawValue()
|
||||
{
|
||||
return _propertySetter.GetPropertyValue(_targetMMProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c6f9c86f5c6aa14490ae9a264c1e884
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,113 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to pick a property and modify its value
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MMPropertyReceiver : MMPropertyPicker
|
||||
{
|
||||
/// values will only be modified if this is true
|
||||
public bool ShouldModifyValue = true;
|
||||
|
||||
/// whether or not to add to this property's initial value
|
||||
public bool RelativeValue = true;
|
||||
|
||||
// vectors ----------------------------------------------------------------------------------------------------------------------
|
||||
/// whether or not to modify the X value of this vector
|
||||
public bool ModifyX = true;
|
||||
/// whether or not to modify the Y value of this vector
|
||||
public bool ModifyY = true;
|
||||
/// whether or not to modify the Z value of this vector
|
||||
public bool ModifyZ = true;
|
||||
/// whether or not to modify the W value of this vector
|
||||
public bool ModifyW = true;
|
||||
|
||||
// bool & string ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the threshold after which the float level should make this bool false or true
|
||||
public float Threshold = 0.5f;
|
||||
|
||||
// bool ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the state to remap a float's zero to
|
||||
public bool BoolRemapZero = false;
|
||||
/// the state to remap a float's one to
|
||||
public bool BoolRemapOne = true;
|
||||
|
||||
// string ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the string to remap a float's zero to
|
||||
public string StringRemapZero = "Zero";
|
||||
/// the string to remap a float's zero to
|
||||
public string StringRemapOne = "One";
|
||||
|
||||
// int ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the int value to remap the level's zero to
|
||||
public int IntRemapZero = 0;
|
||||
/// the int value to remap the level's 1 to
|
||||
public int IntRemapOne = 1;
|
||||
|
||||
// float ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the float value to remap the level's 0 to
|
||||
public float FloatRemapZero = 0f;
|
||||
/// the float value to remap the level's 1 to
|
||||
public float FloatRemapOne = 1f;
|
||||
|
||||
// vector2 ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the vector2 value to remap the level's 0 to
|
||||
public Vector2 Vector2RemapZero = Vector2.zero;
|
||||
/// the vector2 value to remap the level's 1 to
|
||||
public Vector2 Vector2RemapOne = Vector2.one;
|
||||
|
||||
// vector3 ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the vector3 value to remap the level's 0 to
|
||||
public Vector3 Vector3RemapZero = Vector3.zero;
|
||||
/// the vector3 value to remap the level's 1 to
|
||||
public Vector3 Vector3RemapOne = Vector3.one;
|
||||
|
||||
// vector4 ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the vector4 value to remap the level's 0 to
|
||||
public Vector4 Vector4RemapZero = Vector4.zero;
|
||||
/// the vector4 value to remap the level's 1 to
|
||||
public Vector4 Vector4RemapOne = Vector4.one;
|
||||
|
||||
// quaternion ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the quaternion value to remap the level's 0 to
|
||||
public Vector3 QuaternionRemapZero = Vector3.zero;
|
||||
/// the quaternion value to remap the level's 1 to
|
||||
public Vector3 QuaternionRemapOne = new Vector3(180f, 180f, 180f);
|
||||
|
||||
// color ----------------------------------------------------------------------------------------------------------------------
|
||||
/// the color value to remap the level's 0 to
|
||||
[ColorUsage(true, true)]
|
||||
public Color ColorRemapZero = Color.white;
|
||||
/// the color value to remap the level's 1 to
|
||||
[ColorUsage(true, true)]
|
||||
public Color ColorRemapOne = Color.black;
|
||||
|
||||
/// the current level
|
||||
public float Level = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level
|
||||
/// </summary>
|
||||
/// <param name="newLevel"></param>
|
||||
public virtual void SetLevel(float newLevel)
|
||||
{
|
||||
if (!PropertyFound)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShouldModifyValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_propertySetter.SetLevel(this, _targetMMProperty, newLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 003f6640c70f0c74085aeba7df48fe55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
105
Assets/Feel/MMTools/Core/MMRadio/MMRadioBroadcaster.cs
Normal file
105
Assets/Feel/MMTools/Core/MMRadio/MMRadioBroadcaster.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to broadcast a level to MMRadioReceiver(s), either directly or via events
|
||||
/// It can read from pretty much any value on any class
|
||||
/// </summary>
|
||||
[MMRequiresConstantRepaint]
|
||||
public class MMRadioBroadcaster : MMMonoBehaviour
|
||||
{
|
||||
[Header("Source")]
|
||||
/// the emitter to read the level on
|
||||
public MMPropertyEmitter Emitter;
|
||||
|
||||
[Header("Destinations")]
|
||||
/// a list of receivers hardwired to this broadcaster, that will receive the level at runtime
|
||||
public MMRadioReceiver[] Receivers;
|
||||
|
||||
[Header("Channel Broadcasting")]
|
||||
/// whether or not this broadcaster should use events to broadcast its level on the specified channel
|
||||
public bool BroadcastOnChannel = true;
|
||||
/// the channel to broadcast on, has to match the Channel on the target receivers
|
||||
[MMCondition("BroadcastOnChannel", true)]
|
||||
public int Channel = 0;
|
||||
/// whether to broadcast all the time, or only when the value changes (lighter on performance, but won't "lock" the value)
|
||||
[MMCondition("BroadcastOnChannel", true)]
|
||||
public bool OnlyBroadcastOnValueChange = true;
|
||||
|
||||
/// a delegate to handle value changes
|
||||
public delegate void OnValueChangeDelegate();
|
||||
/// what to do on value change
|
||||
public OnValueChangeDelegate OnValueChange;
|
||||
|
||||
protected float _levelLastFrame = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake we initialize our emitter
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Emitter.Initialization(this.gameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update we process our broadcast
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
ProcessBroadcast();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts the value if needed
|
||||
/// </summary>
|
||||
protected virtual void ProcessBroadcast()
|
||||
{
|
||||
if (Emitter == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float level = Emitter.GetLevel();
|
||||
|
||||
if (level != _levelLastFrame)
|
||||
{
|
||||
// we trigger a value change event
|
||||
OnValueChange?.Invoke();
|
||||
|
||||
// for each of our receivers, we set the level manually
|
||||
foreach (MMRadioReceiver receiver in Receivers)
|
||||
{
|
||||
receiver?.SetLevel(level);
|
||||
}
|
||||
|
||||
// we broadcast an event
|
||||
if (BroadcastOnChannel)
|
||||
{
|
||||
MMRadioLevelEvent.Trigger(Channel, level);
|
||||
}
|
||||
}
|
||||
|
||||
_levelLastFrame = level;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A struct event used to broadcast the level to channels
|
||||
/// </summary>
|
||||
public struct MMRadioLevelEvent
|
||||
{
|
||||
static private event Delegate OnEvent;
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void RuntimeInitialization() { OnEvent = null; }
|
||||
static public void Register(Delegate callback) { OnEvent += callback; }
|
||||
static public void Unregister(Delegate callback) { OnEvent -= callback; }
|
||||
|
||||
public delegate void Delegate(int channel, float level);
|
||||
static public void Trigger(int channel, float level)
|
||||
{
|
||||
OnEvent?.Invoke(channel, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Feel/MMTools/Core/MMRadio/MMRadioBroadcaster.cs.meta
Normal file
11
Assets/Feel/MMTools/Core/MMRadio/MMRadioBroadcaster.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f655bab42c018140aaf68474d594e6c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
115
Assets/Feel/MMTools/Core/MMRadio/MMRadioReceiver.cs
Normal file
115
Assets/Feel/MMTools/Core/MMRadio/MMRadioReceiver.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to receive level values from a MMRadioBroadcaster, and apply it to (almost) any value on any object
|
||||
/// </summary>
|
||||
[MMRequiresConstantRepaint]
|
||||
public class MMRadioReceiver : MMMonoBehaviour
|
||||
{
|
||||
[Header("Target")]
|
||||
/// the receiver to write the level to
|
||||
public MMPropertyReceiver Receiver;
|
||||
|
||||
[Header("Channel")]
|
||||
/// whether or not this receiver should listen to the channel
|
||||
public bool CanListen = true;
|
||||
/// the Channel to listen to (has to match the one on the MMRadioBroadcaster you're listening to)
|
||||
[MMCondition("CanListen", true)]
|
||||
public int Channel = 0;
|
||||
|
||||
[Header("Modifiers")]
|
||||
/// whether or not to randomize the received level, this will generate at awake a random level multiplier, to apply to the level
|
||||
public bool RandomizeLevel = false;
|
||||
/// if random, the min bound of the random multiplier
|
||||
[MMCondition("RandomizeLevel", true)]
|
||||
public float MinRandomLevelMultiplier = 0f;
|
||||
/// if random, the max bound of the random multiplier
|
||||
[MMCondition("RandomizeLevel", true)]
|
||||
public float MaxRandomLevelMultiplier = 1f;
|
||||
|
||||
protected bool _listeningToEvents = false;
|
||||
protected float _randomLevelMultiplier = 1f;
|
||||
protected float _lastLevel;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake, starts listening and generates a random level multiplier if needed
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Receiver.Initialization(this.gameObject);
|
||||
|
||||
if (!_listeningToEvents && CanListen)
|
||||
{
|
||||
StartListening();
|
||||
}
|
||||
|
||||
GenerateRandomLevelMultiplier();
|
||||
}
|
||||
|
||||
public virtual void GenerateRandomLevelMultiplier()
|
||||
{
|
||||
if (RandomizeLevel)
|
||||
{
|
||||
_randomLevelMultiplier = Random.Range(MinRandomLevelMultiplier, MaxRandomLevelMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the level on the receiver
|
||||
/// </summary>
|
||||
/// <param name="newLevel"></param>
|
||||
public virtual void SetLevel(float newLevel)
|
||||
{
|
||||
Receiver.SetLevel(newLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When getting a radio level event, we make sure it's the right channel, and apply it if needed
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="level"></param>
|
||||
protected virtual void OnRadioLevelEvent(int channel, float level)
|
||||
{
|
||||
if (channel != Channel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (RandomizeLevel)
|
||||
{
|
||||
level *= _randomLevelMultiplier;
|
||||
}
|
||||
SetLevel(level);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops listening to events on destroy
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
_listeningToEvents = false;
|
||||
StopListening();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts listening for events
|
||||
/// </summary>
|
||||
public virtual void StartListening()
|
||||
{
|
||||
_listeningToEvents = true;
|
||||
MMRadioLevelEvent.Register(OnRadioLevelEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops listening for events
|
||||
/// </summary>
|
||||
public virtual void StopListening()
|
||||
{
|
||||
_listeningToEvents = false;
|
||||
MMRadioLevelEvent.Unregister(OnRadioLevelEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Feel/MMTools/Core/MMRadio/MMRadioReceiver.cs.meta
Normal file
11
Assets/Feel/MMTools/Core/MMRadio/MMRadioReceiver.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83dcb4ea8c2204a43adf98a01a3bc0d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Feel/MMTools/Core/MMRadio/MMRadioSignal.meta
Normal file
8
Assets/Feel/MMTools/Core/MMRadio/MMRadioSignal.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2d66563365af5a409fb9fbd56a215d2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
276
Assets/Feel/MMTools/Core/MMRadio/MMRadioSignal/MMRadioSignal.cs
Normal file
276
Assets/Feel/MMTools/Core/MMRadio/MMRadioSignal/MMRadioSignal.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
[System.Serializable]
|
||||
public class MMRadioSignalOnValueChange : UnityEvent<float> { }
|
||||
|
||||
/// <summary>
|
||||
/// A class used to define a signal, meant to be broadcasted by a MMRadioBroadcaster
|
||||
/// It'll output a Level value to broadcast, using one time, persistent or driven modes
|
||||
/// Meant to be extended
|
||||
/// </summary>
|
||||
public abstract class MMRadioSignal : MonoBehaviour
|
||||
{
|
||||
/// the possible modes a radio signal can operate on
|
||||
/// - one time : plays its signal once, goes back to sleep
|
||||
/// - outputs a signal constantly while not sleeping
|
||||
/// - driven : lets you drive the level value from another script
|
||||
public enum SignalModes { OneTime, Persistent, Driven }
|
||||
/// whether this signal operates on scaled or unscaled time
|
||||
public enum TimeScales { Unscaled, Scaled }
|
||||
/// the level, to read from a MMRadioBroadcaster
|
||||
public virtual float Level { get { return CurrentLevel; } }
|
||||
/// the time, unscaled or scaled
|
||||
public virtual float TimescaleTime { get { return (TimeScale == TimeScales.Scaled) ? Time.time : Time.unscaledTime; } }
|
||||
/// the delta time, unscaled or not
|
||||
public virtual float TimescaleDeltaTime { get { return (TimeScale == TimeScales.Scaled) ? Time.deltaTime : Time.unscaledDeltaTime; } }
|
||||
|
||||
[Header("Signal")]
|
||||
/// the selected signal mode
|
||||
public SignalModes SignalMode = SignalModes.Persistent;
|
||||
/// the selected time scale
|
||||
public TimeScales TimeScale = TimeScales.Unscaled;
|
||||
/// the duration of the shake, in seconds
|
||||
public float Duration = 2f;
|
||||
/// a global multiplier to apply to the end result of the combination
|
||||
public float GlobalMultiplier = 1f;
|
||||
/// the current level, not to be read from a broadcaster (it's best to use the property than the field, fields generate garbage)
|
||||
[MMReadOnly]
|
||||
public float CurrentLevel = 0f;
|
||||
|
||||
[Header("Play Settings")]
|
||||
/// whether or not this shaker is shaking right now
|
||||
[MMReadOnly]
|
||||
public bool Playing = false;
|
||||
/// the driver time, that can be controlled from another class if you're in Driven mode
|
||||
[Range(0f, 1f)]
|
||||
public float DriverTime;
|
||||
/// if this is true this shaker will play on awake
|
||||
public bool PlayOnStart = true;
|
||||
/// an event to trigger on value change
|
||||
public MMRadioSignalOnValueChange OnValueChange;
|
||||
|
||||
/// a test button to start shaking
|
||||
[Header(("Debug"))]
|
||||
[MMInspectorButton("StartShaking")]
|
||||
public bool StartShakingButton;
|
||||
|
||||
protected float _signalTime = 0f;
|
||||
protected float _shakeStartedTimestamp;
|
||||
protected float _levelLastFrame;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake we grab our volume and profile
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Initialization();
|
||||
if (PlayOnStart)
|
||||
{
|
||||
StartShaking();
|
||||
}
|
||||
this.enabled = PlayOnStart;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to initialize your shaker
|
||||
/// </summary>
|
||||
protected virtual void Initialization()
|
||||
{
|
||||
CurrentLevel = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts shaking the values
|
||||
/// </summary>
|
||||
public virtual void StartShaking()
|
||||
{
|
||||
if (Playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.enabled = true;
|
||||
_shakeStartedTimestamp = TimescaleTime;
|
||||
Playing = true;
|
||||
ShakeStarts();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes what happens when a shake starts
|
||||
/// </summary>
|
||||
protected virtual void ShakeStarts()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Update, we shake our values if needed, or reset if our shake has ended
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
ProcessUpdate();
|
||||
|
||||
if (SignalMode == SignalModes.Driven)
|
||||
{
|
||||
ProcessDrivenMode();
|
||||
}
|
||||
else if (SignalMode == SignalModes.Persistent)
|
||||
{
|
||||
_signalTime += TimescaleDeltaTime;
|
||||
if (_signalTime > Duration)
|
||||
{
|
||||
_signalTime = 0f;
|
||||
}
|
||||
|
||||
DriverTime = MMMaths.Remap(_signalTime, 0f, Duration, 0f, 1f);
|
||||
}
|
||||
else if (SignalMode == SignalModes.OneTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (Playing || (SignalMode == SignalModes.Driven))
|
||||
{
|
||||
Shake();
|
||||
}
|
||||
|
||||
if ((SignalMode == SignalModes.OneTime) && Playing && (TimescaleTime - _shakeStartedTimestamp > Duration))
|
||||
{
|
||||
ShakeComplete();
|
||||
}
|
||||
|
||||
if (_levelLastFrame != Level)
|
||||
{
|
||||
ApplyLevel(Level);
|
||||
}
|
||||
|
||||
_levelLastFrame = Level;
|
||||
}
|
||||
|
||||
public virtual void ApplyLevel(float level)
|
||||
{
|
||||
if (OnValueChange != null)
|
||||
{
|
||||
OnValueChange.Invoke(level);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method to override to describe the behaviour in Driven mode
|
||||
/// </summary>
|
||||
protected virtual void ProcessDrivenMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method to override to describe what should happen at update
|
||||
/// </summary>
|
||||
protected virtual void ProcessUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override this method to implement shake over time
|
||||
/// </summary>
|
||||
protected virtual void Shake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual float GraphValue(float time)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes what happens when the shake is complete
|
||||
/// </summary>
|
||||
protected virtual void ShakeComplete()
|
||||
{
|
||||
Playing = false;
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On enable we start shaking if needed
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
StartShaking();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On destroy we stop listening for events
|
||||
/// </summary>
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On disable we complete our shake if it was in progress
|
||||
/// </summary>
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
if (Playing)
|
||||
{
|
||||
ShakeComplete();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts this shaker
|
||||
/// </summary>
|
||||
public virtual void Play()
|
||||
{
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts this shaker
|
||||
/// </summary>
|
||||
public virtual void Stop()
|
||||
{
|
||||
ShakeComplete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a bias to a time value
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="bias"></param>
|
||||
/// <returns></returns>
|
||||
public virtual float ApplyBias(float t, float bias)
|
||||
{
|
||||
if (bias == 0.5f)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
bias = MMMaths.Remap(bias, 0f, 1f, 1f, 0f);
|
||||
|
||||
float a = bias * 2.0f - 1.0f;
|
||||
|
||||
if (a < 0)
|
||||
{
|
||||
t = 1 - Mathf.Pow(1.0f - t, Mathf.Max(1 + a, .01f));
|
||||
}
|
||||
else
|
||||
{
|
||||
t = Mathf.Pow(t, Mathf.Max(1 - a, .01f));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a81b3d6b0f5d3d14a8395a2a9611e7a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to expose a beat level from a target MMAudioAnalyzer, to be broadcasted by a MMAudioBroadcaster
|
||||
/// </summary>
|
||||
public class MMRadioSignalAudioAnalyzer : MMRadioSignal
|
||||
{
|
||||
[Header("Audio Analyzer")]
|
||||
/// the MMAudioAnalyzer to read the value on
|
||||
public MMAudioAnalyzer TargetAnalyzer;
|
||||
/// the ID of the beat to listen to
|
||||
public int BeatID;
|
||||
|
||||
/// <summary>
|
||||
/// On Shake, we output our beat value
|
||||
/// </summary>
|
||||
protected override void Shake()
|
||||
{
|
||||
base.Shake();
|
||||
CurrentLevel = TargetAnalyzer.Beats[BeatID].CurrentValue * GlobalMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d566c4f1cefdec64fbce3a07b23976cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,165 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MoreMountains.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to generate signals, normalized values between 0 and 1
|
||||
/// You can then use these values from a MMRadioBroadcaster, or simply evaluate its value to use wherever you want,
|
||||
/// like a supercharged animation curve. In that case, simply disable the component, and read from it using its Evaluate method
|
||||
/// </summary>
|
||||
public class MMRadioSignalGenerator : MMRadioSignal
|
||||
{
|
||||
/// whether or not to display an animated preview
|
||||
public bool AnimatedPreview = false;
|
||||
/// whether this signal should play in back & forth (mirroring the curve around a tipping point)
|
||||
public bool BackAndForth = false;
|
||||
/// the tipping point at which to mirror the curve (between 0 and 1)
|
||||
[MMCondition("BackAndForth", true)]
|
||||
public float BackAndForthMirrorPoint = 0.5f;
|
||||
/// the list of signals to assemble to create the final signal
|
||||
public MMRadioSignalGeneratorItemList SignalList;
|
||||
/// how to clamp the result value
|
||||
[MMVector("Min", "Max")]
|
||||
public Vector2 Clamps = new Vector2(0f, 1f);
|
||||
/// the amplitude of the signal
|
||||
[Range(0f, 1f)]
|
||||
public float Bias = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// On reset, we initialize our list
|
||||
/// </summary>
|
||||
void Reset()
|
||||
{
|
||||
SignalList = new MMRadioSignalGeneratorItemList(){
|
||||
new MMRadioSignalGeneratorItem()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the y value of the generated signal curve, at the x time value specified in parameters
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public virtual float Evaluate(float time)
|
||||
{
|
||||
float level = 1f;
|
||||
if (SignalList.Count <= 0)
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
time = ApplyBias(time, Bias);
|
||||
|
||||
for (int i = 0; i < SignalList.Count; i++)
|
||||
{
|
||||
if (SignalList[i].Active)
|
||||
{
|
||||
float newLevel = MMSignal.GetValueNormalized(time,
|
||||
SignalList[i].SignalType, SignalList[i].Phase,
|
||||
SignalList[i].Amplitude, SignalList[i].Frequency, SignalList[i].Offset,
|
||||
SignalList[i].Invert, SignalList[i].Curve, SignalList[i].TweenCurve,
|
||||
true, Clamps.x, Clamps.y, BackAndForth, BackAndForthMirrorPoint);
|
||||
|
||||
level = (SignalList[i].Mode == MMRadioSignalGeneratorItem.GeneratorItemModes.Multiply) ? level * newLevel : level + newLevel;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
CurrentLevel *= GlobalMultiplier;
|
||||
|
||||
CurrentLevel = Mathf.Clamp(CurrentLevel, Clamps.x, Clamps.y);
|
||||
return level;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On Shake, we shake our level if needed
|
||||
/// </summary>
|
||||
protected override void Shake()
|
||||
{
|
||||
base.Shake();
|
||||
|
||||
if (!Playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SignalMode == SignalModes.OneTime)
|
||||
{
|
||||
float elapsedTime = TimescaleTime - _shakeStartedTimestamp;
|
||||
CurrentLevel = Evaluate(MMMaths.Remap(elapsedTime, 0f, Duration, 0f, 1f));
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLevel = Evaluate(DriverTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Once the shake is complete, we apply our final level
|
||||
/// </summary>
|
||||
protected override void ShakeComplete()
|
||||
{
|
||||
base.ShakeComplete();
|
||||
CurrentLevel = Evaluate(1f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a custom value to display in the graph in inspector
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public override float GraphValue(float time)
|
||||
{
|
||||
time = ApplyBias(time, Bias);
|
||||
return Evaluate(time);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class used to store generator items and their properties
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class MMRadioSignalGeneratorItem
|
||||
{
|
||||
/// whether this individual signal should be multiplied or added to the rest
|
||||
public enum GeneratorItemModes { Multiply, Additive }
|
||||
|
||||
/// whether to take this signal into account in the generator or not
|
||||
public bool Active = true;
|
||||
/// the type of this signal
|
||||
public MMSignal.SignalType SignalType = MMSignal.SignalType.Sine;
|
||||
/// if the type is animation curve, the curve to consider
|
||||
[MMEnumCondition("SignalType", (int)MMSignal.SignalType.AnimationCurve)]
|
||||
public AnimationCurve Curve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
|
||||
/// if the type is MMTween, the tween to consider
|
||||
[MMEnumCondition("SignalType", (int)MMSignal.SignalType.MMTween)]
|
||||
public MMTween.MMTweenCurve TweenCurve = MMTween.MMTweenCurve.EaseInOutQuartic;
|
||||
/// the selected mode (multiply or additive)
|
||||
public GeneratorItemModes Mode = GeneratorItemModes.Multiply;
|
||||
/// the phase of the signal
|
||||
[Range(-1f, 1f)]
|
||||
public float Phase = 0f;
|
||||
/// the frequency of the signal
|
||||
[Range(0f, 10f)]
|
||||
public float Frequency = 5f;
|
||||
/// the amplitude of the signal
|
||||
[Range(0f, 1f)]
|
||||
public float Amplitude = 1f;
|
||||
/// the offset of the signal
|
||||
[Range(-1f, 1f)]
|
||||
public float Offset = 0f;
|
||||
/// whether or not to vertically invert the signal
|
||||
public bool Invert = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A reorderable list type used to store generator items
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class MMRadioSignalGeneratorItemList : MMReorderableArray<MMRadioSignalGeneratorItem>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65443987bd9048f408777b8d8f4c1994
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user