summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/AnimationLinkTraverser.cs
blob: 455bc3ef058b26b931956b11bdfc0149ecd722cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System.Collections;
using UnityEngine;

namespace Pathfinding.Examples {
	using Pathfinding;

	/// <summary>
	/// Example of how to handle off-mesh link traversal.
	/// This is used in the "Example4_Recast_Navmesh2" example scene.
	///
	/// See: <see cref="Pathfinding.RichAI"/>
	/// See: <see cref="Pathfinding.RichAI.onTraverseOffMeshLink"/>
	/// See: <see cref="Pathfinding.AnimationLink"/>
	/// </summary>
	[HelpURL("https://arongranberg.com/astar/documentation/stable/animationlinktraverser.html")]
	public class AnimationLinkTraverser : VersionedMonoBehaviour {
		public Animation anim;

		RichAI ai;

		void OnEnable () {
			ai = GetComponent<RichAI>();
			if (ai != null) ai.onTraverseOffMeshLink += TraverseOffMeshLink;
		}

		void OnDisable () {
			if (ai != null) ai.onTraverseOffMeshLink -= TraverseOffMeshLink;
		}

		protected virtual IEnumerator TraverseOffMeshLink (RichSpecial rs) {
			var link = rs.nodeLink.gameObject.GetComponent<AnimationLink>();

			if (link == null) {
				Debug.LogError("Unhandled RichSpecial");
				yield break;
			}

			// Rotate character to face the correct direction
			while (true) {
				var origRotation = ai.rotation;
				var finalRotation = ai.SimulateRotationTowards(rs.first.rotation * Vector3.forward, ai.rotationSpeed * Time.deltaTime);
				// Rotate until the rotation does not change anymore
				if (origRotation == finalRotation) break;
				ai.FinalizeMovement(ai.position, finalRotation);
				yield return null;
			}

			// Reposition
			transform.parent.position = transform.position;

			transform.parent.rotation = transform.rotation;
			transform.localPosition = Vector3.zero;
			transform.localRotation = Quaternion.identity;

			// Set up animation speeds
			if (rs.reverse && link.reverseAnim) {
				anim[link.clip].speed = -link.animSpeed;
				anim[link.clip].normalizedTime = 1;
				anim.Play(link.clip);
				anim.Sample();
			} else {
				anim[link.clip].speed = link.animSpeed;
				anim.Rewind(link.clip);
				anim.Play(link.clip);
			}

			// Fix required for animations in reverse direction
			transform.parent.position -= transform.position-transform.parent.position;

			// Wait for the animation to finish
			yield return new WaitForSeconds(Mathf.Abs(anim[link.clip].length/link.animSpeed));
		}
	}
}