118 lines
4.5 KiB
C#
118 lines
4.5 KiB
C#
// ============================================================
|
|
// Renamed/modified from JiggleBone so it won't conflict.
|
|
// Name: Jiggle Bone v.1.0
|
|
// Author: Michael Cook (Fishypants)
|
|
// Date: 9-25-2011
|
|
// License: Free to use. Any credit would be nice :)
|
|
//
|
|
// To Use:
|
|
// Drag this script onto a bone. (ideally bones at the end)
|
|
// Set the boneAxis to be the front facing axis of the bone.
|
|
// Done! Now you have bones with jiggle dynamics.
|
|
//
|
|
// ============================================================
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
namespace UMA
|
|
{
|
|
public class UMAJiggleBone : MonoBehaviour
|
|
{
|
|
// Target and dynamic positions
|
|
Vector3 dynamicPos = new Vector3();
|
|
|
|
// Bone settings
|
|
public Vector3 boneAxis = new Vector3(0, 0, 1);
|
|
public float targetDistance = 2.0f;
|
|
|
|
// Dynamics settings
|
|
public float bStiffness = 0.1f;
|
|
public float bMass = 0.9f;
|
|
public float bDamping = 0.6f;
|
|
public float bGravity = 0.75f;
|
|
|
|
// Dynamics variables
|
|
Vector3 force = new Vector3();
|
|
Vector3 acc = new Vector3();
|
|
Vector3 vel = new Vector3();
|
|
|
|
// Squash and stretch variables
|
|
public bool SquashAndStretch = true;
|
|
public float sideStretch = 0.25f;
|
|
public float frontStretch = 0.3f;
|
|
|
|
void Awake()
|
|
{
|
|
// Set targetPos and dynamicPos at startup
|
|
Vector3 targetPos = transform.position + transform.TransformDirection(new Vector3((boneAxis.x * targetDistance), (boneAxis.y * targetDistance), (boneAxis.z * targetDistance)));
|
|
dynamicPos = targetPos;
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
// Reset the bone rotation so we can recalculate the upVector and forwardVector
|
|
transform.rotation = new Quaternion();
|
|
|
|
// Update forwardVector and upVector
|
|
Vector3 upVector = transform.TransformDirection(new Vector3(0, 1, 0));
|
|
|
|
// Calculate target position
|
|
Vector3 targetPos = transform.position + transform.TransformDirection(new Vector3((boneAxis.x * targetDistance), (boneAxis.y * targetDistance), (boneAxis.z * targetDistance)));
|
|
|
|
// Calculate force, acceleration, and velocity per X, Y and Z
|
|
force.x = (targetPos.x - dynamicPos.x) * bStiffness;
|
|
acc.x = force.x / bMass;
|
|
vel.x += acc.x * (1 - bDamping);
|
|
|
|
force.y = (targetPos.y - dynamicPos.y) * bStiffness;
|
|
force.y -= bGravity / 10; // Add some gravity
|
|
acc.y = force.y / bMass;
|
|
vel.y += acc.y * (1 - bDamping);
|
|
|
|
force.z = (targetPos.z - dynamicPos.z) * bStiffness;
|
|
acc.z = force.z / bMass;
|
|
vel.z += acc.z * (1 - bDamping);
|
|
|
|
// Update dynamic postion
|
|
dynamicPos += vel + force;
|
|
|
|
// Set bone rotation to look at dynamicPos
|
|
transform.LookAt(dynamicPos, upVector);
|
|
|
|
// ==================================================
|
|
// Squash and Stretch section
|
|
// ==================================================
|
|
if (SquashAndStretch)
|
|
{
|
|
// Create a vector from target position to dynamic position
|
|
// We will measure the magnitude of the vector to determine
|
|
// how much squash and stretch we will apply
|
|
Vector3 dynamicVec = dynamicPos - targetPos;
|
|
|
|
// Get the magnitude of the vector
|
|
float stretchMag = dynamicVec.magnitude;
|
|
|
|
// Here we determine the amount of squash and stretch based on stretchMag
|
|
// and the direction the Bone Axis is pointed in. Ideally there should be
|
|
// a vector with two values at 0 and one at 1. Like Vector3(0,0,1)
|
|
// for the 0 values, we assume those are the sides, and 1 is the direction
|
|
// the bone is facing
|
|
float xStretch;
|
|
if (boneAxis.x == 0) xStretch = 1 + (-stretchMag * sideStretch);
|
|
else xStretch = 1 + (stretchMag * frontStretch);
|
|
|
|
float yStretch;
|
|
if (boneAxis.y == 0) yStretch = 1 + (-stretchMag * sideStretch);
|
|
else yStretch = 1 + (stretchMag * frontStretch);
|
|
|
|
float zStretch;
|
|
if (boneAxis.z == 0) zStretch = 1 + (-stretchMag * sideStretch);
|
|
else zStretch = 1 + (stretchMag * frontStretch);
|
|
|
|
// Set the bone scale
|
|
transform.localScale = new Vector3(xStretch, yStretch, zStretch);
|
|
}
|
|
}
|
|
}
|
|
} |