Files
HauntedBloodlines/Assets/FImpossible Creations/Plugins - Shared/Animating Help/MotionInfluenceProcessor.cs
2025-05-29 22:31:40 +03:00

165 lines
6.3 KiB
C#

using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace FIMSpace.FProceduralAnimation
{
[System.Serializable]
public class MotionInfluenceProcessor
{
/// <summary> Using separated influence on each axis when enabled </summary>
public bool AdvancedInfluence = false;
public Vector3 AxisMotionInfluence = Vector3.one;
public Vector3 AxisMotionInfluenceBackwards = Vector3.one;
/// <summary> Can be used to lower blending when character is moving / idling </summary>
private float MultiplyBlend = 1f;
[NonSerialized] public float ExtraBoost = 1f;
private float _sd_mb = 0f;
public void TransitionBlend(float target, float duration, float delta)
{
MultiplyBlend = Mathf.SmoothDamp(MultiplyBlend, target, ref _sd_mb, duration, 10000000f, delta);
}
public void Reset()
{
previousPosition = root.position;
localOffset = Vector3.zero;
rootOffset = Vector3.zero;
}
private Transform root;
public Vector3 OutputInfluenceOffset { get; private set; }
public Vector3 previousPosition { get; private set; }
public Vector3 rootOffset { get; private set; }
public Vector3 localOffset { get; private set; }
public void Init(Transform root)
{
this.root = root;
previousPosition = root.position;
localOffset = Vector3.zero;
}
public void Update()
{
rootOffset = root.position - previousPosition;
previousPosition = root.position;
localOffset = root.InverseTransformVector(rootOffset);
float blend = MultiplyBlend * ExtraBoost;
if (blend != 1f) localOffset *= blend;
Motion_MotionInfluence();
}
public void OverrideOffset(Vector3 offset)
{
rootOffset = offset;
localOffset = root.InverseTransformVector(rootOffset);
Motion_MotionInfluence();
}
private void Motion_MotionInfluence()
{
if (!AdvancedInfluence)
{
if (AxisMotionInfluence != Vector3.one) OutputInfluenceOffset = root.TransformVector(ScaleMotionInfluence(localOffset, AxisMotionInfluence));
}
else OutputInfluenceOffset = root.TransformVector(ScaleMotionInfluence(localOffset, AxisMotionInfluence, AxisMotionInfluenceBackwards));
}
private Vector3 ScaleMotionInfluence(Vector3 toScale, Vector3 influenceMul)
{
return new Vector3(
toScale.x * (1f - influenceMul.x),
toScale.y * (1f - influenceMul.y),
toScale.z * (1f - influenceMul.z));
}
private Vector3 ScaleMotionInfluence(Vector3 toScale, Vector3 influenceMulForw, Vector3 influenceMulBack)
{
if (toScale.x > 0f) toScale.x *= (1f - influenceMulForw.x); else toScale.x *= (1f - influenceMulBack.x);
if (toScale.y > 0f) toScale.y *= (1f - influenceMulForw.y); else toScale.y *= (1f - influenceMulBack.y);
if (toScale.z > 0f) toScale.z *= (1f - influenceMulForw.z); else toScale.z *= (1f - influenceMulBack.z);
return toScale;
}
public Vector3 CalculateInversedInfluence()
{
if (!AdvancedInfluence)
{
if (AxisMotionInfluence != Vector3.one) return root.TransformVector(ScaleMotionInfluenceInverse(localOffset, AxisMotionInfluence));
}
else return root.TransformVector(ScaleMotionInfluenceInverse(localOffset, AxisMotionInfluence, AxisMotionInfluenceBackwards));
return rootOffset;
}
private Vector3 ScaleMotionInfluenceInverse(Vector3 toScale, Vector3 influenceMul)
{
return new Vector3(
toScale.x * (influenceMul.x),
toScale.y * (influenceMul.y),
toScale.z * (influenceMul.z));
}
private Vector3 ScaleMotionInfluenceInverse(Vector3 toScale, Vector3 influenceMulForw, Vector3 influenceMulBack)
{
if (toScale.x > 0f) toScale.x *= (influenceMulForw.x); else toScale.x *= (influenceMulBack.x);
if (toScale.y > 0f) toScale.y *= (influenceMulForw.y); else toScale.y *= (influenceMulBack.y);
if (toScale.z > 0f) toScale.z *= (influenceMulForw.z); else toScale.z *= (influenceMulBack.z);
return toScale;
}
#if UNITY_EDITOR
public static void _EditorDrawGUI(SerializedProperty processor)
{
SerializedProperty motInfl = processor.FindPropertyRelative("AxisMotionInfluence");
SerializedProperty motInflAdv = processor.FindPropertyRelative("AdvancedInfluence");
SerializedProperty backwards = processor.FindPropertyRelative("AxisMotionInfluenceBackwards");
if (motInflAdv.boolValue == false) // Simple motion influence slider
{
float pre = motInfl.vector3Value.x;
Vector3 newVal = motInfl.vector3Value;
EditorGUILayout.BeginHorizontal();
newVal.x = EditorGUILayout.Slider(new GUIContent(motInfl.displayName, motInfl.tooltip), motInfl.vector3Value.x, 0f, 1f); EditorGUIUtility.labelWidth = 4;
EditorGUILayout.PropertyField(motInflAdv, new GUIContent(" ", "Switch to advanced motion influence settings"), GUILayout.Width(24)); EditorGUIUtility.labelWidth = 0;
EditorGUILayout.EndHorizontal();
if (newVal.x != pre)
{
motInfl.vector3Value = Vector3.one * newVal.x;
backwards.vector3Value = motInfl.vector3Value;
}
}
else // Motion influence per axis
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(motInfl); EditorGUIUtility.labelWidth = 4;
EditorGUILayout.PropertyField(motInflAdv, new GUIContent(" ", "Switch to advanced motion influence settings"), GUILayout.Width(24)); EditorGUIUtility.labelWidth = 0;
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(backwards);
}
}
#endif
}
}