浏览代码
Generic Animation Rigs (#53)
Generic Animation Rigs (#53)
* Base Commit (Float Animation) // TODO : Genericize Animation * Added Animation Handlers * Added More Float Helpers * Added Vector3AnimationHandlers * Added Generic Binding Rig * Added ColorAnimationHandlers + Added More types to Generic Binding Rig * Updated Changelog * Fix Garbage/main
GitHub
4 年前
当前提交
4f250950
共有 38 个文件被更改,包括 1218 次插入 和 1 次删除
-
1CHANGELOG.md
-
2Runtime/Ingredients/Rigs/RigManager.cs
-
11Editor/PropertyDrawers/ReflectedMemberyPropertyDrawer.cs.meta
-
106Editor/PropertyDrawers/AnimationHandlerPropertyDrawer.cs
-
11Editor/PropertyDrawers/AnimationHandlerPropertyDrawer.cs.meta
-
189Editor/PropertyDrawers/ReflectedMemberyPropertyDrawer.cs
-
8Runtime/Ingredients/Rigs/GenericAnimation.meta
-
8Runtime/ReflectedMember.meta
-
31Runtime/Ingredients/Rigs/GenericAnimation/GenericAnimationRig.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/GenericAnimationRig.cs.meta
-
49Runtime/Ingredients/Rigs/GenericAnimation/GenericFloatAnimationRig.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/GenericFloatAnimationRig.cs.meta
-
8Runtime/Ingredients/Rigs/GenericAnimation/Handlers.meta
-
48Runtime/Ingredients/Rigs/GenericAnimation/GenericVector3AnimationRig.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/GenericVector3AnimationRig.cs.meta
-
11Runtime/Ingredients/Rigs/GenericAnimation/GenericBindingRig.cs.meta
-
73Runtime/Ingredients/Rigs/GenericAnimation/GenericBindingRig.cs
-
48Runtime/Ingredients/Rigs/GenericAnimation/GenericColorAnimationRig.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/GenericColorAnimationRig.cs.meta
-
19Runtime/Ingredients/Rigs/GenericAnimation/Handlers/AnimationHandler.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/AnimationHandler.cs.meta
-
19Runtime/Ingredients/Rigs/GenericAnimation/Handlers/AnimationHandlerAttribute.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/AnimationHandlerAttribute.cs.meta
-
134Runtime/Ingredients/Rigs/GenericAnimation/Handlers/FloatAnimationHandler.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/FloatAnimationHandler.cs.meta
-
15Runtime/Ingredients/Rigs/GenericAnimation/Handlers/HandlerTypeAttribute.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/HandlerTypeAttribute.cs.meta
-
151Runtime/Ingredients/Rigs/GenericAnimation/Handlers/Vector3AnimationHandler.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/Vector3AnimationHandler.cs.meta
-
51Runtime/Ingredients/Rigs/GenericAnimation/Handlers/ColorAnimationHandler.cs
-
11Runtime/Ingredients/Rigs/GenericAnimation/Handlers/ColorAnimationHandler.cs.meta
-
80Runtime/ReflectedMember/ReflectedMember.cs
-
11Runtime/ReflectedMember/ReflectedMember.cs.meta
-
14Runtime/ReflectedMember/ReflectedMemberAttribute.cs
-
11Runtime/ReflectedMember/ReflectedMemberAttribute.cs.meta
|
|||
fileFormatVersion: 2 |
|||
guid: 101539721cd4dbd4092347cc4f9a1714 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using GameplayIngredients.Rigs; |
|||
using System.Reflection; |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
namespace GameplayIngredients.Editor |
|||
{ |
|||
[CustomPropertyDrawer(typeof(AnimationHandler), true)] |
|||
public class AnimationHandlerPropertyDrawer : PropertyDrawer |
|||
{ |
|||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) |
|||
{ |
|||
return EditorGUI.GetPropertyHeight(property, label, true) + 8; |
|||
} |
|||
|
|||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) |
|||
{ |
|||
var targetObj = property.serializedObject.targetObject; |
|||
MemberInfo selfInfo = targetObj.GetType().GetMember(property.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField).First(); |
|||
|
|||
if (typeToAdd != null) |
|||
{ |
|||
if (selfInfo.MemberType == MemberTypes.Property) |
|||
{ |
|||
Undo.RecordObject(targetObj, "Change Animation Handler"); |
|||
(selfInfo as PropertyInfo).SetValue(targetObj, Activator.CreateInstance(typeToAdd)); |
|||
typeToAdd = null; |
|||
} |
|||
else if (selfInfo.MemberType == MemberTypes.Field) |
|||
{ |
|||
Undo.RecordObject(targetObj, "Change Animation Handler"); |
|||
(selfInfo as FieldInfo).SetValue(targetObj, Activator.CreateInstance(typeToAdd)); |
|||
typeToAdd = null; |
|||
} |
|||
else |
|||
throw new Exception($"Could not find field/property of name {property.name} on object {targetObj.name}"); |
|||
} |
|||
else |
|||
{ |
|||
GUI.Box(position, GUIContent.none, EditorStyles.helpBox); |
|||
|
|||
position = new RectOffset(4, 4, 4, 4).Remove(position); |
|||
|
|||
using (new EditorGUI.IndentLevelScope(1)) |
|||
{ |
|||
Rect r = position; |
|||
r.xMin += EditorGUIUtility.labelWidth; |
|||
r.height = EditorGUIUtility.singleLineHeight; |
|||
|
|||
var p = property.serializedObject.targetObject.GetType().GetMember(property.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField).First(); |
|||
var attr = p.GetCustomAttribute<HandlerTypeAttribute>(); |
|||
if (attr != null) |
|||
{ |
|||
var type = attr.type; |
|||
Type curType = typeof(object); |
|||
if (selfInfo.MemberType == MemberTypes.Property) |
|||
curType = (selfInfo as PropertyInfo).GetValue(targetObj).GetType(); |
|||
else if (selfInfo.MemberType == MemberTypes.Field) |
|||
curType = (selfInfo as FieldInfo).GetValue(targetObj).GetType(); |
|||
|
|||
string name = curType.Name; |
|||
var typeAttr = curType.GetCustomAttribute<AnimationHandlerAttribute>(); |
|||
if (typeAttr != null) |
|||
name = typeAttr.menuPath; |
|||
|
|||
if (EditorGUI.DropdownButton(r, new GUIContent(name), FocusType.Passive)) |
|||
{ |
|||
PromptMenuFor(r, type, curType); |
|||
} |
|||
|
|||
} |
|||
else |
|||
{ |
|||
using (new EditorGUI.DisabledGroupScope(true)) |
|||
EditorGUI.DropdownButton(r, new GUIContent("(Property does not implement [HandlerType] attribute)"), FocusType.Passive); |
|||
} |
|||
|
|||
|
|||
EditorGUI.PropertyField(position, property, true); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Type typeToAdd = null; |
|||
|
|||
void PromptMenuFor(Rect position, Type filterType, Type currentType) |
|||
{ |
|||
var allHandlers = TypeUtility.GetConcreteTypes<AnimationHandler>(); |
|||
GenericMenu m = new GenericMenu(); |
|||
foreach(var handlerType in allHandlers) |
|||
{ |
|||
var attr = handlerType.GetCustomAttribute<AnimationHandlerAttribute>(); |
|||
if (attr != null && attr.type == filterType) |
|||
{ |
|||
m.AddItem(new GUIContent(attr.menuPath), handlerType == currentType, () => { typeToAdd = handlerType; }); |
|||
} |
|||
} |
|||
m.DropDown(position); |
|||
} |
|||
} |
|||
|
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b9dae9fe60237924199a1ede12aab6a8 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using System.Reflection; |
|||
using System.Linq; |
|||
|
|||
namespace GameplayIngredients.Editor |
|||
{ |
|||
[CustomPropertyDrawer(typeof(ReflectedMember))] |
|||
public class ReflectedMemberyPropertyDrawer : PropertyDrawer |
|||
{ |
|||
Dictionary<(Object, System.Type), string[]> cachedMemberNames; |
|||
|
|||
GenericMenu nullMenu; |
|||
|
|||
void CacheMembersForObject(Object obj, System.Type filterType) |
|||
{ |
|||
if (obj == null) |
|||
return; |
|||
|
|||
if (cachedMemberNames == null) |
|||
cachedMemberNames = new Dictionary<(Object, System.Type), string[]>(); |
|||
|
|||
if (!cachedMemberNames.ContainsKey((obj, filterType))) |
|||
{ |
|||
List<string> names = new List<string>(); |
|||
foreach (var p in obj.GetType().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.SetField)) |
|||
{ |
|||
if (p.MemberType == MemberTypes.Field && filterType.IsAssignableFrom((p as FieldInfo).FieldType)) |
|||
names.Add(p.Name); |
|||
else if (p.MemberType == MemberTypes.Property && filterType.IsAssignableFrom((p as PropertyInfo).PropertyType)) |
|||
names.Add(p.Name); |
|||
} |
|||
cachedMemberNames.Add((obj, filterType), names.ToArray()); |
|||
} |
|||
} |
|||
|
|||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) |
|||
{ |
|||
return EditorGUIUtility.singleLineHeight + 8; |
|||
} |
|||
|
|||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) |
|||
{ |
|||
GUI.Box(position, GUIContent.none, EditorStyles.helpBox); |
|||
|
|||
position = new RectOffset(4, 4, 4, 4).Remove(position); |
|||
|
|||
SerializedProperty obj = property.FindPropertyRelative("m_TargetObject"); |
|||
SerializedProperty propName = property.FindPropertyRelative("m_MemberName"); |
|||
|
|||
float width = EditorGUIUtility.currentViewWidth; |
|||
|
|||
var filterType = typeof(object); |
|||
var p = property.serializedObject.targetObject.GetType().GetMember(property.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField | BindingFlags.FlattenHierarchy).First(); |
|||
var attr = p.GetCustomAttribute<ReflectedMemberAttribute>(); |
|||
|
|||
if (attr != null) // If using a ReflectedMemberAttribute for filtering type
|
|||
{ |
|||
var typeMember = property.serializedObject.targetObject.GetType().GetMember(attr.typeMemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField).First(); |
|||
if (typeMember.DeclaringType is System.Type) |
|||
{ |
|||
|
|||
if (typeMember is PropertyInfo) |
|||
filterType = (typeMember as PropertyInfo).GetValue(property.serializedObject.targetObject) as System.Type; |
|||
else if (typeMember is FieldInfo) |
|||
filterType = (typeMember as FieldInfo).GetValue(property.serializedObject.targetObject) as System.Type; |
|||
} |
|||
} |
|||
|
|||
Rect objRect = position; |
|||
Rect btnRect = position; |
|||
Rect propRect = position; |
|||
|
|||
objRect.xMax = (width / 3) - 4; |
|||
btnRect.xMin = (width / 3); |
|||
btnRect.xMax = (2 * width / 3); |
|||
propRect.xMin = (2 * width / 3); |
|||
|
|||
EditorGUI.ObjectField(objRect, obj, GUIContent.none); |
|||
|
|||
var tgt = obj.objectReferenceValue; |
|||
|
|||
if (tgt == null || !(tgt is GameObject || tgt is Component)) |
|||
{ |
|||
if (EditorGUI.DropdownButton(btnRect, GUIContent.none, FocusType.Passive)) |
|||
{ |
|||
if (nullMenu == null) |
|||
{ |
|||
nullMenu = new GenericMenu(); |
|||
nullMenu.AddDisabledItem(new GUIContent("No Game Object or Component Selected"), false); |
|||
} |
|||
|
|||
nullMenu.DropDown(btnRect); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
Component[] comps = null; |
|||
int sel = -1; |
|||
if (tgt is GameObject) |
|||
{ |
|||
sel = 0; |
|||
comps = (tgt as GameObject).GetComponents(typeof(Component)); |
|||
} |
|||
else if (tgt is Component) |
|||
{ |
|||
|
|||
comps = (tgt as Component).GetComponents(typeof(Component)); |
|||
} |
|||
|
|||
List<string> names = new List<string>(); |
|||
names.Add("Game Object"); |
|||
|
|||
int i = 1; |
|||
foreach (var comp in comps) |
|||
{ |
|||
if (comp is Callable) |
|||
names.Add($"{comp.GetType().Name} ({(comp as Callable).Name})"); |
|||
else |
|||
names.Add(comp.GetType().Name); |
|||
|
|||
if (tgt == comp) |
|||
sel = i; |
|||
i++; |
|||
} |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
|
|||
int newSel = EditorGUI.Popup(btnRect, sel, names.ToArray()); |
|||
|
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
if (newSel == 0) |
|||
{ |
|||
if (tgt is GameObject) |
|||
obj.objectReferenceValue = (tgt as GameObject); |
|||
else if (tgt is Component) |
|||
obj.objectReferenceValue = (tgt as Component).gameObject; |
|||
} |
|||
else |
|||
obj.objectReferenceValue = comps[newSel - 1]; |
|||
|
|||
propName.stringValue = string.Empty; |
|||
} |
|||
|
|||
} |
|||
|
|||
if (obj.objectReferenceValue != null) |
|||
{ |
|||
CacheMembersForObject(obj.objectReferenceValue, filterType); |
|||
int propIdx = -1; |
|||
int i = 0; |
|||
if (!string.IsNullOrEmpty(propName.stringValue)) |
|||
foreach (var name in cachedMemberNames[(obj.objectReferenceValue, filterType)]) |
|||
{ |
|||
if (propName.stringValue == name) |
|||
propIdx = i; |
|||
i++; |
|||
} |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
|
|||
int newPropIdx = EditorGUI.Popup(propRect, propIdx, cachedMemberNames[(obj.objectReferenceValue, filterType)]); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
propName.stringValue = cachedMemberNames[(obj.objectReferenceValue, filterType)][newPropIdx]; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
using (new EditorGUI.DisabledGroupScope(true)) |
|||
{ |
|||
EditorGUI.DropdownButton(propRect, new GUIContent("(Please Select an object first)"), FocusType.Passive); |
|||
} |
|||
} |
|||
|
|||
// Validate data
|
|||
if (obj.objectReferenceValue != null) |
|||
{ |
|||
if (!(obj.objectReferenceValue is GameObject || obj.objectReferenceValue is Component)) // Invalid Component Type
|
|||
{ |
|||
obj.objectReferenceValue = null; |
|||
propName.stringValue = string.Empty; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2cdfdb3fcc6b5f64eb2254610fcc2891 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 7b4741ea51c1b4646974c0957033625f |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
|
|||
public abstract class GenericAnimationRig : Rig |
|||
{ |
|||
public override UpdateMode defaultUpdateMode => UpdateMode.Update; |
|||
|
|||
public override int defaultPriority => 0; |
|||
|
|||
public override bool canChangeUpdateMode => true; |
|||
|
|||
public abstract Type animatedType { get; } |
|||
|
|||
[Header("Target Property / Field"), ReflectedMember("animatedType")] |
|||
public ReflectedMember property; |
|||
|
|||
public override void UpdateRig(float deltaTime) |
|||
{ |
|||
if (property.targetObject != null) |
|||
{ |
|||
property.SetValue(UpdateAndGetValue(deltaTime)); |
|||
} |
|||
} |
|||
|
|||
protected abstract object UpdateAndGetValue(float deltaTime); |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6f6acdc002a4fea4a85a07db8133241e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using NaughtyAttributes; |
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
public class GenericFloatAnimationRig : GenericAnimationRig |
|||
{ |
|||
[Header("Base Value")] |
|||
[SerializeField] |
|||
bool useStoredValueAsBase = true; |
|||
[SerializeField, DisableIf("useStoredValueAsBase")] |
|||
float baseValue = 1.0f; |
|||
|
|||
[Header("Animation")] |
|||
[SerializeReference, HandlerType(typeof(float))] |
|||
public FloatAnimationHandler animationHandler = new FloatContinuousAnimationHandler(); |
|||
|
|||
|
|||
public override Type animatedType => typeof(float); |
|||
|
|||
private void Awake() |
|||
{ |
|||
if (useStoredValueAsBase) |
|||
baseValue = (float)property.GetValue(); |
|||
} |
|||
|
|||
protected override void OnEnable() |
|||
{ |
|||
base.OnEnable(); |
|||
animationHandler?.OnStart(baseValue); |
|||
} |
|||
|
|||
protected override object UpdateAndGetValue(float deltaTime) |
|||
{ |
|||
if (animationHandler != null) |
|||
{ |
|||
return animationHandler.OnUpdate(deltaTime); |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogWarning("Float Animation Rig has no Animation Handler", this); |
|||
return baseValue; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: 3d5a84f07865f0244beebd46a1ae8c1e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 39f767ee22f05fa40ba6e9376674e2da |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using NaughtyAttributes; |
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
public class GenericVector3AnimationRig : GenericAnimationRig |
|||
{ |
|||
[Header("Base Value")] |
|||
[SerializeField] |
|||
bool useStoredValueAsBase = true; |
|||
[SerializeField, DisableIf("useStoredValueAsBase")] |
|||
Vector3 baseValue = Vector3.one; |
|||
|
|||
[Header("Animation")] |
|||
[SerializeReference, HandlerType(typeof(Vector3))] |
|||
public Vector3AnimationHandler animationHandler = new Vector3ContinuousAnimationHandler(); |
|||
|
|||
public override Type animatedType => typeof(Vector3); |
|||
|
|||
private void Awake() |
|||
{ |
|||
if (useStoredValueAsBase) |
|||
baseValue = (Vector3)property.GetValue(); |
|||
} |
|||
|
|||
protected override void OnEnable() |
|||
{ |
|||
base.OnEnable(); |
|||
animationHandler?.OnStart(baseValue); |
|||
} |
|||
|
|||
protected override object UpdateAndGetValue(float deltaTime) |
|||
{ |
|||
if (animationHandler != null) |
|||
{ |
|||
return animationHandler.OnUpdate(deltaTime); |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogWarning("Float Animation Rig has no Animation Handler", this); |
|||
return baseValue; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: 9fe67c04a8c58ff48a5f05998a7051ce |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: d544ada91e4229b4aa7b7d1f01f7110d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using NaughtyAttributes; |
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
|
|||
public class GenericBindingRig : Rig |
|||
{ |
|||
public enum BindingType |
|||
{ |
|||
Bool, |
|||
Int, |
|||
UInt, |
|||
Float, |
|||
Vector2, |
|||
Vector3, |
|||
Vector4, |
|||
Quaternion, |
|||
Color |
|||
} |
|||
[SerializeField] |
|||
BindingType bindingType = BindingType.Float; |
|||
|
|||
[InfoBox("Reads the value of SOURCE property and stores it into TARGET property")] |
|||
|
|||
[SerializeField, ReflectedMember("typeForBinding")] |
|||
ReflectedMember source; |
|||
[SerializeField, ReflectedMember("typeForBinding")] |
|||
ReflectedMember target; |
|||
|
|||
Type typeForBinding |
|||
{ |
|||
get |
|||
{ |
|||
switch (bindingType) |
|||
{ |
|||
case BindingType.Bool: |
|||
return typeof(bool); |
|||
case BindingType.Int: |
|||
return typeof(int); |
|||
case BindingType.UInt: |
|||
return typeof(uint); |
|||
case BindingType.Float: |
|||
return typeof(float); |
|||
case BindingType.Vector2: |
|||
return typeof(Vector2); |
|||
case BindingType.Vector3: |
|||
return typeof(Vector3); |
|||
case BindingType.Vector4: |
|||
return typeof(Vector4); |
|||
case BindingType.Quaternion: |
|||
return typeof(Quaternion); |
|||
case BindingType.Color: |
|||
return typeof(Color); |
|||
default: |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override UpdateMode defaultUpdateMode => UpdateMode.Update; |
|||
|
|||
public override int defaultPriority => 0; |
|||
|
|||
public override void UpdateRig(float deltaTime) |
|||
{ |
|||
target.SetValue(source.GetValue()); |
|||
} |
|||
} |
|||
} |
|||
|
|
|||
using NaughtyAttributes; |
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
public class GenericColorAnimationRig : GenericAnimationRig |
|||
{ |
|||
[Header("Base Value")] |
|||
[SerializeField] |
|||
bool useStoredValueAsBase = true; |
|||
[SerializeField, DisableIf("useStoredValueAsBase")] |
|||
Color baseValue = Color.white; |
|||
|
|||
[Header("Animation")] |
|||
[SerializeReference, HandlerType(typeof(Color))] |
|||
public ColorAnimationHandler animationHandler = new ColorGradientAnimationHandler(); |
|||
|
|||
public override Type animatedType => typeof(Color); |
|||
|
|||
private void Awake() |
|||
{ |
|||
if (useStoredValueAsBase) |
|||
baseValue = (Color)property.GetValue(); |
|||
} |
|||
|
|||
protected override void OnEnable() |
|||
{ |
|||
base.OnEnable(); |
|||
animationHandler?.OnStart(baseValue); |
|||
} |
|||
|
|||
protected override object UpdateAndGetValue(float deltaTime) |
|||
{ |
|||
if (animationHandler != null) |
|||
{ |
|||
return animationHandler.OnUpdate(deltaTime); |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogWarning("Float Animation Rig has no Animation Handler", this); |
|||
return baseValue; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: da33a542fba967a4cbd12450bb0b12da |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
public abstract class AnimationHandler<T> : AnimationHandler |
|||
{ |
|||
public sealed override Type animatedType => typeof(T); |
|||
|
|||
public abstract void OnStart(T defaultValue); |
|||
|
|||
public abstract T OnUpdate(float deltaTime); |
|||
} |
|||
|
|||
public abstract class AnimationHandler |
|||
{ |
|||
public abstract Type animatedType { get; } |
|||
} |
|||
|
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: bab759fa7ad0bf84a858be6d7d08d364 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Class)] |
|||
public class AnimationHandlerAttribute : Attribute |
|||
{ |
|||
public string menuPath; |
|||
public Type type; |
|||
|
|||
public AnimationHandlerAttribute(string menuPath, Type type) |
|||
{ |
|||
this.type = type; |
|||
this.menuPath = menuPath; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: 27f72e7c25503e54c931c85ecf203e2e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
[Serializable] |
|||
public abstract class FloatAnimationHandler : AnimationHandler<float> { } |
|||
|
|||
[Serializable, AnimationHandler("Float Continuous", typeof(float))] |
|||
public class FloatContinuousAnimationHandler : FloatAnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
float Rate = 1.0f; |
|||
|
|||
float m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(float defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override float OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + m_Time * Rate; |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Float Sine Wave", typeof(float))] |
|||
public class FloatSineAnimationHandler : FloatAnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
float frequency = 1.0f; |
|||
[SerializeField] |
|||
public float amplitude = 1.0f; |
|||
|
|||
float m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(float defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override float OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + Mathf.Sin(m_Time * frequency * Mathf.PI) * amplitude; |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Float Noise", typeof(float))] |
|||
public class FloatNoiseAnimationHandler : FloatAnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
float frequency = 1.0f; |
|||
[SerializeField] |
|||
float amplitude = 1.0f; |
|||
[SerializeField, Range(0f, 5f)] |
|||
float lacunarity = 0.3f; |
|||
[SerializeField, Range(1,5)] |
|||
int octaves = 1; |
|||
[SerializeField] |
|||
int seed = -1485472; |
|||
|
|||
float m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(float defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override float OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + GetRandom(); |
|||
} |
|||
|
|||
float GetRandom() |
|||
{ |
|||
float v = 0; |
|||
for(int i = 0; i < octaves; i++) |
|||
{ |
|||
v += (Mathf.PerlinNoise(seed, m_Time * frequency * ((i+1) * 1.7153f)) - .5f) * (amplitude / (i * lacunarity + 1)); |
|||
} |
|||
return v; |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Float Curve", typeof(float))] |
|||
public class FloatCurveAnimationHandler : FloatAnimationHandler |
|||
{ |
|||
static AnimationCurve defaultCurve { |
|||
get |
|||
{ |
|||
var c = new AnimationCurve( |
|||
new Keyframe[] { |
|||
new Keyframe(0,0, 0, 4f), |
|||
new Keyframe(0.25f,1), |
|||
new Keyframe(0.75f,-1), |
|||
new Keyframe(1,0, 4f, 0) |
|||
}); |
|||
c.preWrapMode = WrapMode.Loop; |
|||
c.postWrapMode = WrapMode.Loop; |
|||
return c; |
|||
} |
|||
} |
|||
|
|||
[SerializeField] |
|||
AnimationCurve curve = defaultCurve; |
|||
[SerializeField] |
|||
float amplitude = 1.0f; |
|||
|
|||
float m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(float defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override float OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + curve.Evaluate(m_Time) * amplitude; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f4df285f285c57f479a58a7d5c99c4fc |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
public class HandlerTypeAttribute : PropertyAttribute |
|||
{ |
|||
public Type type; |
|||
public HandlerTypeAttribute(Type type) |
|||
{ |
|||
this.type = type; |
|||
} |
|||
} |
|||
} |
|||
|
|
|||
fileFormatVersion: 2 |
|||
guid: a7e904f72ff82344e80c1413c3f14d29 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
[Serializable] |
|||
public abstract class Vector3AnimationHandler : AnimationHandler<Vector3> { } |
|||
|
|||
[Serializable, AnimationHandler("Vector3 Continuous", typeof(Vector3))] |
|||
public class Vector3ContinuousAnimationHandler : Vector3AnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
Vector3 Rate = Vector3.one; |
|||
|
|||
Vector3 m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(Vector3 defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override Vector3 OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + m_Time * Rate; |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Vector3 Sine Wave", typeof(Vector3))] |
|||
public class Vector3SineAnimationHandler : Vector3AnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
Vector3 frequency = Vector3.one; |
|||
[SerializeField] |
|||
Vector3 amplitude = Vector3.one; |
|||
|
|||
Vector3 m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(Vector3 defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override Vector3 OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + new Vector3( |
|||
Mathf.Sin(m_Time * frequency.x * Mathf.PI) * amplitude.x, |
|||
Mathf.Sin(m_Time * frequency.y * Mathf.PI) * amplitude.y, |
|||
Mathf.Sin(m_Time * frequency.z * Mathf.PI) * amplitude.z |
|||
); |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Vector3 Noise", typeof(Vector3))] |
|||
public class Vector3NoiseAnimationHandler : Vector3AnimationHandler |
|||
{ |
|||
[SerializeField] |
|||
Vector3 frequency = Vector3.one; |
|||
[SerializeField] |
|||
Vector3 amplitude = Vector3.one; |
|||
[SerializeField, Range(0f, 5f)] |
|||
float lacunarity = 0.3f; |
|||
[SerializeField, Range(1,5)] |
|||
int octaves = 1; |
|||
[SerializeField] |
|||
int seed = -1485472; |
|||
|
|||
Vector3 m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(Vector3 defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override Vector3 OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + GetRandom(); |
|||
} |
|||
|
|||
Vector3 GetRandom() |
|||
{ |
|||
Vector3 v = Vector3.zero; |
|||
for(int i = 0; i < octaves; i++) |
|||
{ |
|||
v += new Vector3( |
|||
(Mathf.PerlinNoise(seed, m_Time * frequency.x * ((i+1) * 1.7153f)) - .5f) * (amplitude.x / (i * lacunarity + 1)), |
|||
(Mathf.PerlinNoise(seed, m_Time * frequency.y * ((i+1) * 1.7153f)) - .5f) * (amplitude.y / (i * lacunarity + 1)), |
|||
(Mathf.PerlinNoise(seed, m_Time * frequency.z * ((i+1) * 1.7153f)) - .5f) * (amplitude.z / (i * lacunarity + 1)) |
|||
); |
|||
} |
|||
return v; |
|||
} |
|||
} |
|||
|
|||
[Serializable, AnimationHandler("Vector3 Curve", typeof(Vector3))] |
|||
public class Vector3CurveAnimationHandler : Vector3AnimationHandler |
|||
{ |
|||
static AnimationCurve defaultCurve { |
|||
get |
|||
{ |
|||
var c = new AnimationCurve( |
|||
new Keyframe[] { |
|||
new Keyframe(0,0, 0, 4f), |
|||
new Keyframe(0.25f,1), |
|||
new Keyframe(0.75f,-1), |
|||
new Keyframe(1,0, 4f, 0) |
|||
}); |
|||
c.preWrapMode = WrapMode.Loop; |
|||
c.postWrapMode = WrapMode.Loop; |
|||
return c; |
|||
} |
|||
} |
|||
|
|||
[SerializeField] |
|||
AnimationCurve curveX = defaultCurve; |
|||
[SerializeField] |
|||
AnimationCurve curveY = defaultCurve; |
|||
[SerializeField] |
|||
AnimationCurve curveZ = defaultCurve; |
|||
|
|||
[SerializeField] |
|||
Vector3 amplitude = Vector3.one; |
|||
|
|||
Vector3 m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(Vector3 defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override Vector3 OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return m_Base + new Vector3 ( |
|||
curveX.Evaluate(m_Time) * amplitude.x, |
|||
curveY.Evaluate(m_Time) * amplitude.y, |
|||
curveZ.Evaluate(m_Time) * amplitude.z |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 62f74223d6b5aae4ba44b76bc1c18a6b |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients.Rigs |
|||
{ |
|||
[Serializable] |
|||
public abstract class ColorAnimationHandler : AnimationHandler<Color> { } |
|||
|
|||
[Serializable, AnimationHandler("Color Gradient", typeof(Color))] |
|||
public class ColorGradientAnimationHandler : ColorAnimationHandler |
|||
{ |
|||
static Gradient defaultGradient { |
|||
get |
|||
{ |
|||
var c = new Gradient(); |
|||
c.SetKeys(new GradientColorKey[] |
|||
{ |
|||
new GradientColorKey(Color.red, .0f), |
|||
new GradientColorKey(Color.yellow, .16666f), |
|||
new GradientColorKey(Color.green, .33333f), |
|||
new GradientColorKey(Color.cyan, .5f), |
|||
new GradientColorKey(Color.blue, .6666666f), |
|||
new GradientColorKey(Color.magenta, .833333f), |
|||
new GradientColorKey(Color.red, .1f) |
|||
}, |
|||
new GradientAlphaKey[] { new GradientAlphaKey(1, 0), new GradientAlphaKey(1, 1) }); |
|||
return c; |
|||
} |
|||
} |
|||
|
|||
[SerializeField] |
|||
Gradient gradient = defaultGradient; |
|||
[SerializeField] |
|||
float blendSourceColor = 0f; |
|||
|
|||
Color m_Base; |
|||
float m_Time; |
|||
|
|||
public override void OnStart(Color defaultValue) |
|||
{ |
|||
m_Base = defaultValue; |
|||
m_Time = 0; |
|||
} |
|||
|
|||
public override Color OnUpdate(float deltaTime) |
|||
{ |
|||
m_Time += deltaTime; |
|||
return Color.Lerp(gradient.Evaluate(m_Time), m_Base, blendSourceColor); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 623206cf60ca5ac44a99bceeda298282 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients |
|||
{ |
|||
|
|||
[Serializable] |
|||
public struct ReflectedMember |
|||
{ |
|||
public UnityEngine.Object targetObject { get => m_TargetObject; } |
|||
public MemberInfo member { get { UpdateMember(); return m_Member; } } |
|||
|
|||
[SerializeField] |
|||
UnityEngine.Object m_TargetObject; |
|||
|
|||
[SerializeField] |
|||
string m_MemberName; |
|||
|
|||
[SerializeField] |
|||
MemberInfo m_Member; |
|||
|
|||
public void SetMember(UnityEngine.Object obj, string memberName) |
|||
{ |
|||
m_TargetObject = obj; |
|||
m_MemberName = memberName; |
|||
UpdateMember(); |
|||
} |
|||
|
|||
public void SetValue(object value) |
|||
{ |
|||
if (m_TargetObject != null) |
|||
{ |
|||
if (m_Member == null) |
|||
UpdateMember(); |
|||
|
|||
if (m_Member.MemberType == MemberTypes.Field) |
|||
(m_Member as FieldInfo).SetValue(m_TargetObject, value); |
|||
else if (m_Member.MemberType == MemberTypes.Property) |
|||
(m_Member as PropertyInfo).SetValue(m_TargetObject, value); |
|||
else |
|||
throw new Exception($"Could not Set value of member {m_Member.Name} which is a {m_Member.MemberType}"); |
|||
} |
|||
else |
|||
throw new Exception($"Could not Find member '{m_MemberName}' of target object {m_TargetObject}"); |
|||
} |
|||
|
|||
public T GetValue<T>() |
|||
{ |
|||
return (T)GetValue(); |
|||
} |
|||
|
|||
public object GetValue() |
|||
{ |
|||
if (m_TargetObject != null) |
|||
{ |
|||
if (m_Member == null) |
|||
UpdateMember(); |
|||
|
|||
if (m_Member.MemberType == MemberTypes.Field) |
|||
return (m_Member as FieldInfo).GetValue(m_TargetObject); |
|||
else if (m_Member.MemberType == MemberTypes.Property) |
|||
return (m_Member as PropertyInfo).GetValue(m_TargetObject); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public void UpdateMember() |
|||
{ |
|||
if (m_TargetObject == null) |
|||
return; |
|||
|
|||
m_Member = m_TargetObject.GetType().GetMember(m_MemberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.SetField).First(); |
|||
|
|||
if (m_Member == null) |
|||
Debug.LogWarning($"Could not find member of name {m_MemberName} on type {m_TargetObject.GetType().Name}"); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c6d25824103303749a64c4f3026ffe33 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients |
|||
{ |
|||
public class ReflectedMemberAttribute : PropertyAttribute |
|||
{ |
|||
public string typeMemberName; |
|||
|
|||
public ReflectedMemberAttribute(string typeMemberName) |
|||
{ |
|||
this.typeMemberName = typeMemberName; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b835f96fcf72cb8449ff1447a1f36812 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue