122 lines
3.6 KiB
C#
122 lines
3.6 KiB
C#
//----------------------------------------------
|
|
// Realistic Car Controller
|
|
//
|
|
// Copyright © 2014 - 2023 BoneCracker Games
|
|
// https://www.bonecrackergames.com
|
|
// Buğra Özdoğanlar
|
|
//
|
|
//----------------------------------------------
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
/// <summary>
|
|
/// Rotates and moves suspension arms based on wheelcollider suspension distance.
|
|
/// </summary>
|
|
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Visual Axle (Suspension Distance Based)")]
|
|
public class RCC_SuspensionArm : MonoBehaviour {
|
|
|
|
public RCC_WheelCollider wheelcollider; // Target wheelcollider.
|
|
|
|
public SuspensionType suspensionType; // Suspension type.
|
|
public enum SuspensionType { Position, Rotation }
|
|
|
|
public Axis axis; // Axis of the rotation.
|
|
public enum Axis { X, Y, Z }
|
|
|
|
// Default position and rotation of the arm.
|
|
private Vector3 orgPos;
|
|
private Vector3 orgRot;
|
|
|
|
// Total suspension distance.
|
|
private float totalSuspensionDistance = 0;
|
|
|
|
// Offset and angle factor.
|
|
public float offsetAngle = 30;
|
|
public float angleFactor = 150;
|
|
|
|
private void Start() {
|
|
|
|
// Getting default position and rotation of the arm.
|
|
orgPos = transform.localPosition;
|
|
orgRot = transform.localEulerAngles;
|
|
|
|
// Getting suspension distance.
|
|
totalSuspensionDistance = GetSuspensionDistance();
|
|
|
|
}
|
|
|
|
private void Update() {
|
|
|
|
// If no wheelcollider found, return.
|
|
if (!wheelcollider)
|
|
return;
|
|
|
|
// If wheelcollider is not active, return.
|
|
if (!wheelcollider.gameObject.activeSelf)
|
|
return;
|
|
|
|
float suspensionCourse = GetSuspensionDistance() - totalSuspensionDistance;
|
|
|
|
// Setting position and rotation of the arm to original.
|
|
transform.localPosition = orgPos;
|
|
transform.localEulerAngles = orgRot;
|
|
|
|
// And then change position or rotation of the arm related to calculated suspension distance.
|
|
switch (suspensionType) {
|
|
|
|
case SuspensionType.Position:
|
|
|
|
switch (axis) {
|
|
|
|
case Axis.X:
|
|
transform.position += transform.right * suspensionCourse;
|
|
break;
|
|
case Axis.Y:
|
|
transform.position += transform.up * suspensionCourse;
|
|
break;
|
|
case Axis.Z:
|
|
transform.position += transform.forward * suspensionCourse;
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SuspensionType.Rotation:
|
|
|
|
switch (axis) {
|
|
|
|
case Axis.X:
|
|
transform.Rotate(Vector3.right, suspensionCourse * angleFactor - offsetAngle, Space.Self);
|
|
break;
|
|
case Axis.Y:
|
|
transform.Rotate(Vector3.up, suspensionCourse * angleFactor - offsetAngle, Space.Self);
|
|
break;
|
|
case Axis.Z:
|
|
transform.Rotate(Vector3.forward, suspensionCourse * angleFactor - offsetAngle, Space.Self);
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates suspension distance.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private float GetSuspensionDistance() {
|
|
|
|
wheelcollider.WheelCollider.GetWorldPose(out Vector3 position, out Quaternion quat);
|
|
Vector3 local = wheelcollider.transform.InverseTransformPoint(position);
|
|
return local.y;
|
|
|
|
}
|
|
|
|
}
|