100 lines
3.4 KiB
C#
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;
|
|
}
|
|
}
|