Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 208d626100
commit f74c547a13
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5820c9edef53d494881bfde92df4adb7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8fe23ce5bc9554f46aebd960ab58b9eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 556746a88058ca94bbcbd62da24a1f6f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e5da26383e93e941be7bdbcd7b5d940
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d3a1806a84d8016419f53c93976ff64c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1ca607d01430f9419336e2d59ee639b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d260fd7dcadc0284a8d734805d374223
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 991ae4d843392bc4e9ec4e7d8649d94e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2efa1b899c8751046b9617c7268d54f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f6dcec9f2c4bea14baa2582a1bae072a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1dc025857430aa041b4588942e1f27d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ac8f4e19669836447b70ca22e908a10c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c074591fd378046418957bf77882defc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f28b7b1842189d04f8eb2c7093835fc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96afd1836702fcc4297951d56333a9e2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 467c2b48eb6f08b478d8ed7a178f5b55
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7dc665c3421b61d40bd0c4c6eaab763f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c6f9c86f5c6aa14490ae9a264c1e884
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 003f6640c70f0c74085aeba7df48fe55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f655bab42c018140aaf68474d594e6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83dcb4ea8c2204a43adf98a01a3bc0d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b2d66563365af5a409fb9fbd56a215d2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a81b3d6b0f5d3d14a8395a2a9611e7a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d566c4f1cefdec64fbce3a07b23976cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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>
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 65443987bd9048f408777b8d8f4c1994
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: