add ckg
plantilla base para movimiento básico
This commit is contained in:
@@ -0,0 +1,981 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class sphereController : vehicleController
|
||||
{
|
||||
[Header ("Custom Settings")]
|
||||
[Space]
|
||||
|
||||
public otherVehicleParts vehicleParts;
|
||||
public vehicleSettings settings;
|
||||
|
||||
[Space]
|
||||
[Header ("Physics Settings")]
|
||||
[Space]
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxSpeed = 10f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxClimbSpeed = 4f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxBoostClimbSpeed = 4f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxSwimSpeed = 5f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxAcceleration = 10f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxAirAcceleration = 1f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxClimbAcceleration = 40f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxSwimAcceleration = 5f;
|
||||
|
||||
[SerializeField, Range (0, 5)]
|
||||
int maxAirJumps = 0;
|
||||
|
||||
[SerializeField, Range (0, 90)]
|
||||
float maxGroundAngle = 25f, maxStairsAngle = 50f;
|
||||
|
||||
[SerializeField, Range (90, 180)]
|
||||
float maxClimbAngle = 140f;
|
||||
|
||||
[SerializeField, Range (0f, 100f)]
|
||||
float maxSnapSpeed = 100f;
|
||||
|
||||
[SerializeField]
|
||||
float probeDistance = 1f;
|
||||
|
||||
[SerializeField]
|
||||
float submergenceOffset = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
float submergenceRange = 1f;
|
||||
|
||||
[SerializeField]
|
||||
float buoyancy = 1f;
|
||||
|
||||
[SerializeField, Range (0f, 10f)]
|
||||
float waterDrag = 1f;
|
||||
|
||||
[SerializeField, Range (0.01f, 1f)]
|
||||
float swimThreshold = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
LayerMask probeMask = -1, stairsMask = -1, climbMask = -1, waterMask = 0;
|
||||
|
||||
[SerializeField]
|
||||
float sphereRadius = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
float sphereAlignSpeed = 45;
|
||||
|
||||
[SerializeField]
|
||||
float sphereAirRotation = 0.5f;
|
||||
|
||||
[SerializeField]
|
||||
float sphereSwimRotation = 2f;
|
||||
|
||||
public bool useClimbEnabled = true;
|
||||
|
||||
[Space]
|
||||
[Header ("Debug")]
|
||||
[Space]
|
||||
|
||||
public bool anyOnGround;
|
||||
|
||||
public int stepsSinceLastJump;
|
||||
|
||||
public int climbContactCount;
|
||||
|
||||
public bool desiresClimbing;
|
||||
|
||||
public int groundContactCount;
|
||||
|
||||
public int steepContactCount;
|
||||
|
||||
public int stepsSinceLastGrounded;
|
||||
|
||||
public Vector3 velocity;
|
||||
|
||||
public Vector3 moveInput;
|
||||
|
||||
[Space]
|
||||
[Header ("Components")]
|
||||
[Space]
|
||||
|
||||
public Transform sphereTransform;
|
||||
|
||||
float originalJumpPower;
|
||||
|
||||
Transform vehicleCameraTransform;
|
||||
|
||||
Rigidbody connectedBody;
|
||||
Rigidbody previousConnectedBody;
|
||||
|
||||
Vector3 connectionVelocity;
|
||||
|
||||
Vector3 connectionWorldPosition;
|
||||
Vector3 connectionLocalPosition;
|
||||
|
||||
Vector3 upAxis, rightAxis, forwardAxis;
|
||||
|
||||
bool desiredJump;
|
||||
|
||||
Vector3 contactNormal, steepNormal, climbNormal, lastClimbNormal;
|
||||
|
||||
Vector3 lastContactNormal, lastSteepNormal, lastConnectionVelocity;
|
||||
|
||||
float submergence;
|
||||
|
||||
int jumpPhase;
|
||||
|
||||
float minGroundDotProduct, minStairsDotProduct, minClimbDotProduct;
|
||||
|
||||
|
||||
public override void Awake ()
|
||||
{
|
||||
base.Awake ();
|
||||
|
||||
OnValidate ();
|
||||
}
|
||||
|
||||
public override void Start ()
|
||||
{
|
||||
base.Start ();
|
||||
|
||||
originalJumpPower = vehicleControllerSettings.jumpPower;
|
||||
|
||||
vehicleCameraTransform = mainVehicleCameraController.transform;
|
||||
}
|
||||
|
||||
public override void vehicleUpdate ()
|
||||
{
|
||||
base.vehicleUpdate ();
|
||||
|
||||
if (isPlayerMovingOn3dWorld ()) {
|
||||
moveInput.x = horizontalAxis;
|
||||
moveInput.z = verticalAxis;
|
||||
} else {
|
||||
if (desiresClimbing) {
|
||||
moveInput.z = verticalAxis;
|
||||
|
||||
moveInput.x = 0;
|
||||
} else {
|
||||
moveInput.x = verticalAxis;
|
||||
moveInput.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
moveInput.y = 0;
|
||||
moveInput = Vector3.ClampMagnitude (moveInput, 1f);
|
||||
|
||||
if (isCameraTypeFree ()) {
|
||||
rightAxis = projectDirectionOnPlane (settings.vehicleCamera.transform.right, upAxis);
|
||||
|
||||
forwardAxis = projectDirectionOnPlane (settings.vehicleCamera.transform.forward, upAxis);
|
||||
} else {
|
||||
Transform currentLockedCameraTransform = mainVehicleCameraController.getLockedCameraTransform ();
|
||||
|
||||
if (currentLockedCameraTransform != null) {
|
||||
if (isPlayerMovingOn3dWorld ()) {
|
||||
rightAxis = projectDirectionOnPlane (currentLockedCameraTransform.right, upAxis);
|
||||
|
||||
forwardAxis = projectDirectionOnPlane (currentLockedCameraTransform.forward, upAxis);
|
||||
} else {
|
||||
rightAxis = projectDirectionOnPlane (currentLockedCameraTransform.right, upAxis);
|
||||
|
||||
forwardAxis = projectDirectionOnPlane (currentLockedCameraTransform.forward, upAxis);
|
||||
}
|
||||
} else {
|
||||
rightAxis = Vector3.zero;
|
||||
|
||||
forwardAxis = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSwimmingActive ()) {
|
||||
setDesiresClimbingState (false);
|
||||
}
|
||||
|
||||
updateSphereState ();
|
||||
}
|
||||
|
||||
void setDesiresClimbingState (bool state)
|
||||
{
|
||||
desiresClimbing = state;
|
||||
|
||||
if (desiresClimbing) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
mainVehicleGravityControl.setGravityForcePausedState (desiresClimbing);
|
||||
}
|
||||
|
||||
void FixedUpdate ()
|
||||
{
|
||||
anyOnGround = isOnGround ();
|
||||
|
||||
if (usingHoverBoardWaypoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
upAxis = mainVehicleGravityControl.getCurrentNormal ();
|
||||
|
||||
Vector3 gravity = -upAxis * mainVehicleGravityControl.getGravityForce ();
|
||||
|
||||
fixedUpdateSphereState ();
|
||||
|
||||
if (insideWater ()) {
|
||||
velocity *= 1f - waterDrag * submergence * Time.deltaTime;
|
||||
}
|
||||
|
||||
adjustVelocity ();
|
||||
|
||||
if (desiredJump) {
|
||||
desiredJump = false;
|
||||
|
||||
activeJump (gravity);
|
||||
}
|
||||
|
||||
if (isClimbingActive ()) {
|
||||
velocity -= contactNormal * (maxClimbAcceleration * 0.9f * Time.deltaTime);
|
||||
|
||||
} else if (insideWater ()) {
|
||||
velocity += gravity * ((1f - buoyancy * submergence) * Time.deltaTime);
|
||||
|
||||
} else if (isOnGround () && velocity.sqrMagnitude < 0.01f) {
|
||||
velocity += contactNormal * (Vector3.Dot (gravity, contactNormal) * Time.deltaTime);
|
||||
|
||||
} else if (desiresClimbing && isOnGround ()) {
|
||||
velocity += (gravity - contactNormal * (maxClimbAcceleration * 0.9f)) * Time.deltaTime;
|
||||
|
||||
} else {
|
||||
velocity += gravity * Time.deltaTime;
|
||||
|
||||
}
|
||||
|
||||
mainRigidbody.linearVelocity = velocity;
|
||||
|
||||
if (anyOnGround || isClimbingActive ()) {
|
||||
bool brakeActive = (braking || isBrakeActive ());
|
||||
|
||||
if (brakeActive) {
|
||||
float verticalVelocity = vehicleCameraTransform.InverseTransformDirection (mainRigidbody.linearVelocity).y;
|
||||
Vector3 downVelocity = vehicleCameraTransform.up * verticalVelocity;
|
||||
|
||||
mainRigidbody.linearVelocity = Vector3.Lerp (mainRigidbody.linearVelocity, Vector3.zero + downVelocity, Time.deltaTime * settings.brakeForce);
|
||||
}
|
||||
}
|
||||
|
||||
clearState ();
|
||||
|
||||
currentSpeed = mainRigidbody.linearVelocity.magnitude;
|
||||
}
|
||||
|
||||
void updateSphereState ()
|
||||
{
|
||||
Vector3 rotationPlaneNormal = lastContactNormal;
|
||||
|
||||
float rotationFactor = 1f;
|
||||
|
||||
if (isClimbingActive ()) {
|
||||
|
||||
} else if (isSwimmingActive ()) {
|
||||
|
||||
rotationFactor = sphereSwimRotation;
|
||||
} else if (!isOnGround ()) {
|
||||
if (isOnSteep ()) {
|
||||
rotationPlaneNormal = lastSteepNormal;
|
||||
} else {
|
||||
rotationFactor = sphereAirRotation;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 movement = (mainRigidbody.linearVelocity - lastConnectionVelocity) * Time.deltaTime;
|
||||
|
||||
movement -= rotationPlaneNormal * Vector3.Dot (movement, rotationPlaneNormal);
|
||||
|
||||
float distance = movement.magnitude;
|
||||
|
||||
Quaternion rotation = sphereTransform.localRotation;
|
||||
|
||||
if (connectedBody != null && connectedBody == previousConnectedBody) {
|
||||
rotation = Quaternion.Euler (connectedBody.angularVelocity * (Mathf.Rad2Deg * Time.deltaTime)) * rotation;
|
||||
|
||||
if (distance < 0.001f) {
|
||||
sphereTransform.localRotation = rotation;
|
||||
|
||||
return;
|
||||
}
|
||||
} else if (distance < 0.001f) {
|
||||
return;
|
||||
}
|
||||
|
||||
float angle = distance * rotationFactor * (180f / Mathf.PI) / sphereRadius;
|
||||
|
||||
Vector3 rotationAxis = Vector3.Cross (rotationPlaneNormal, movement).normalized;
|
||||
|
||||
rotation = Quaternion.Euler (rotationAxis * angle) * rotation;
|
||||
|
||||
if (sphereAlignSpeed > 0f) {
|
||||
rotation = alignSphereRotation (rotationAxis, rotation, distance);
|
||||
}
|
||||
|
||||
sphereTransform.localRotation = rotation;
|
||||
}
|
||||
|
||||
Quaternion alignSphereRotation (Vector3 rotationAxis, Quaternion rotation, float traveledDistance)
|
||||
{
|
||||
Vector3 sphereAxis = sphereTransform.up;
|
||||
|
||||
float dot = Mathf.Clamp (Vector3.Dot (sphereAxis, rotationAxis), -1f, 1f);
|
||||
|
||||
float angle = Mathf.Acos (dot) * Mathf.Rad2Deg;
|
||||
|
||||
float maxAngle = sphereAlignSpeed * traveledDistance;
|
||||
|
||||
Quaternion newAlignment = Quaternion.FromToRotation (sphereAxis, rotationAxis) * rotation;
|
||||
|
||||
if (angle <= maxAngle) {
|
||||
return newAlignment;
|
||||
} else {
|
||||
return Quaternion.SlerpUnclamped (rotation, newAlignment, maxAngle / angle);
|
||||
}
|
||||
}
|
||||
|
||||
void clearState ()
|
||||
{
|
||||
lastContactNormal = contactNormal;
|
||||
|
||||
lastSteepNormal = steepNormal;
|
||||
|
||||
lastConnectionVelocity = connectionVelocity;
|
||||
|
||||
groundContactCount = steepContactCount = climbContactCount = 0;
|
||||
|
||||
contactNormal = steepNormal = climbNormal = Vector3.zero;
|
||||
|
||||
connectionVelocity = Vector3.zero;
|
||||
|
||||
previousConnectedBody = connectedBody;
|
||||
|
||||
connectedBody = null;
|
||||
|
||||
submergence = 0f;
|
||||
}
|
||||
|
||||
void fixedUpdateSphereState ()
|
||||
{
|
||||
stepsSinceLastGrounded += 1;
|
||||
|
||||
stepsSinceLastJump += 1;
|
||||
|
||||
velocity = mainRigidbody.linearVelocity;
|
||||
|
||||
if (checkClimbing () ||
|
||||
checkSwimming () ||
|
||||
isOnGround () ||
|
||||
snapToGround () ||
|
||||
checkSteepContacts ()) {
|
||||
|
||||
stepsSinceLastGrounded = 0;
|
||||
|
||||
if (stepsSinceLastJump > 1) {
|
||||
jumpPhase = 0;
|
||||
}
|
||||
|
||||
if (groundContactCount > 1) {
|
||||
contactNormal.Normalize ();
|
||||
}
|
||||
} else {
|
||||
contactNormal = upAxis;
|
||||
}
|
||||
|
||||
if (connectedBody != null) {
|
||||
if (connectedBody.isKinematic || connectedBody.mass >= mainRigidbody.mass) {
|
||||
updateConnectionState ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateConnectionState ()
|
||||
{
|
||||
if (connectedBody == previousConnectedBody) {
|
||||
Vector3 connectionMovement = connectedBody.transform.TransformPoint (connectionLocalPosition) - connectionWorldPosition;
|
||||
|
||||
connectionVelocity = connectionMovement / Time.deltaTime;
|
||||
}
|
||||
|
||||
connectionWorldPosition = mainRigidbody.position;
|
||||
|
||||
connectionLocalPosition = connectedBody.transform.InverseTransformPoint (connectionWorldPosition);
|
||||
}
|
||||
|
||||
bool checkClimbing ()
|
||||
{
|
||||
if (isClimbingActive ()) {
|
||||
if (climbContactCount > 1) {
|
||||
climbNormal.Normalize ();
|
||||
|
||||
float upDot = Vector3.Dot (upAxis, climbNormal);
|
||||
|
||||
if (upDot >= minGroundDotProduct) {
|
||||
climbNormal = lastClimbNormal;
|
||||
}
|
||||
}
|
||||
|
||||
groundContactCount = 1;
|
||||
|
||||
contactNormal = climbNormal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkSwimming ()
|
||||
{
|
||||
if (isSwimmingActive ()) {
|
||||
groundContactCount = 0;
|
||||
|
||||
contactNormal = upAxis;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void updateMovingState ()
|
||||
{
|
||||
moving = verticalAxis != 0 || horizontalAxis != 0;
|
||||
}
|
||||
|
||||
bool snapToGround ()
|
||||
{
|
||||
if (stepsSinceLastGrounded > 1 || stepsSinceLastJump <= 2 || insideWater ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float speed = velocity.magnitude;
|
||||
|
||||
if (speed > maxSnapSpeed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RaycastHit hit;
|
||||
|
||||
if (!Physics.Raycast (mainRigidbody.position, -upAxis, out hit, probeDistance, probeMask, QueryTriggerInteraction.Ignore)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 hitNormal = hit.normal;
|
||||
|
||||
float upDot = Vector3.Dot (upAxis, hitNormal);
|
||||
|
||||
if (upDot < getMinDot (hit.collider.gameObject.layer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
groundContactCount = 1;
|
||||
|
||||
contactNormal = hitNormal;
|
||||
|
||||
float dot = Vector3.Dot (velocity, hitNormal);
|
||||
|
||||
if (dot > 0f) {
|
||||
velocity = (velocity - hitNormal * dot).normalized * speed;
|
||||
}
|
||||
|
||||
connectedBody = hit.rigidbody;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkSteepContacts ()
|
||||
{
|
||||
if (steepContactCount > 1) {
|
||||
steepNormal.Normalize ();
|
||||
|
||||
float upDot = Vector3.Dot (upAxis, steepNormal);
|
||||
|
||||
if (upDot >= minGroundDotProduct) {
|
||||
steepContactCount = 0;
|
||||
|
||||
groundContactCount = 1;
|
||||
|
||||
contactNormal = steepNormal;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void adjustVelocity ()
|
||||
{
|
||||
float acceleration, speed;
|
||||
|
||||
Vector3 xAxis, zAxis;
|
||||
|
||||
float currentMaxSpeeed = maxSpeed * boostInput;
|
||||
|
||||
if (isClimbingActive ()) {
|
||||
acceleration = maxClimbAcceleration;
|
||||
|
||||
speed = maxClimbSpeed;
|
||||
|
||||
if (usingBoost) {
|
||||
speed = maxBoostClimbSpeed;
|
||||
}
|
||||
|
||||
xAxis = Vector3.Cross (contactNormal, upAxis);
|
||||
|
||||
zAxis = upAxis;
|
||||
} else if (insideWater ()) {
|
||||
float swimFactor = Mathf.Min (1f, submergence / swimThreshold);
|
||||
|
||||
acceleration = Mathf.LerpUnclamped (isOnGround () ? maxAcceleration : maxAirAcceleration, maxSwimAcceleration, swimFactor);
|
||||
|
||||
speed = Mathf.LerpUnclamped (currentMaxSpeeed, maxSwimSpeed, swimFactor);
|
||||
|
||||
xAxis = rightAxis;
|
||||
zAxis = forwardAxis;
|
||||
} else {
|
||||
acceleration = isOnGround () ? maxAcceleration : maxAirAcceleration;
|
||||
|
||||
float currentClimbSpeed = maxClimbSpeed;
|
||||
|
||||
if (usingBoost) {
|
||||
currentClimbSpeed = maxBoostClimbSpeed;
|
||||
}
|
||||
|
||||
speed = isOnGround () && desiresClimbing ? currentClimbSpeed : currentMaxSpeeed;
|
||||
|
||||
xAxis = rightAxis;
|
||||
zAxis = forwardAxis;
|
||||
}
|
||||
|
||||
xAxis = projectDirectionOnPlane (xAxis, contactNormal);
|
||||
zAxis = projectDirectionOnPlane (zAxis, contactNormal);
|
||||
|
||||
Vector3 relativeVelocity = velocity - connectionVelocity;
|
||||
|
||||
Vector3 adjustment;
|
||||
|
||||
adjustment.x = moveInput.x * speed - Vector3.Dot (relativeVelocity, xAxis);
|
||||
adjustment.z = moveInput.z * speed - Vector3.Dot (relativeVelocity, zAxis);
|
||||
|
||||
adjustment.y = isSwimmingActive () ? moveInput.y * speed - Vector3.Dot (relativeVelocity, upAxis) : 0f;
|
||||
|
||||
adjustment = Vector3.ClampMagnitude (adjustment, acceleration * Time.deltaTime);
|
||||
|
||||
velocity += (xAxis * adjustment.x + zAxis * adjustment.z) * boostInput;
|
||||
|
||||
if (isSwimmingActive ()) {
|
||||
velocity += upAxis * adjustment.y;
|
||||
}
|
||||
}
|
||||
|
||||
bool isOnGround ()
|
||||
{
|
||||
return groundContactCount > 0;
|
||||
}
|
||||
|
||||
bool isOnSteep ()
|
||||
{
|
||||
return steepContactCount > 0;
|
||||
}
|
||||
|
||||
bool isClimbingActive ()
|
||||
{
|
||||
return climbContactCount > 0 && stepsSinceLastJump > 2;
|
||||
}
|
||||
|
||||
bool insideWater ()
|
||||
{
|
||||
return submergence > 0f;
|
||||
}
|
||||
|
||||
bool isSwimmingActive ()
|
||||
{
|
||||
return submergence >= swimThreshold;
|
||||
}
|
||||
|
||||
public void preventSnapToGround ()
|
||||
{
|
||||
stepsSinceLastJump = -1;
|
||||
}
|
||||
|
||||
void OnValidate ()
|
||||
{
|
||||
minGroundDotProduct = Mathf.Cos (maxGroundAngle * Mathf.Deg2Rad);
|
||||
|
||||
minStairsDotProduct = Mathf.Cos (maxStairsAngle * Mathf.Deg2Rad);
|
||||
|
||||
minClimbDotProduct = Mathf.Cos (maxClimbAngle * Mathf.Deg2Rad);
|
||||
}
|
||||
|
||||
void activeJump (Vector3 gravity)
|
||||
{
|
||||
Vector3 jumpDirection;
|
||||
|
||||
if (isOnGround ()) {
|
||||
jumpDirection = contactNormal;
|
||||
} else if (isOnSteep ()) {
|
||||
jumpDirection = steepNormal;
|
||||
|
||||
jumpPhase = 0;
|
||||
} else if (maxAirJumps > 0 && jumpPhase <= maxAirJumps) {
|
||||
if (jumpPhase == 0) {
|
||||
jumpPhase = 1;
|
||||
}
|
||||
jumpDirection = contactNormal;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
stepsSinceLastJump = 0;
|
||||
|
||||
jumpPhase += 1;
|
||||
|
||||
float jumpSpeed = Mathf.Sqrt (2f * gravity.magnitude * vehicleControllerSettings.jumpPower);
|
||||
|
||||
if (insideWater ()) {
|
||||
jumpSpeed *= Mathf.Max (0f, 1f - submergence / swimThreshold);
|
||||
}
|
||||
|
||||
jumpDirection = (jumpDirection + upAxis).normalized;
|
||||
|
||||
float alignedSpeed = Vector3.Dot (velocity, jumpDirection);
|
||||
|
||||
if (alignedSpeed > 0f) {
|
||||
jumpSpeed = Mathf.Max (jumpSpeed - alignedSpeed, 0f);
|
||||
}
|
||||
|
||||
velocity += jumpDirection * jumpSpeed;
|
||||
}
|
||||
|
||||
void OnCollisionEnter (Collision collision)
|
||||
{
|
||||
EvaluateCollision (collision);
|
||||
}
|
||||
|
||||
void OnCollisionStay (Collision collision)
|
||||
{
|
||||
EvaluateCollision (collision);
|
||||
}
|
||||
|
||||
void EvaluateCollision (Collision collision)
|
||||
{
|
||||
if (isSwimmingActive ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int layer = collision.gameObject.layer;
|
||||
|
||||
float minDot = getMinDot (layer);
|
||||
|
||||
for (int i = 0; i < collision.contacts.Length; i++) {
|
||||
Vector3 normal = collision.contacts [i].normal;
|
||||
|
||||
float upDot = Vector3.Dot (upAxis, normal);
|
||||
|
||||
if (upDot >= minDot) {
|
||||
groundContactCount += 1;
|
||||
|
||||
contactNormal += normal;
|
||||
|
||||
connectedBody = collision.rigidbody;
|
||||
} else {
|
||||
if (upDot > -0.01f) {
|
||||
steepContactCount += 1;
|
||||
|
||||
steepNormal += normal;
|
||||
|
||||
if (groundContactCount == 0) {
|
||||
connectedBody = collision.rigidbody;
|
||||
}
|
||||
}
|
||||
|
||||
if (desiresClimbing && upDot >= minClimbDotProduct && (climbMask & (1 << layer)) != 0) {
|
||||
|
||||
climbContactCount += 1;
|
||||
|
||||
climbNormal += normal;
|
||||
|
||||
lastClimbNormal = normal;
|
||||
|
||||
connectedBody = collision.rigidbody;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter (Collider other)
|
||||
{
|
||||
if ((waterMask & (1 << other.gameObject.layer)) != 0) {
|
||||
EvaluateSubmergence (other);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerStay (Collider other)
|
||||
{
|
||||
if ((waterMask & (1 << other.gameObject.layer)) != 0) {
|
||||
EvaluateSubmergence (other);
|
||||
}
|
||||
}
|
||||
|
||||
void EvaluateSubmergence (Collider collider)
|
||||
{
|
||||
RaycastHit hit;
|
||||
|
||||
if (Physics.Raycast (mainRigidbody.position + upAxis * submergenceOffset, -upAxis, out hit, submergenceRange + 1f, waterMask)) {
|
||||
//, QueryTriggerInteraction.Collide)) {
|
||||
submergence = 1f - hit.distance / submergenceRange;
|
||||
} else {
|
||||
submergence = 1f;
|
||||
}
|
||||
|
||||
if (isSwimmingActive ()) {
|
||||
connectedBody = collider.attachedRigidbody;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 projectDirectionOnPlane (Vector3 direction, Vector3 normal)
|
||||
{
|
||||
return (direction - normal * Vector3.Dot (direction, normal)).normalized;
|
||||
}
|
||||
|
||||
float getMinDot (int layer)
|
||||
{
|
||||
if ((stairsMask & (1 << layer)) == 0) {
|
||||
return minGroundDotProduct;
|
||||
} else {
|
||||
return minStairsDotProduct;
|
||||
}
|
||||
}
|
||||
|
||||
//if the vehicle is using the gravity control, set the state in this component
|
||||
public override void changeGravityControlUse (bool state)
|
||||
{
|
||||
base.changeGravityControlUse (state);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//the player is getting on or off from the vehicle, so
|
||||
public override void changeVehicleState ()
|
||||
{
|
||||
base.changeVehicleState ();
|
||||
|
||||
setDesiresClimbingState (false);
|
||||
}
|
||||
|
||||
public override void setTurnOnState ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void setTurnOffState (bool previouslyTurnedOn)
|
||||
{
|
||||
base.setTurnOffState (previouslyTurnedOn);
|
||||
|
||||
if (previouslyTurnedOn) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override bool isDrivingActive ()
|
||||
{
|
||||
return driving;
|
||||
}
|
||||
|
||||
public override void setEngineOnOrOffState ()
|
||||
{
|
||||
base.setEngineOnOrOffState ();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void turnOnOrOff (bool state, bool previouslyTurnedOn)
|
||||
{
|
||||
base.turnOnOrOff (state, previouslyTurnedOn);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//the vehicle has been destroyed, so disabled every component in it
|
||||
public override void disableVehicle ()
|
||||
{
|
||||
base.disableVehicle ();
|
||||
|
||||
}
|
||||
|
||||
//if the vehicle is using the boost, set the boost particles
|
||||
public override void usingBoosting ()
|
||||
{
|
||||
base.usingBoosting ();
|
||||
|
||||
}
|
||||
|
||||
//use a jump platform
|
||||
public void useVehicleJumpPlatform (Vector3 direction)
|
||||
{
|
||||
mainRigidbody.AddForce (mainRigidbody.mass * direction, ForceMode.Impulse);
|
||||
}
|
||||
|
||||
public void useJumpPlatformParable (Vector3 direction)
|
||||
{
|
||||
Vector3 jumpForce = direction;
|
||||
|
||||
mainRigidbody.AddForce (jumpForce, ForceMode.VelocityChange);
|
||||
}
|
||||
|
||||
public void setNewJumpPower (float newJumpPower)
|
||||
{
|
||||
vehicleControllerSettings.jumpPower = newJumpPower * 100;
|
||||
}
|
||||
|
||||
public void setOriginalJumpPower ()
|
||||
{
|
||||
vehicleControllerSettings.jumpPower = originalJumpPower;
|
||||
}
|
||||
|
||||
//CALL INPUT FUNCTIONS
|
||||
public override void inputJump ()
|
||||
{
|
||||
if (driving && !usingGravityControl && isTurnedOn && vehicleControllerSettings.canJump) {
|
||||
if (usingHoverBoardWaypoint) {
|
||||
pickOrReleaseHoverboardVehicle (false, false);
|
||||
|
||||
Vector3 totalJumpForce = mainRigidbody.mass * hoverboardJumpForce * (currentNormal + transform.forward);
|
||||
|
||||
if (useHoverboardJumpClamp) {
|
||||
totalJumpForce = Vector3.ClampMagnitude (totalJumpForce, hoverboardJumpClamp);
|
||||
}
|
||||
|
||||
mainRigidbody.AddForce (totalJumpForce, ForceMode.Impulse);
|
||||
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSwimmingActive ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (desiresClimbing) {
|
||||
if (!isClimbingActive ()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!anyOnGround) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setDesiresClimbingState (false);
|
||||
|
||||
desiredJump = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void inputHoldOrReleaseTurbo (bool holdingButton)
|
||||
{
|
||||
if (driving && !usingGravityControl && isTurnedOn && !usingHoverBoardWaypoint) {
|
||||
//boost input
|
||||
if (holdingButton) {
|
||||
if (vehicleControllerSettings.canUseBoost) {
|
||||
usingBoost = true;
|
||||
//set the camera move away action
|
||||
mainVehicleCameraController.usingBoost (true, vehicleControllerSettings.boostCameraShakeStateName,
|
||||
vehicleControllerSettings.useBoostCameraShake, vehicleControllerSettings.moveCameraAwayOnBoost);
|
||||
}
|
||||
} else {
|
||||
//stop boost input
|
||||
usingBoost = false;
|
||||
|
||||
//disable the camera move away action
|
||||
mainVehicleCameraController.usingBoost (false, vehicleControllerSettings.boostCameraShakeStateName,
|
||||
vehicleControllerSettings.useBoostCameraShake, vehicleControllerSettings.moveCameraAwayOnBoost);
|
||||
|
||||
usingBoosting ();
|
||||
|
||||
boostInput = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void inputHoldOrReleaseBrake (bool holdingButton)
|
||||
{
|
||||
if (driving && !usingGravityControl && isTurnedOn && anyOnGround) {
|
||||
braking = holdingButton;
|
||||
}
|
||||
}
|
||||
|
||||
public override void inputSetTurnOnState ()
|
||||
{
|
||||
if (driving && !usingGravityControl) {
|
||||
if (mainVehicleHUDManager.canSetTurnOnState) {
|
||||
setEngineOnOrOffState ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inputSetClimbState (bool state)
|
||||
{
|
||||
if (driving && !usingGravityControl && isTurnedOn) {
|
||||
if (!useClimbEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSwimmingActive ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDesiresClimbingState (state);
|
||||
|
||||
if (state) {
|
||||
if (usingBoost) {
|
||||
mainVehicleCameraController.usingBoost (false, vehicleControllerSettings.boostCameraShakeStateName,
|
||||
vehicleControllerSettings.useBoostCameraShake, vehicleControllerSettings.moveCameraAwayOnBoost);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inputToggleClimbState ()
|
||||
{
|
||||
if (driving && !usingGravityControl && isTurnedOn) {
|
||||
inputSetClimbState (!desiresClimbing);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class otherVehicleParts
|
||||
{
|
||||
public Transform COM;
|
||||
public GameObject chassis;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class vehicleSettings
|
||||
{
|
||||
public LayerMask layer;
|
||||
public GameObject vehicleCamera;
|
||||
public float brakeForce = 5;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user