add ckg
plantilla base para movimiento básico
This commit is contained in:
@@ -0,0 +1,812 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
public class upperBodyRotationSystem : MonoBehaviour
|
||||
{
|
||||
[Header ("Main Settings")]
|
||||
[Space]
|
||||
|
||||
public bool shakeUpperBodyEnabled = true;
|
||||
|
||||
[Space]
|
||||
[Header ("Head Settings")]
|
||||
[Space]
|
||||
|
||||
public Vector3 headLookVector = Vector3.forward;
|
||||
public Vector3 headUpVector = Vector3.up;
|
||||
|
||||
[Space]
|
||||
[Header ("Rotation Settings")]
|
||||
[Space]
|
||||
|
||||
public float horizontalThresholdAngleDifference = 5;
|
||||
public float verticalThresholdAngleDifference = 5;
|
||||
public float horizontalBendingMultiplier = 1;
|
||||
public float verticalBendingMultiplier = 1;
|
||||
public float horizontalMaxAngleDifference = 90;
|
||||
public float verticalMaxAngleDifference = 90;
|
||||
public float maxBendingAngle = 90;
|
||||
public float horizontalResponsiveness = 10;
|
||||
public float verticalResponsiveness = 10;
|
||||
|
||||
public float upperBodyRotationSpeed = 5;
|
||||
public float rotationSpeed = 5;
|
||||
|
||||
[Space]
|
||||
[Space]
|
||||
|
||||
public bool chestRotationEnabled = true;
|
||||
public bool spineRotationEnabled = true;
|
||||
public bool extraHorizontalRotationEnabled = true;
|
||||
|
||||
public bool horizontalRotationEnabled = true;
|
||||
public bool verticalRotationEnabled = true;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool useSmoothRotationPointValue;
|
||||
public float smoothRotationPointValue = 0.1f;
|
||||
|
||||
[Space]
|
||||
[Header ("Chest Orientation Settings")]
|
||||
[Space]
|
||||
|
||||
public Vector3 chestUpVector = new Vector3 (0, 0, 1);
|
||||
|
||||
[Space]
|
||||
[Header ("Spine And Chest Transforms")]
|
||||
[Space]
|
||||
|
||||
public Transform spineTransform;
|
||||
public Transform chestTransform;
|
||||
|
||||
[Space]
|
||||
[Header ("Other Settings")]
|
||||
[Space]
|
||||
|
||||
public bool followFullRotationPointDirection;
|
||||
|
||||
public Vector3 followFullRotationPointMultipliers = Vector3.one;
|
||||
|
||||
public bool useFollowFullRotationClamp;
|
||||
|
||||
public Vector2 followFullRotationClampX;
|
||||
public Vector2 followFullRotationClampY;
|
||||
public Vector2 followFullRotationClampZ;
|
||||
|
||||
[Space]
|
||||
[Header ("Debug")]
|
||||
[Space]
|
||||
|
||||
public bool IKUpperBodyActive;
|
||||
public float currentExtraRotation;
|
||||
public bool usingWeaponRotationPoint;
|
||||
|
||||
public bool usingTemporalObjectToFollow;
|
||||
public Transform temporalObjectToFollow;
|
||||
|
||||
public Transform currentWeaponRotationPoint;
|
||||
|
||||
public bool fullBodyAwarenessActive;
|
||||
|
||||
[Space]
|
||||
[Header ("Components")]
|
||||
[Space]
|
||||
|
||||
public Transform objectToFollow;
|
||||
public Transform weaponRotationPointToFollow;
|
||||
public playerController playerControllerManager;
|
||||
|
||||
|
||||
bool usingDualWeapon;
|
||||
|
||||
|
||||
|
||||
float currentRotation;
|
||||
float rotationXValue;
|
||||
|
||||
weaponRotationPointInfo rotationPointInfo;
|
||||
|
||||
int currentRotationDirection = 1;
|
||||
|
||||
Quaternion chestRotation;
|
||||
Quaternion spineRotation;
|
||||
|
||||
float angleH;
|
||||
float angleV;
|
||||
Vector3 dirUp;
|
||||
Vector3 referenceLookDir;
|
||||
Vector3 referenceUpDir;
|
||||
float originalAngleDifference;
|
||||
Coroutine changeExtraRotation;
|
||||
|
||||
Vector3 extraRotation;
|
||||
|
||||
float auxCurrentExtraRotation;
|
||||
|
||||
Coroutine shakeUpperBodyRotationCoroutine;
|
||||
|
||||
Quaternion parentRot;
|
||||
Quaternion parentRotInv;
|
||||
Vector3 lookDirWorld;
|
||||
Vector3 lookDirGoal;
|
||||
|
||||
Vector3 rightOfTarget;
|
||||
Vector3 lookDirGoalinHPlane;
|
||||
|
||||
float hAngle;
|
||||
float vAngle;
|
||||
float hAngleThr;
|
||||
float vAngleThr;
|
||||
|
||||
float hAngleABS;
|
||||
float vAngleABS;
|
||||
|
||||
float hAngleSign;
|
||||
float vAngleSign;
|
||||
|
||||
Vector3 referenceRightDir;
|
||||
Vector3 upDirGoal;
|
||||
Vector3 lookDir;
|
||||
Quaternion lookRot;
|
||||
Quaternion dividedRotation;
|
||||
|
||||
Quaternion finalLookRotation;
|
||||
|
||||
bool isPlayerDead;
|
||||
|
||||
Transform currentRightWeaponRotationPoint;
|
||||
Transform currentLeftWeaponRotationPoint;
|
||||
|
||||
weaponRotationPointInfo rightRotationPointInfo;
|
||||
weaponRotationPointInfo leftRotationPointInfo;
|
||||
|
||||
int currentRightRotationDirection = 1;
|
||||
int currentLeftRotationDirection = 1;
|
||||
|
||||
bool weaponRotationPointToFollowLocated;
|
||||
|
||||
float originalHorizontalBendingMultiplier;
|
||||
float originalVerticalBendingMultiplier;
|
||||
|
||||
float originalHorizontalMaxAngleDifference;
|
||||
float originalVerticalMaxAngleDifference;
|
||||
|
||||
float currentTime;
|
||||
|
||||
float currentDeltatime;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
parentRot = spineTransform.parent.rotation;
|
||||
parentRotInv = Quaternion.Inverse (parentRot);
|
||||
|
||||
referenceLookDir = parentRotInv * transform.rotation * headLookVector.normalized;
|
||||
referenceUpDir = parentRotInv * transform.rotation * headUpVector.normalized;
|
||||
dirUp = referenceUpDir;
|
||||
originalAngleDifference = maxBendingAngle;
|
||||
|
||||
weaponRotationPointToFollowLocated = weaponRotationPointToFollow != null;
|
||||
|
||||
originalHorizontalBendingMultiplier = horizontalBendingMultiplier;
|
||||
originalVerticalBendingMultiplier = verticalBendingMultiplier;
|
||||
|
||||
originalHorizontalMaxAngleDifference = horizontalMaxAngleDifference;
|
||||
originalVerticalMaxAngleDifference = verticalMaxAngleDifference;
|
||||
}
|
||||
|
||||
void FixedUpdate ()
|
||||
{
|
||||
if (IKUpperBodyActive) {
|
||||
|
||||
isPlayerDead = playerControllerManager.isPlayerDead ();
|
||||
|
||||
if (isPlayerDead) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentTime = Time.smoothDeltaTime;
|
||||
|
||||
parentRot = spineTransform.parent.rotation;
|
||||
parentRotInv = Quaternion.Inverse (parentRot);
|
||||
|
||||
// Desired look direction in world space
|
||||
if (usingTemporalObjectToFollow) {
|
||||
lookDirWorld = (temporalObjectToFollow.position - chestTransform.position).normalized;
|
||||
} else {
|
||||
lookDirWorld = (objectToFollow.position - chestTransform.position).normalized;
|
||||
}
|
||||
|
||||
// Desired look directions in neck parent space
|
||||
lookDirGoal = (parentRotInv * lookDirWorld);
|
||||
|
||||
// Get the horizontal and vertical rotation angle to look at the target
|
||||
hAngle = AngleAroundAxis (referenceLookDir, lookDirGoal, referenceUpDir);
|
||||
|
||||
rightOfTarget = Vector3.Cross (referenceUpDir, lookDirGoal);
|
||||
lookDirGoalinHPlane = lookDirGoal - Vector3.Project (lookDirGoal, referenceUpDir);
|
||||
|
||||
vAngle = AngleAroundAxis (lookDirGoalinHPlane, lookDirGoal, rightOfTarget);
|
||||
|
||||
|
||||
hAngleABS = Mathf.Abs (hAngle);
|
||||
vAngleABS = Mathf.Abs (vAngle);
|
||||
|
||||
hAngleSign = Mathf.Sign (hAngle);
|
||||
vAngleSign = Mathf.Sign (vAngle);
|
||||
|
||||
|
||||
// Handle threshold angle difference, bending multiplier, and max angle difference here
|
||||
hAngleThr = Mathf.Max (0, hAngleABS - horizontalThresholdAngleDifference) * hAngleSign;
|
||||
vAngleThr = Mathf.Max (0, vAngleABS - verticalThresholdAngleDifference) * vAngleSign;
|
||||
|
||||
hAngle = Mathf.Max (Mathf.Abs (hAngleThr) * Mathf.Abs (horizontalBendingMultiplier), hAngleABS
|
||||
- horizontalMaxAngleDifference) * hAngleSign * Mathf.Sign (horizontalBendingMultiplier);
|
||||
|
||||
vAngle = Mathf.Max (Mathf.Abs (vAngleThr) * Mathf.Abs (verticalBendingMultiplier), vAngleABS
|
||||
- verticalMaxAngleDifference) * vAngleSign * Mathf.Sign (verticalBendingMultiplier);
|
||||
|
||||
// Handle max bending angle here
|
||||
hAngle = Mathf.Clamp (hAngle, -maxBendingAngle, maxBendingAngle);
|
||||
vAngle = Mathf.Clamp (vAngle, -maxBendingAngle, maxBendingAngle);
|
||||
|
||||
referenceRightDir = Vector3.Cross (referenceUpDir, referenceLookDir);
|
||||
|
||||
// Lerp angles
|
||||
angleH = Mathf.Lerp (angleH, hAngle, currentTime * horizontalResponsiveness);
|
||||
angleV = Mathf.Lerp (angleV, vAngle, currentTime * verticalResponsiveness);
|
||||
|
||||
if (!horizontalRotationEnabled) {
|
||||
angleH = 0;
|
||||
}
|
||||
|
||||
if (!verticalRotationEnabled) {
|
||||
angleV = 0;
|
||||
}
|
||||
|
||||
// Get direction
|
||||
lookDirGoal = Quaternion.AngleAxis (angleH, referenceUpDir) *
|
||||
Quaternion.AngleAxis (angleV, referenceRightDir) *
|
||||
referenceLookDir;
|
||||
|
||||
// Make look and up perpendicular
|
||||
upDirGoal = referenceUpDir;
|
||||
Vector3.OrthoNormalize (ref lookDirGoal, ref upDirGoal);
|
||||
|
||||
// Interpolated look and up directions in neck parent space
|
||||
lookDir = lookDirGoal;
|
||||
dirUp = Vector3.Slerp (dirUp, upDirGoal, currentTime * 5);
|
||||
Vector3.OrthoNormalize (ref lookDir, ref dirUp);
|
||||
|
||||
// Look rotation in world space
|
||||
lookRot = ((parentRot * Quaternion.LookRotation (lookDir, dirUp)) *
|
||||
Quaternion.Inverse (parentRot * Quaternion.LookRotation (referenceLookDir, referenceUpDir)));
|
||||
|
||||
if (upperBodyRotationSpeed > 0) {
|
||||
finalLookRotation = Quaternion.Slerp (finalLookRotation, lookRot, currentTime * upperBodyRotationSpeed);
|
||||
} else {
|
||||
finalLookRotation = lookRot;
|
||||
}
|
||||
|
||||
// Distribute rotation over all joints in segment
|
||||
dividedRotation = Quaternion.Slerp (Quaternion.identity, finalLookRotation, 0.5f);
|
||||
|
||||
chestRotation = dividedRotation;
|
||||
spineRotation = dividedRotation;
|
||||
}
|
||||
|
||||
if (usingWeaponRotationPoint) {
|
||||
checkWeaponRotationPoint ();
|
||||
}
|
||||
}
|
||||
|
||||
void LateUpdate ()
|
||||
{
|
||||
if (IKUpperBodyActive) {
|
||||
|
||||
if (!isPlayerDead) {
|
||||
if (chestRotationEnabled) {
|
||||
chestTransform.rotation = chestRotation * chestTransform.rotation;
|
||||
}
|
||||
|
||||
if (spineRotationEnabled) {
|
||||
spineTransform.rotation = spineRotation * spineTransform.rotation;
|
||||
}
|
||||
|
||||
if (extraHorizontalRotationEnabled) {
|
||||
if (currentExtraRotation != 0) {
|
||||
extraRotation = chestUpVector * currentExtraRotation;
|
||||
|
||||
chestTransform.localEulerAngles = new Vector3 (chestTransform.localEulerAngles.x, chestTransform.localEulerAngles.y, chestTransform.localEulerAngles.z) + extraRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkWeaponRotationPoint ()
|
||||
{
|
||||
currentDeltatime = Time.smoothDeltaTime;
|
||||
|
||||
if (IKUpperBodyActive && weaponRotationPointToFollowLocated) {
|
||||
currentRotation = weaponRotationPointToFollow.localEulerAngles.x;
|
||||
|
||||
if (usingDualWeapon) {
|
||||
if (currentRightWeaponRotationPoint != null) {
|
||||
if (followFullRotationPointDirection) {
|
||||
updateFullRotationPoint (weaponRotationPointToFollow, currentRightWeaponRotationPoint,
|
||||
rightRotationPointInfo.rotationPointSpeed, currentDeltatime);
|
||||
} else {
|
||||
if (currentRotation > 180) {
|
||||
rotationXValue = (360 - currentRotation) / rightRotationPointInfo.rotationUpPointAmountMultiplier;
|
||||
|
||||
if (rightRotationPointInfo.useRotationUpClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, rightRotationPointInfo.rotationUpClampAmount);
|
||||
}
|
||||
|
||||
rotationXValue *= (-1) * currentRightRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationXValue = currentRotation / rightRotationPointInfo.rotationDownPointAmountMultiplier;
|
||||
|
||||
if (rightRotationPointInfo.useRotationDownClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, rightRotationPointInfo.rotationDownClamp);
|
||||
}
|
||||
|
||||
rotationXValue *= currentRightRotationDirection;
|
||||
}
|
||||
|
||||
Quaternion weaponRotationPointTarget = Quaternion.Euler (new Vector3 (rotationXValue, 0, 0));
|
||||
|
||||
currentRightWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentRightWeaponRotationPoint.localRotation, weaponRotationPointTarget, currentDeltatime * rightRotationPointInfo.rotationPointSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLeftWeaponRotationPoint != null) {
|
||||
if (followFullRotationPointDirection) {
|
||||
updateFullRotationPoint (weaponRotationPointToFollow, currentLeftWeaponRotationPoint,
|
||||
leftRotationPointInfo.rotationPointSpeed, currentDeltatime);
|
||||
} else {
|
||||
if (currentRotation > 180) {
|
||||
rotationXValue = (360 - currentRotation) / leftRotationPointInfo.rotationUpPointAmountMultiplier;
|
||||
|
||||
if (leftRotationPointInfo.useRotationUpClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, leftRotationPointInfo.rotationUpClampAmount);
|
||||
}
|
||||
|
||||
rotationXValue *= (-1) * currentLeftRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationXValue = currentRotation / leftRotationPointInfo.rotationDownPointAmountMultiplier;
|
||||
|
||||
if (leftRotationPointInfo.useRotationDownClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, leftRotationPointInfo.rotationDownClamp);
|
||||
}
|
||||
|
||||
rotationXValue *= currentLeftRotationDirection;
|
||||
}
|
||||
|
||||
Quaternion weaponRotationPointTarget = Quaternion.Euler (new Vector3 (rotationXValue, 0, 0));
|
||||
|
||||
currentLeftWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentLeftWeaponRotationPoint.localRotation, weaponRotationPointTarget, currentDeltatime * leftRotationPointInfo.rotationPointSpeed);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (followFullRotationPointDirection) {
|
||||
updateFullRotationPoint (weaponRotationPointToFollow, currentWeaponRotationPoint,
|
||||
rotationPointInfo.rotationPointSpeed, currentDeltatime);
|
||||
} else {
|
||||
if (currentRotation > 180) {
|
||||
rotationXValue = (360 - currentRotation) / rotationPointInfo.rotationUpPointAmountMultiplier;
|
||||
|
||||
if (rotationPointInfo.useRotationUpClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, rotationPointInfo.rotationUpClampAmount);
|
||||
}
|
||||
|
||||
rotationXValue *= (-1) * currentRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationXValue = currentRotation / rotationPointInfo.rotationDownPointAmountMultiplier;
|
||||
|
||||
if (rotationPointInfo.useRotationDownClamp) {
|
||||
rotationXValue = Mathf.Clamp (rotationXValue, 0, rotationPointInfo.rotationDownClamp);
|
||||
}
|
||||
|
||||
rotationXValue *= currentRotationDirection;
|
||||
}
|
||||
|
||||
Quaternion weaponRotationPointTarget = Quaternion.Euler (new Vector3 (rotationXValue, 0, 0));
|
||||
|
||||
currentWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentWeaponRotationPoint.localRotation, weaponRotationPointTarget, currentDeltatime * rotationPointInfo.rotationPointSpeed);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (usingDualWeapon) {
|
||||
|
||||
bool rightWeaponIsReset = false;
|
||||
bool leftWeaponIsReset = false;
|
||||
|
||||
if (currentRightWeaponRotationPoint != null) {
|
||||
if (currentRightWeaponRotationPoint.localRotation != Quaternion.identity) {
|
||||
currentRightWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentRightWeaponRotationPoint.localRotation, Quaternion.identity, currentDeltatime * rightRotationPointInfo.rotationPointSpeed);
|
||||
} else {
|
||||
rightWeaponIsReset = true;
|
||||
}
|
||||
} else {
|
||||
rightWeaponIsReset = true;
|
||||
}
|
||||
|
||||
if (currentLeftWeaponRotationPoint != null) {
|
||||
if (currentLeftWeaponRotationPoint.localRotation != Quaternion.identity) {
|
||||
currentLeftWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentLeftWeaponRotationPoint.localRotation, Quaternion.identity, currentDeltatime * leftRotationPointInfo.rotationPointSpeed);
|
||||
} else {
|
||||
leftWeaponIsReset = true;
|
||||
}
|
||||
} else {
|
||||
leftWeaponIsReset = true;
|
||||
}
|
||||
|
||||
if (rightWeaponIsReset && leftWeaponIsReset) {
|
||||
usingWeaponRotationPoint = false;
|
||||
}
|
||||
} else {
|
||||
if (currentWeaponRotationPoint != null) {
|
||||
if (currentWeaponRotationPoint.localRotation != Quaternion.identity) {
|
||||
|
||||
currentWeaponRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentWeaponRotationPoint.localRotation, Quaternion.identity, currentDeltatime * rotationPointInfo.rotationPointSpeed);
|
||||
} else {
|
||||
usingWeaponRotationPoint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateFullRotationPoint (Transform rotationPointToFollow, Transform currentRotationPoint, float rotationPointSpeed, float currentDeltatime)
|
||||
{
|
||||
Quaternion weaponRotationPointTarget = Quaternion.LookRotation (rotationPointToFollow.forward, rotationPointToFollow.up);
|
||||
|
||||
Quaternion localRotation = Quaternion.Inverse (currentRotationPoint.parent.rotation) * weaponRotationPointTarget;
|
||||
|
||||
Vector3 localRotationEuler = localRotation.eulerAngles;
|
||||
|
||||
if (useFollowFullRotationClamp) {
|
||||
float rotationClampX = localRotationEuler.x;
|
||||
|
||||
if (rotationClampX > 180) {
|
||||
rotationClampX = (360 - rotationClampX) / followFullRotationPointMultipliers.x;
|
||||
|
||||
rotationClampX = Mathf.Clamp (rotationClampX, 0, followFullRotationClampX.x);
|
||||
|
||||
rotationClampX *= (-1) * currentRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationClampX = rotationClampX / followFullRotationPointMultipliers.x;
|
||||
|
||||
rotationClampX = Mathf.Clamp (rotationClampX, 0, followFullRotationClampX.y);
|
||||
|
||||
rotationClampX *= currentRotationDirection;
|
||||
}
|
||||
|
||||
|
||||
float rotationClampY = localRotationEuler.y;
|
||||
|
||||
if (rotationClampY > 180) {
|
||||
rotationClampY = (360 - rotationClampY) / followFullRotationPointMultipliers.y;
|
||||
|
||||
rotationClampY = Mathf.Clamp (rotationClampY, 0, followFullRotationClampY.x);
|
||||
|
||||
rotationClampY *= (-1) * currentRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationClampY = rotationClampY / followFullRotationPointMultipliers.y;
|
||||
|
||||
rotationClampY = Mathf.Clamp (rotationClampY, 0, followFullRotationClampY.y);
|
||||
|
||||
rotationClampY *= currentRotationDirection;
|
||||
}
|
||||
|
||||
|
||||
float rotationClampZ = localRotationEuler.z;
|
||||
|
||||
if (rotationClampZ > 180) {
|
||||
rotationClampZ = (360 - rotationClampZ) / followFullRotationPointMultipliers.z;
|
||||
|
||||
rotationClampZ = Mathf.Clamp (rotationClampZ, 0, followFullRotationClampZ.x);
|
||||
|
||||
rotationClampZ *= (-1) * currentRotationDirection;
|
||||
|
||||
} else {
|
||||
rotationClampZ = rotationClampZ / followFullRotationPointMultipliers.z;
|
||||
|
||||
rotationClampZ = Mathf.Clamp (rotationClampZ, 0, followFullRotationClampZ.y);
|
||||
|
||||
rotationClampZ *= currentRotationDirection;
|
||||
}
|
||||
|
||||
localRotationEuler = new Vector3 (rotationClampX, rotationClampY, rotationClampZ);
|
||||
}
|
||||
|
||||
localRotation = Quaternion.Euler (localRotationEuler);
|
||||
|
||||
if (useSmoothRotationPointValue) {
|
||||
currentRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentRotationPoint.localRotation, localRotation, smoothRotationPointValue);
|
||||
} else {
|
||||
currentRotationPoint.localRotation =
|
||||
Quaternion.Lerp (currentRotationPoint.localRotation, localRotation, currentTime * rotationPointSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
// The angle between dirA and dirB around axis
|
||||
public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis)
|
||||
{
|
||||
// Project A and B onto the plane orthogonal target axis
|
||||
dirA = dirA - Vector3.Project (dirA, axis);
|
||||
dirB = dirB - Vector3.Project (dirB, axis);
|
||||
|
||||
// Find (positive) angle between A and B
|
||||
float angle = Vector3.Angle (dirA, dirB);
|
||||
return angle * (Vector3.Dot (axis, Vector3.Cross (dirA, dirB)) < 0 ? -1 : 1);
|
||||
}
|
||||
|
||||
public void setCurrentBodyRotation (float bodyRotation)
|
||||
{
|
||||
currentExtraRotation = bodyRotation;
|
||||
auxCurrentExtraRotation = currentExtraRotation;
|
||||
}
|
||||
|
||||
public void enableOrDisableIKUpperBody (bool value)
|
||||
{
|
||||
if (value) {
|
||||
IKUpperBodyActive = value;
|
||||
}
|
||||
|
||||
checkSetExtraRotationCoroutine (value);
|
||||
}
|
||||
|
||||
void checkSetExtraRotationCoroutine (bool state)
|
||||
{
|
||||
if (changeExtraRotation != null) {
|
||||
StopCoroutine (changeExtraRotation);
|
||||
}
|
||||
|
||||
if (gameObject.activeInHierarchy) {
|
||||
changeExtraRotation = StartCoroutine (setExtraRotation (state));
|
||||
} else {
|
||||
if (state) {
|
||||
maxBendingAngle = originalAngleDifference;
|
||||
} else {
|
||||
maxBendingAngle = 0;
|
||||
|
||||
IKUpperBodyActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator setExtraRotation (bool state)
|
||||
{
|
||||
for (float t = 0; t < 1;) {
|
||||
t += Time.deltaTime * rotationSpeed;
|
||||
|
||||
if (state) {
|
||||
maxBendingAngle = Mathf.Lerp (maxBendingAngle, originalAngleDifference, t);
|
||||
} else {
|
||||
maxBendingAngle = Mathf.Lerp (maxBendingAngle, 0, t);
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
IKUpperBodyActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isIKUpperBodyActive ()
|
||||
{
|
||||
return IKUpperBodyActive;
|
||||
}
|
||||
|
||||
public void checkShakeUpperBodyRotationCoroutine (float extraAngleValue, float speedValue)
|
||||
{
|
||||
if (!shakeUpperBodyEnabled || !IKUpperBodyActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopShakeUpperBodyRotation ();
|
||||
|
||||
shakeUpperBodyRotationCoroutine = StartCoroutine (shakeUpperBodyRotation (extraAngleValue, speedValue));
|
||||
}
|
||||
|
||||
public void stopShakeUpperBodyRotation ()
|
||||
{
|
||||
if (shakeUpperBodyRotationCoroutine != null) {
|
||||
StopCoroutine (shakeUpperBodyRotationCoroutine);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator shakeUpperBodyRotation (float extraAngleValue, float speedValue)
|
||||
{
|
||||
float angleTarget = auxCurrentExtraRotation + extraAngleValue;
|
||||
|
||||
for (float t = 0; t < 1;) {
|
||||
t += Time.deltaTime * speedValue;
|
||||
|
||||
currentExtraRotation = Mathf.Lerp (currentExtraRotation, angleTarget, t);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
for (float t = 0; t < 1;) {
|
||||
t += Time.deltaTime * speedValue;
|
||||
|
||||
currentExtraRotation = Mathf.Lerp (currentExtraRotation, auxCurrentExtraRotation, t);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentWeaponRotationPoint (Transform newWeaponRotationPoint, weaponRotationPointInfo newRotationPointInfo, int newRotationDirection)
|
||||
{
|
||||
currentWeaponRotationPoint = newWeaponRotationPoint;
|
||||
|
||||
rotationPointInfo = newRotationPointInfo;
|
||||
|
||||
currentRotationDirection = newRotationDirection;
|
||||
}
|
||||
|
||||
public void setUsingWeaponRotationPointState (bool state)
|
||||
{
|
||||
usingWeaponRotationPoint = state;
|
||||
}
|
||||
|
||||
public void setUsingDualWeaponState (bool state)
|
||||
{
|
||||
usingDualWeapon = state;
|
||||
}
|
||||
|
||||
public void setCurrentRightWeaponRotationPoint (Transform newWeaponRotationPoint, weaponRotationPointInfo newRotationPointInfo, int newRotationDirection)
|
||||
{
|
||||
currentRightWeaponRotationPoint = newWeaponRotationPoint;
|
||||
|
||||
rightRotationPointInfo = newRotationPointInfo;
|
||||
|
||||
currentRightRotationDirection = newRotationDirection;
|
||||
}
|
||||
|
||||
public void setCurrentLeftWeaponRotationPoint (Transform newWeaponRotationPoint, weaponRotationPointInfo newRotationPointInfo, int newRotationDirection)
|
||||
{
|
||||
currentLeftWeaponRotationPoint = newWeaponRotationPoint;
|
||||
|
||||
leftRotationPointInfo = newRotationPointInfo;
|
||||
|
||||
currentLeftRotationDirection = newRotationDirection;
|
||||
}
|
||||
|
||||
public void setTemporalObjectToFollow (Transform newObject)
|
||||
{
|
||||
temporalObjectToFollow = newObject;
|
||||
|
||||
usingTemporalObjectToFollow = temporalObjectToFollow != null;
|
||||
}
|
||||
|
||||
public void setHorizontalBendingMultiplierValue (float newValue)
|
||||
{
|
||||
horizontalBendingMultiplier = newValue;
|
||||
}
|
||||
|
||||
public void setOriginalHorizontalBendingMultiplier ()
|
||||
{
|
||||
setHorizontalBendingMultiplierValue (originalHorizontalBendingMultiplier);
|
||||
}
|
||||
|
||||
public void setVerticalBendingMultiplierValue (float newValue)
|
||||
{
|
||||
verticalBendingMultiplier = newValue;
|
||||
}
|
||||
|
||||
public void setOriginalVerticalBendingMultiplier ()
|
||||
{
|
||||
setVerticalBendingMultiplierValue (originalVerticalBendingMultiplier);
|
||||
}
|
||||
|
||||
public void setFollowFullRotationPointDirectionState (bool state)
|
||||
{
|
||||
followFullRotationPointDirection = state;
|
||||
}
|
||||
|
||||
public void setUseFollowFullRotationClampState (bool state)
|
||||
{
|
||||
useFollowFullRotationClamp = state;
|
||||
}
|
||||
|
||||
public void setNewFollowFullRotationClampX (Vector2 newFollowFullRotationClampXValues)
|
||||
{
|
||||
followFullRotationClampX = newFollowFullRotationClampXValues;
|
||||
}
|
||||
|
||||
public void setNewFollowFullRotationClampY (Vector2 newFollowFullRotationClampYValues)
|
||||
{
|
||||
followFullRotationClampY = newFollowFullRotationClampYValues;
|
||||
}
|
||||
|
||||
public void setNewFollowFullRotationClampZ (Vector2 newFollowFullRotationClampZValues)
|
||||
{
|
||||
followFullRotationClampZ = newFollowFullRotationClampZValues;
|
||||
}
|
||||
|
||||
public void setExtraHorizontalRotationEnabledState (bool state)
|
||||
{
|
||||
extraHorizontalRotationEnabled = state;
|
||||
}
|
||||
|
||||
public void setHorizontalMaxAngleDifference (float newValue)
|
||||
{
|
||||
horizontalMaxAngleDifference = newValue;
|
||||
}
|
||||
|
||||
public void setVerticalMaxAngleDifference (float newValue)
|
||||
{
|
||||
verticalMaxAngleDifference = newValue;
|
||||
}
|
||||
|
||||
public void setOriginalHorizontalMaxAngleDifference ()
|
||||
{
|
||||
setHorizontalMaxAngleDifference (originalHorizontalMaxAngleDifference);
|
||||
}
|
||||
|
||||
public void setOriginalVerticalMaxAngleDifference ()
|
||||
{
|
||||
setVerticalMaxAngleDifference (originalVerticalMaxAngleDifference);
|
||||
}
|
||||
|
||||
public void setFullBodyAwarenessActiveState (bool state)
|
||||
{
|
||||
fullBodyAwarenessActive = state;
|
||||
|
||||
if (fullBodyAwarenessActive) {
|
||||
if (currentWeaponRotationPoint != null) {
|
||||
currentWeaponRotationPoint.localRotation = Quaternion.identity;
|
||||
|
||||
usingWeaponRotationPoint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//EDITOR FUNCTIONS
|
||||
public void setNewChestUpVectorValue (Vector3 newValue)
|
||||
{
|
||||
chestUpVector = newValue;
|
||||
|
||||
updateComponent ();
|
||||
}
|
||||
|
||||
public void setSpineTransform (Transform newTransform)
|
||||
{
|
||||
spineTransform = newTransform;
|
||||
|
||||
updateComponent ();
|
||||
}
|
||||
|
||||
public void setChestTransform (Transform newTransform)
|
||||
{
|
||||
chestTransform = newTransform;
|
||||
|
||||
updateComponent ();
|
||||
}
|
||||
|
||||
public void updateComponent ()
|
||||
{
|
||||
GKC_Utils.updateComponent (this);
|
||||
|
||||
GKC_Utils.updateDirtyScene ("Update Upper Body Rotation System", gameObject);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user