You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			128 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C#
		
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
 | 
						|
namespace RootMotion {
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Manages solver initiation and updating
 | 
						|
	/// </summary>
 | 
						|
	public class SolverManager: MonoBehaviour {
 | 
						|
		
 | 
						|
		#region Main Interface
 | 
						|
		
 | 
						|
		/// <summary>
 | 
						|
		/// If true, will fix all the Transforms used by the solver to their initial state in each Update. This prevents potential problems with unanimated bones and animator culling with a small cost of performance. Not recommended for CCD and FABRIK solvers.
 | 
						|
		/// </summary>
 | 
						|
		[Tooltip("If true, will fix all the Transforms used by the solver to their initial state in each Update. This prevents potential problems with unanimated bones and animator culling with a small cost of performance. Not recommended for CCD and FABRIK solvers.")]
 | 
						|
		public bool fixTransforms = true;
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// [DEPRECATED] Use "enabled = false" instead.
 | 
						|
		/// </summary>
 | 
						|
		public void Disable() {
 | 
						|
			Debug.Log("IK.Disable() is deprecated. Use enabled = false instead", transform);
 | 
						|
 | 
						|
			enabled = false;
 | 
						|
		}
 | 
						|
 | 
						|
		#endregion Main
 | 
						|
 | 
						|
		protected virtual void InitiateSolver() {}
 | 
						|
		protected virtual void UpdateSolver() {}
 | 
						|
		protected virtual void FixTransforms() {}
 | 
						|
		
 | 
						|
		private Animator animator;
 | 
						|
		private Animation legacy;
 | 
						|
		private bool updateFrame;
 | 
						|
		private bool componentInitiated;
 | 
						|
 | 
						|
		void OnDisable() {
 | 
						|
			if (!Application.isPlaying) return;
 | 
						|
			Initiate();
 | 
						|
		}
 | 
						|
 | 
						|
		void Start() {
 | 
						|
			Initiate();
 | 
						|
		}
 | 
						|
 | 
						|
		private bool animatePhysics {
 | 
						|
			get {
 | 
						|
				if (animator != null) return animator.updateMode == AnimatorUpdateMode.AnimatePhysics;
 | 
						|
				if (legacy != null) return legacy.animatePhysics;
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private void Initiate() {
 | 
						|
			if (componentInitiated) return;
 | 
						|
 | 
						|
			FindAnimatorRecursive(transform, true);
 | 
						|
			
 | 
						|
			InitiateSolver();
 | 
						|
			componentInitiated = true;
 | 
						|
		}
 | 
						|
 | 
						|
		void Update() {
 | 
						|
			if (skipSolverUpdate) return;
 | 
						|
			if (animatePhysics) return;
 | 
						|
 | 
						|
			if (fixTransforms) FixTransforms();
 | 
						|
		}
 | 
						|
 | 
						|
		// Finds the first Animator/Animation up the hierarchy
 | 
						|
		private void FindAnimatorRecursive(Transform t, bool findInChildren) {
 | 
						|
			if (isAnimated) return;
 | 
						|
 | 
						|
			animator = t.GetComponent<Animator>();
 | 
						|
			legacy = t.GetComponent<Animation>();
 | 
						|
 | 
						|
			if (isAnimated) return;
 | 
						|
 | 
						|
			if (animator == null && findInChildren) animator = t.GetComponentInChildren<Animator>();
 | 
						|
			if (legacy == null && findInChildren) legacy = t.GetComponentInChildren<Animation>();
 | 
						|
 | 
						|
			if (!isAnimated && t.parent != null) FindAnimatorRecursive(t.parent, false);
 | 
						|
		}
 | 
						|
 | 
						|
		private bool isAnimated {
 | 
						|
			get {
 | 
						|
				return animator != null || legacy != null;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// Workaround hack for the solver to work with animatePhysics
 | 
						|
		void FixedUpdate() {
 | 
						|
			if (skipSolverUpdate) {
 | 
						|
				skipSolverUpdate = false;
 | 
						|
			}
 | 
						|
 | 
						|
			updateFrame = true;
 | 
						|
 | 
						|
			if (animatePhysics && fixTransforms) FixTransforms();
 | 
						|
		}
 | 
						|
 | 
						|
		// Updating
 | 
						|
		void LateUpdate() {
 | 
						|
			if (skipSolverUpdate) return;
 | 
						|
 | 
						|
			// Check if either animatePhysics is false or FixedUpdate has been called
 | 
						|
			if (!animatePhysics) updateFrame = true;
 | 
						|
			if (!updateFrame) return;
 | 
						|
			updateFrame = false;
 | 
						|
 | 
						|
			UpdateSolver();
 | 
						|
		}
 | 
						|
 | 
						|
		// This enables other scripts to update the Animator on in FixedUpdate and the solvers with it
 | 
						|
		private bool skipSolverUpdate;
 | 
						|
 | 
						|
		public void UpdateSolverExternal() {
 | 
						|
			if (!enabled) return;
 | 
						|
 | 
						|
			skipSolverUpdate = true;
 | 
						|
			
 | 
						|
			UpdateSolver();
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |