2026-05-06 15:07:56 +02:00

100 lines
3.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwayBone : MonoBehaviour
{
[Range(0.0f,1.0f)]
[Tooltip("How much inertia each bone has - makes it more bouncy")]
public float inertia = 0.75f; // how much the force slows each second.
[Range(1.0f,2.0f)]
[Tooltip("How far something can stretch - 1.0 = no stretch")]
public float limit = 2.0f;
[Range(1.0f, 4.0f)]
[Tooltip("How much it can pull away during movement")]
public float elasticity = 2.0f;
[Tooltip("Only rotate. Not supported in v1")]
public bool OrientOnly;
[Tooltip("Also reorient bones")]
public bool Reorient;
protected Vector3 LastWorldPos; // Where this was last in the world. Used for detecting world movement.
protected Vector3 localRestingPos; // Where this is at rest.
protected Vector3 currentForce;
protected Vector3 localTarget;
Vector3 targetvector;
protected Quaternion localOrientation; // current angles
protected float MaxDistance;
public float frameInertia;
public bool isTopLevel;
public Vector3 ViewLocalOrientation;
public Vector3 ViewInverseLocalOrientation;
public Vector3 ViewLocalRotation;
public Vector3 ViewInverseLocalRotation;
public Vector3 ViewRotation;
public Vector3 ViewInverseRotation;
public void Initialize()
{
currentForce = Vector3.zero;
localRestingPos = transform.localPosition;
localOrientation = transform.localRotation;
localTarget = localRestingPos * -1;
LastWorldPos = transform.position;
MaxDistance = limit * localRestingPos.magnitude;
}
public void DoUpdate(float step)
{
// Get the new position.
Vector3 worldRestingPosition = transform.parent.TransformPoint(localRestingPos);
Vector3 worldLookAtPosition = transform.parent.position;
Vector3 GlobalForce = (worldRestingPosition - LastWorldPos) * step * elasticity;
if (!OrientOnly)
{
transform.position = LastWorldPos + GlobalForce + currentForce;
}
// Clamp the position at the limit.
if ((transform.position - worldRestingPosition).magnitude > MaxDistance)
{
targetvector = worldRestingPosition - transform.position;
if (!OrientOnly)
{
transform.position = worldRestingPosition - (targetvector.normalized * MaxDistance);
}
}
#if false
// orient toward the parent.
if (Reorient)
{
//float BoneLength = Vector3.Distance(child.position, child.parent.position);
//Scale.Set(BoneLength / 10.0f, BoneLength / 10.0f, BoneLength);
Vector3 relativePos = transform.position - transform.parent.transform.position;
Quaternion rotation = (relativePos == Vector3.zero) ? Quaternion.identity : Quaternion.LookRotation(relativePos);
Quaternion LocalRotation = Quaternion.Inverse(transform.rotation) * rotation;
ViewLocalOrientation = localOrientation.eulerAngles; // orientation without pointing.
ViewRotation = rotation.eulerAngles; // orientation to point to
ViewLocalRotation = LocalRotation.eulerAngles; // End orientation in local space.
ViewInverseLocalOrientation = Quaternion.Inverse(localOrientation).eulerAngles;
ViewInverseRotation = Quaternion.Inverse(rotation).eulerAngles;
ViewInverseLocalRotation = Quaternion.Inverse(LocalRotation).eulerAngles;
transform.localRotation = LocalRotation; // rotation * localOrientation;// Quaternion.Inverse(this.localOrientation); // LocalRotation;
}
#endif
currentForce += GlobalForce;
currentForce *= inertia;
LastWorldPos = transform.position;
targetvector = worldRestingPosition;
}
}