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.
		
		
		
		
		
			
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C#
		
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
using System;
 | 
						|
 | 
						|
namespace RootMotion.FinalIK
 | 
						|
{
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Posing the children of a Transform to match the children of another Transform that has different bone orientations.
 | 
						|
	/// </summary>
 | 
						|
	public class UniversalPoser : Poser
 | 
						|
	{
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Mapping a bone to its target
 | 
						|
		/// </summary>
 | 
						|
		[System.Serializable]
 | 
						|
		public class Map
 | 
						|
		{
 | 
						|
			public Transform bone;
 | 
						|
			[HideInInspector]
 | 
						|
			public Transform target;
 | 
						|
 | 
						|
			private Vector3 defaultLocalPosition;
 | 
						|
			private Quaternion defaultLocalRotation;
 | 
						|
			
 | 
						|
			// Custom constructor
 | 
						|
			public Map(Transform bone, Transform target)
 | 
						|
			{
 | 
						|
				this.bone = bone;
 | 
						|
				this.target = target;
 | 
						|
 | 
						|
				StoreDefaultState();
 | 
						|
			}
 | 
						|
 | 
						|
			public void StoreDefaultState()
 | 
						|
			{
 | 
						|
				defaultLocalPosition = bone.localPosition;
 | 
						|
				defaultLocalRotation = bone.localRotation;
 | 
						|
			}
 | 
						|
 | 
						|
			public void FixTransform()
 | 
						|
			{
 | 
						|
				bone.localPosition = defaultLocalPosition;
 | 
						|
				bone.localRotation = defaultLocalRotation;
 | 
						|
			}
 | 
						|
 | 
						|
			// Update mapping
 | 
						|
			public void Update(float localRotationWeight, float localPositionWeight, Vector3 targetAxis1, Vector3 targetAxis2, Vector3 axis1, Vector3 axis2)
 | 
						|
			{
 | 
						|
				if (targetAxis1 == axis1 && targetAxis2 == axis2)
 | 
						|
				{
 | 
						|
					bone.localRotation = Quaternion.Lerp(bone.localRotation, target.localRotation, localRotationWeight);
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					Quaternion r = Quaternion.Lerp(bone.localRotation, QuaTools.MatchRotation(target.localRotation, targetAxis1, targetAxis2, axis1, axis2), localRotationWeight);
 | 
						|
					Quaternion c = QuaTools.MatchRotation(Quaternion.identity, targetAxis1, targetAxis2, axis1, axis2);
 | 
						|
					bone.localRotation = c * r;
 | 
						|
				}
 | 
						|
 | 
						|
				//bone.localPosition = Vector3.Lerp(bone.localPosition, target.localPosition, localPositionWeight); //TODO
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		[Tooltip("Choose 2 axes of a finger bone. For example 1 pointing towards the next finger and 2 pointing up. Select a finger bone in the InteractionTarget hierarchy and see which local axis points towards the next bone and which local axis points up and set targetAxis1 and targetAxis2 accordingly. Then select a finger in this poser's hierarchy and do the same for axis1 and axis2.")]
 | 
						|
		public Vector3 targetAxis1, targetAxis2, axis1, axis2;
 | 
						|
		[Tooltip("List of bones must match InteractionTarget's list of bones in both array size and hierarchy.")]
 | 
						|
		public Map[] bones;
 | 
						|
 | 
						|
		public override void AutoMapping() {}
 | 
						|
 | 
						|
        public override void AutoMapping(Transform[] bones)
 | 
						|
        {
 | 
						|
			if (bones.Length != this.bones.Length)
 | 
						|
            {
 | 
						|
				Debug.LogError("Trying to use UniversalPoser with an InteractionTarget that has a different number of bones. Bones must match with UniversalPoser bones in both array size and hierarchy", transform);
 | 
						|
				return;
 | 
						|
            }
 | 
						|
 | 
						|
            for (int i = 0; i < this.bones.Length; i++)
 | 
						|
            {
 | 
						|
				this.bones[i].target = bones[i];
 | 
						|
            }
 | 
						|
 | 
						|
			StoreDefaultState();
 | 
						|
		}
 | 
						|
 | 
						|
        protected override void InitiatePoser()
 | 
						|
		{
 | 
						|
			StoreDefaultState();
 | 
						|
		}
 | 
						|
 | 
						|
		protected override void UpdatePoser()
 | 
						|
		{
 | 
						|
			if (weight <= 0f) return;
 | 
						|
			if (localPositionWeight <= 0f && localRotationWeight <= 0f) return;
 | 
						|
			if (poseRoot == null) return;
 | 
						|
 | 
						|
			// Calculate weights
 | 
						|
			float rW = localRotationWeight * weight;
 | 
						|
			float pW = localPositionWeight * weight;
 | 
						|
 | 
						|
			// Lerping the localRotation and the localPosition
 | 
						|
			for (int i = 0; i < bones.Length; i++) bones[i].Update(rW, pW, targetAxis1, targetAxis2, axis1, axis2);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		protected override void FixPoserTransforms()
 | 
						|
		{
 | 
						|
			for (int i = 0; i < bones.Length; i++)
 | 
						|
			{
 | 
						|
				bones[i].FixTransform();
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		private void StoreDefaultState()
 | 
						|
		{
 | 
						|
			for (int i = 0; i < bones.Length; i++)
 | 
						|
			{
 | 
						|
				bones[i].StoreDefaultState();
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// Returns a Transform from the array that has the specified name
 | 
						|
		private Transform GetTargetNamed(string tName, Transform[] array)
 | 
						|
		{
 | 
						|
			for (int i = 0; i < array.Length; i++)
 | 
						|
			{
 | 
						|
				if (array[i].name == tName) return array[i];
 | 
						|
			}
 | 
						|
			return null;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
	}
 | 
						|
}
 |