Files
2026-03-04 10:03:45 +08:00

108 lines
2.9 KiB
C#

using System;
using UnityEngine;
namespace RootMotion.FinalIK
{
[Serializable]
public class IKSolverCCD : IKSolverHeuristic
{
public IterationDelegate OnPreIteration;
public void FadeOutBoneWeights()
{
if (bones.Length >= 2)
{
bones[0].weight = 1f;
float num = 1f / (float)(bones.Length - 1);
for (int i = 1; i < bones.Length; i++)
{
bones[i].weight = num * (float)(bones.Length - 1 - i);
}
}
}
protected override void OnInitiate()
{
if (firstInitiation || !Application.isPlaying)
{
IKPosition = bones[bones.Length - 1].transform.position;
}
InitiateBones();
}
protected override void OnUpdate()
{
if (IKPositionWeight <= 0f)
{
return;
}
IKPositionWeight = Mathf.Clamp(IKPositionWeight, 0f, 1f);
if (target != null)
{
IKPosition = target.position;
}
if (XY)
{
IKPosition.z = bones[0].transform.position.z;
}
Vector3 vector = ((maxIterations > 1) ? GetSingularityOffset() : Vector3.zero);
for (int i = 0; i < maxIterations && (!(vector == Vector3.zero) || i < 1 || !(tolerance > 0f) || !(base.positionOffset < tolerance * tolerance)); i++)
{
lastLocalDirection = localDirection;
if (OnPreIteration != null)
{
OnPreIteration(i);
}
Solve(IKPosition + ((i == 0) ? vector : Vector3.zero));
}
lastLocalDirection = localDirection;
}
protected void Solve(Vector3 targetPosition)
{
if (XY)
{
for (int num = bones.Length - 2; num > -1; num--)
{
float num2 = bones[num].weight * IKPositionWeight;
if (num2 > 0f)
{
Vector3 vector = bones[bones.Length - 1].transform.position - bones[num].transform.position;
Vector3 vector2 = targetPosition - bones[num].transform.position;
float current = Mathf.Atan2(vector.x, vector.y) * 57.29578f;
float num3 = Mathf.Atan2(vector2.x, vector2.y) * 57.29578f;
bones[num].transform.rotation = Quaternion.AngleAxis(Mathf.DeltaAngle(current, num3) * num2, Vector3.back) * bones[num].transform.rotation;
}
if (useRotationLimits && bones[num].rotationLimit != null)
{
bones[num].rotationLimit.Apply();
}
}
return;
}
for (int num4 = bones.Length - 2; num4 > -1; num4--)
{
float num5 = bones[num4].weight * IKPositionWeight;
if (num5 > 0f)
{
Vector3 fromDirection = bones[bones.Length - 1].transform.position - bones[num4].transform.position;
Vector3 toDirection = targetPosition - bones[num4].transform.position;
Quaternion quaternion = Quaternion.FromToRotation(fromDirection, toDirection) * bones[num4].transform.rotation;
if (num5 >= 1f)
{
bones[num4].transform.rotation = quaternion;
}
else
{
bones[num4].transform.rotation = Quaternion.Lerp(bones[num4].transform.rotation, quaternion, num5);
}
}
if (useRotationLimits && bones[num4].rotationLimit != null)
{
bones[num4].rotationLimit.Apply();
}
}
}
}
}