123 lines
3.3 KiB
C#
Raw Normal View History

2023-04-24 15:49:03 +02:00
using UnityEngine;
using System.Collections.Generic;
namespace Pathfinding {
[HelpURL("http://arongranberg.com/astar/docs/class_pathfinding_1_1_animation_link.php")]
public class AnimationLink : NodeLink2 {
public string clip;
public float animSpeed = 1;
public bool reverseAnim = true;
public GameObject referenceMesh;
public LinkClip[] sequence;
public string boneRoot = "bn_COG_Root";
[System.Serializable]
public class LinkClip {
public AnimationClip clip;
public Vector3 velocity;
public int loopCount = 1;
public string name {
get {
return clip != null ? clip.name : "";
}
}
}
static Transform SearchRec (Transform tr, string name) {
int childCount = tr.childCount;
for (int i = 0; i < childCount; i++) {
Transform ch = tr.GetChild(i);
if (ch.name == name) return ch;
else {
Transform rec = SearchRec(ch, name);
if (rec != null) return rec;
}
}
return null;
}
public void CalculateOffsets (List<Vector3> trace, out Vector3 endPosition) {
//Vector3 opos = transform.position;
endPosition = transform.position;
if (referenceMesh == null) return;
GameObject ob = GameObject.Instantiate(referenceMesh, transform.position, transform.rotation) as GameObject;
ob.hideFlags = HideFlags.HideAndDontSave;
Transform root = SearchRec(ob.transform, boneRoot);
if (root == null) throw new System.Exception("Could not find root transform");
Animation anim = ob.GetComponent<Animation>();
if (anim == null) anim = ob.AddComponent<Animation>();
for (int i = 0; i < sequence.Length; i++) {
anim.AddClip(sequence[i].clip, sequence[i].clip.name);
}
Vector3 prevOffset = Vector3.zero;
Vector3 position = transform.position;
Vector3 firstOffset = Vector3.zero;
for (int i = 0; i < sequence.Length; i++) {
LinkClip c = sequence[i];
if (c == null) {
endPosition = position;
return;
}
anim[c.clip.name].enabled = true;
anim[c.clip.name].weight = 1;
for (int repeat = 0; repeat < c.loopCount; repeat++) {
anim[c.clip.name].normalizedTime = 0;
anim.Sample();
Vector3 soffset = root.position - transform.position;
if (i > 0) {
position += prevOffset - soffset;
} else {
firstOffset = soffset;
}
for (int t = 0; t <= 20; t++) {
float tf = t/20.0f;
anim[c.clip.name].normalizedTime = tf;
anim.Sample();
Vector3 tmp = position + (root.position-transform.position) + c.velocity*tf*c.clip.length;
trace.Add(tmp);
}
position = position + c.velocity*1*c.clip.length;
anim[c.clip.name].normalizedTime = 1;
anim.Sample();
Vector3 eoffset = root.position - transform.position;
prevOffset = eoffset;
}
anim[c.clip.name].enabled = false;
anim[c.clip.name].weight = 0;
}
position += prevOffset - firstOffset;
GameObject.DestroyImmediate(ob);
endPosition = position;
}
public override void OnDrawGizmosSelected () {
base.OnDrawGizmosSelected();
List<Vector3> buffer = Pathfinding.Util.ListPool<Vector3>.Claim();
Vector3 endPosition = Vector3.zero;
CalculateOffsets(buffer, out endPosition);
Gizmos.color = Color.blue;
for (int i = 0; i < buffer.Count-1; i++) {
Gizmos.DrawLine(buffer[i], buffer[i+1]);
}
}
}
}