Initial Commit
This commit is contained in:
commit
ee5c2f922d
2255 changed files with 547750 additions and 0 deletions
246
Assets/Scripts/PlayableGraphTester.cs
Normal file
246
Assets/Scripts/PlayableGraphTester.cs
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Animations;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace DefaultNamespace
|
||||
{
|
||||
[RequireComponent(typeof(Animator))]
|
||||
public class PlayableGraphTester : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float bounceHeight = 0.2f;
|
||||
[SerializeField] private AnimationClip[] clips;
|
||||
[SerializeField] private float fallHeight = 0.2f;
|
||||
[SerializeField] private AnimationClip idleClip;
|
||||
[SerializeField] private Transform Root;
|
||||
[SerializeField] private float speed = 1;
|
||||
[SerializeField, Range(0, 1)] public float velocity;
|
||||
private Animator animator;
|
||||
private Avatar avatar;
|
||||
private NativeArray<float> boneWeights;
|
||||
private AnimationScriptPlayable bounceAnim;
|
||||
private PlayableGraph graph;
|
||||
private NativeArray<TransformStreamHandle> handles;
|
||||
private AnimationClipPlayable idlePlayable;
|
||||
private AnimationScriptPlayable lookAnim;
|
||||
private AnimationMixerPlayable movementMixer;
|
||||
private AnimationScriptPlayable runPlayable;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var transforms = transform.GetComponentsInChildren<Transform>();
|
||||
var numTransforms = transforms.Length - 1;
|
||||
|
||||
animator = GetComponent<Animator>();
|
||||
avatar = AvatarBuilder.BuildGenericAvatar(gameObject, "");
|
||||
animator.avatar = avatar;
|
||||
graph = PlayableGraph.Create("Test Graph");
|
||||
|
||||
handles = new NativeArray<TransformStreamHandle>(numTransforms, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
|
||||
boneWeights = new NativeArray<float>(numTransforms, Allocator.Persistent);
|
||||
for (var i = 0; i < numTransforms; i++)
|
||||
{
|
||||
handles[i] = animator.BindStreamTransform(transforms[i + 1]);
|
||||
boneWeights[i] = 1f;
|
||||
}
|
||||
|
||||
var mixerJob = new MixerJob { handles = handles, boneWeights = boneWeights };
|
||||
|
||||
var bounceJob = new BounceAnimJob { root = animator.BindStreamTransform(Root), defaultPos = Root.transform.localPosition };
|
||||
|
||||
var lookJob = new LookAnimJob { root = animator.BindStreamTransform(Root) };
|
||||
|
||||
var layerMixer = AnimationLayerMixerPlayable.Create(graph);
|
||||
|
||||
runPlayable = AnimationScriptPlayable.Create(graph, mixerJob);
|
||||
runPlayable.SetProcessInputs(false);
|
||||
|
||||
for (var i = 0; i < clips.Length; i++)
|
||||
{
|
||||
runPlayable.AddInput(AnimationClipPlayable.Create(graph, clips[i]), 0, 1);
|
||||
}
|
||||
|
||||
movementMixer = AnimationMixerPlayable.Create(graph, 2);
|
||||
idlePlayable = AnimationClipPlayable.Create(graph, idleClip);
|
||||
movementMixer.AddInput(runPlayable, 0);
|
||||
movementMixer.AddInput(idlePlayable, 0);
|
||||
layerMixer.AddInput(movementMixer, 0, 1);
|
||||
|
||||
bounceAnim = AnimationScriptPlayable.Create(graph, bounceJob);
|
||||
layerMixer.AddInput(bounceAnim, 0, 1);
|
||||
|
||||
lookAnim = AnimationScriptPlayable.Create(graph, lookJob);
|
||||
layerMixer.AddInput(lookAnim, 0, 1);
|
||||
|
||||
var animatorOutput = AnimationPlayableOutput.Create(graph, "Animator", animator);
|
||||
animatorOutput.SetSourcePlayable(layerMixer);
|
||||
graph.Play();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
movementMixer.SetInputWeight(runPlayable, velocity);
|
||||
movementMixer.SetInputWeight(idlePlayable, 1 - velocity);
|
||||
|
||||
if (idlePlayable.GetTime() > 1)
|
||||
{
|
||||
idlePlayable.Play();
|
||||
}
|
||||
|
||||
var mixerData = runPlayable.GetJobData<MixerJob>();
|
||||
var bounceData = bounceAnim.GetJobData<BounceAnimJob>();
|
||||
var lookData = lookAnim.GetJobData<LookAnimJob>();
|
||||
|
||||
mixerData.weight = Time.time * speed;
|
||||
bounceData.time = Time.time * speed;
|
||||
bounceData.bounceHeight = bounceHeight * velocity;
|
||||
bounceData.fallHeight = fallHeight * velocity;
|
||||
lookData.targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||
|
||||
runPlayable.SetJobData(mixerData);
|
||||
bounceAnim.SetJobData(bounceData);
|
||||
lookAnim.SetJobData(lookData);
|
||||
|
||||
/*
|
||||
for (int i = 0; i < clips.Length; i++)
|
||||
{
|
||||
mixer.SetInputWeight(i, currentIndex == i ? 1 - time : nextIndex == i ? time : 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
graph.Destroy();
|
||||
handles.Dispose();
|
||||
boneWeights.Dispose();
|
||||
DestroyImmediate(avatar);
|
||||
}
|
||||
|
||||
private float EaseInOut(float t, float c = 1, float b = 0, float d = 1)
|
||||
{
|
||||
t /= d / 2;
|
||||
if (t < 1)
|
||||
{
|
||||
return c / 2 * t * t * t + b;
|
||||
}
|
||||
t -= 2;
|
||||
return c / 2 * (t * t * t + 2) + b;
|
||||
}
|
||||
|
||||
public struct MixerJob : IAnimationJob
|
||||
{
|
||||
public NativeArray<TransformStreamHandle> handles;
|
||||
public NativeArray<float> boneWeights;
|
||||
public float weight;
|
||||
|
||||
public void ProcessAnimation(AnimationStream stream)
|
||||
{
|
||||
var numHandles = handles.Length;
|
||||
var inputCount = stream.inputStreamCount;
|
||||
var currentIndex = Mathf.FloorToInt(weight) % inputCount;
|
||||
var nextIndex = (currentIndex + 1) % inputCount;
|
||||
var time = weight - Mathf.FloorToInt(weight);
|
||||
|
||||
for (var i = 0; i < numHandles; i++)
|
||||
{
|
||||
var handle = handles[i];
|
||||
if (handle.IsValid(stream))
|
||||
{
|
||||
var s0 = stream.GetInputStream(GetWraped(currentIndex - 1, inputCount));
|
||||
var s1 = stream.GetInputStream(currentIndex);
|
||||
var s2 = stream.GetInputStream(GetWraped(currentIndex + 1, inputCount));
|
||||
var s3 = stream.GetInputStream(GetWraped(currentIndex + 2, inputCount));
|
||||
|
||||
var pos0 = handle.GetLocalPosition(s0);
|
||||
var pos1 = handle.GetLocalPosition(s1);
|
||||
var pos2 = handle.GetLocalPosition(s2);
|
||||
var pos3 = handle.GetLocalPosition(s3);
|
||||
|
||||
var rotA = handle.GetLocalRotation(s1);
|
||||
var rotB = handle.GetLocalRotation(s2);
|
||||
handle.SetLocalRotation(stream, Quaternion.Slerp(rotA, rotB, time * boneWeights[i]));
|
||||
|
||||
var x = CubicInterpolate(pos0.x, pos1.x, pos2.x, pos3.x, time * boneWeights[i]);
|
||||
var y = CubicInterpolate(pos0.y, pos1.y, pos2.y, pos3.y, time * boneWeights[i]);
|
||||
|
||||
handle.SetLocalPosition(stream, new Vector3(x, y, pos1.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessRootMotion(AnimationStream stream)
|
||||
{
|
||||
/*var streamA = stream.GetInputStream(0);
|
||||
var streamB = stream.GetInputStream(1);
|
||||
|
||||
var velocity = Vector3.Lerp(streamA.velocity, streamB.velocity, weight);
|
||||
var angularVelocity = Vector3.Lerp(streamA.angularVelocity, streamB.angularVelocity, weight);
|
||||
stream.velocity = velocity;
|
||||
stream.angularVelocity = angularVelocity;*/
|
||||
}
|
||||
|
||||
private float CubicInterpolate(float y0, float y1, float y2, float y3, float mu)
|
||||
{
|
||||
float a0, a1, a2, a3, mu2;
|
||||
|
||||
mu2 = mu * mu;
|
||||
a0 = y3 - y2 - y0 + y1;
|
||||
a1 = y0 - y1 - a0;
|
||||
a2 = y2 - y0;
|
||||
a3 = y1;
|
||||
|
||||
return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3;
|
||||
}
|
||||
|
||||
private int GetWraped(int index, int length)
|
||||
{
|
||||
var wrapedIndex = index % length;
|
||||
if (wrapedIndex < 0)
|
||||
{
|
||||
return length + wrapedIndex;
|
||||
}
|
||||
return wrapedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public struct BounceAnimJob : IAnimationJob
|
||||
{
|
||||
public Vector2 defaultPos;
|
||||
public TransformStreamHandle root;
|
||||
public float time;
|
||||
public float bounceHeight;
|
||||
public float fallHeight;
|
||||
|
||||
public void ProcessAnimation(AnimationStream stream)
|
||||
{
|
||||
var pos = defaultPos;
|
||||
pos += new Vector2(0, Mathf.Abs(Mathf.Sin(Mathf.PI + time * 0.25f * Mathf.PI * 2))) * bounceHeight;
|
||||
pos += new Vector2(0, Mathf.Abs(Mathf.Cos(Mathf.PI + time * 0.25f * Mathf.PI * 2))) * fallHeight;
|
||||
root.SetLocalPosition(stream, pos);
|
||||
}
|
||||
|
||||
public void ProcessRootMotion(AnimationStream stream)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public struct LookAnimJob : IAnimationJob
|
||||
{
|
||||
public TransformStreamHandle root;
|
||||
public Vector2 targetPos;
|
||||
|
||||
public void ProcessAnimation(AnimationStream stream)
|
||||
{
|
||||
Vector2 pos = root.GetPosition(stream);
|
||||
var dir = (targetPos - pos).normalized;
|
||||
var angle = Vector2.SignedAngle(Vector2.right, dir);
|
||||
root.SetLocalRotation(stream, Quaternion.Euler(0, 0, angle));
|
||||
}
|
||||
|
||||
public void ProcessRootMotion(AnimationStream stream)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue