123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- using UnityEngine;
- using System.Collections;
- namespace RootMotion.FinalIK {
-
-
-
- public abstract class OffsetModifier: MonoBehaviour {
-
-
-
- [System.Serializable]
- public class OffsetLimits {
- [Tooltip("The effector type (this is just an enum)")]
- public FullBodyBipedEffector effector;
- [Tooltip("Spring force, if zero then this is a hard limit, if not, offset can exceed the limit.")]
- public float spring = 0f;
- [Tooltip("Which axes to limit the offset on?")]
- public bool x, y, z;
- [Tooltip("The limits")]
- public float minX, maxX, minY, maxY, minZ, maxZ;
-
-
- public void Apply(IKEffector e, Quaternion rootRotation) {
- Vector3 offset = Quaternion.Inverse(rootRotation) * e.positionOffset;
-
- if (spring <= 0f) {
-
- if (x) offset.x = Mathf.Clamp(offset.x, minX, maxX);
- if (y) offset.y = Mathf.Clamp(offset.y, minY, maxY);
- if (z) offset.z = Mathf.Clamp(offset.z, minZ, maxZ);
- } else {
-
- if (x) offset.x = SpringAxis(offset.x, minX, maxX);
- if (y) offset.y = SpringAxis(offset.y, minY, maxY);
- if (z) offset.z = SpringAxis(offset.z, minZ, maxZ);
- }
-
-
- e.positionOffset = rootRotation * offset;
- }
-
-
- private float SpringAxis(float value, float min, float max) {
- if (value > min && value < max) return value;
- if (value < min) return Spring(value, min, true);
- return Spring(value, max, false);
- }
-
-
- private float Spring(float value, float limit, bool negative) {
- float illegal = value - limit;
- float s = illegal * spring;
-
- if (negative) return value + Mathf.Clamp(-s, 0, -illegal);
- return value - Mathf.Clamp(s, 0, illegal);
- }
- }
- [Tooltip("The master weight")]
- public float weight = 1f;
- [Tooltip("Reference to the FBBIK component")]
- public FullBodyBipedIK ik;
-
- protected float deltaTime { get { return Time.time - lastTime; }}
- protected abstract void OnModifyOffset();
- protected float lastTime;
- protected virtual void Start() {
- StartCoroutine(Initiate());
- }
-
- private IEnumerator Initiate() {
- while (ik == null) yield return null;
-
- ik.solver.OnPreUpdate += ModifyOffset;
- lastTime = Time.time;
- }
-
- private void ModifyOffset() {
- if (!enabled) return;
- if (weight <= 0f) return;
- if (deltaTime <= 0f) return;
- if (ik == null) return;
- weight = Mathf.Clamp(weight, 0f, 1f);
- OnModifyOffset();
- lastTime = Time.time;
- }
- protected void ApplyLimits(OffsetLimits[] limits) {
-
- foreach (OffsetLimits limit in limits) {
- limit.Apply(ik.solver.GetEffector(limit.effector), transform.rotation);
- }
- }
-
- protected virtual void OnDestroy() {
- if (ik != null) ik.solver.OnPreUpdate -= ModifyOffset;
- }
- }
- }
|