Первый коммит

This commit is contained in:
2024-04-20 11:16:35 +03:00
parent 284e0891d9
commit 2452b24ee5
5427 changed files with 4562744 additions and 0 deletions

View File

@ -0,0 +1,226 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///<summary>
/// API for instantiating, registering new RCC vehicles, and changes at runtime.
///</summary>
public class RCC {
///<summary>
/// Spawn a RCC vehicle prefab with given position, rotation, sets its controllable, and engine state.
///</summary>
public static RCC_CarControllerV3 SpawnRCC(RCC_CarControllerV3 vehiclePrefab, Vector3 position, Quaternion rotation, bool registerAsPlayerVehicle, bool isControllable, bool isEngineRunning) {
RCC_CarControllerV3 spawnedRCC = (RCC_CarControllerV3)GameObject.Instantiate(vehiclePrefab, position, rotation);
spawnedRCC.gameObject.SetActive(true);
spawnedRCC.SetCanControl(isControllable);
if (registerAsPlayerVehicle)
RCC_SceneManager.Instance.RegisterPlayer(spawnedRCC);
if (isEngineRunning)
spawnedRCC.StartEngine(true);
else
spawnedRCC.KillEngine();
return spawnedRCC;
}
///<summary>
/// Registers the vehicle as player vehicle.
///</summary>
public static void RegisterPlayerVehicle(RCC_CarControllerV3 vehicle) {
RCC_SceneManager.Instance.RegisterPlayer(vehicle);
}
///<summary>
/// Registers the vehicle as player vehicle with controllable state.
///</summary>
public static void RegisterPlayerVehicle(RCC_CarControllerV3 vehicle, bool isControllable) {
RCC_SceneManager.Instance.RegisterPlayer(vehicle, isControllable);
}
///<summary>
/// Registers the vehicle as player vehicle with controllable and engine state.
///</summary>
public static void RegisterPlayerVehicle(RCC_CarControllerV3 vehicle, bool isControllable, bool engineState) {
RCC_SceneManager.Instance.RegisterPlayer(vehicle, isControllable, engineState);
}
///<summary>
/// De-Registers the player vehicle.
///</summary>
public static void DeRegisterPlayerVehicle() {
RCC_SceneManager.Instance.DeRegisterPlayer();
}
///<summary>
/// Sets controllable state of the vehicle.
///</summary>
public static void SetControl(RCC_CarControllerV3 vehicle, bool isControllable) {
vehicle.SetCanControl(isControllable);
}
///<summary>
/// Sets engine state of the vehicle.
///</summary>
public static void SetEngine(RCC_CarControllerV3 vehicle, bool engineState) {
if (engineState)
vehicle.StartEngine();
else
vehicle.KillEngine();
}
///<summary>
/// Sets the mobile controller type.
///</summary>
public static void SetMobileController(RCC_Settings.MobileController mobileController) {
RCC_Settings.Instance.mobileController = mobileController;
Debug.Log("Mobile Controller has been changed to " + mobileController.ToString());
}
///<summary>
/// Sets the units.
///</summary>
public static void SetUnits() { }
///<summary>
/// Sets the Automatic Gear.
///</summary>
public static void SetAutomaticGear() { }
///<summary>
/// Starts / stops to record the player vehicle.
///</summary>
public static void StartStopRecord() {
RCC_SceneManager.Instance.Record();
}
///<summary>
/// Start / stops replay of the last record.
///</summary>
public static void StartStopReplay() {
RCC_SceneManager.Instance.Play();
}
///<summary>
/// Stops record / replay of the last record.
///</summary>
public static void StopRecordReplay() {
RCC_SceneManager.Instance.Stop();
}
///<summary>
/// Sets new behavior.
///</summary>
public static void SetBehavior(int behaviorIndex) {
RCC_SceneManager.Instance.SetBehavior(behaviorIndex);
Debug.Log("Behavior has been changed to " + behaviorIndex.ToString());
}
/// <summary>
/// Changes the camera mode.
/// </summary>
public static void ChangeCamera() {
RCC_SceneManager.Instance.ChangeCamera();
}
/// <summary>
/// Transport player vehicle the specified position and rotation.
/// </summary>
/// <param name="position">Position.</param>
/// <param name="rotation">Rotation.</param>
public static void Transport(Vector3 position, Quaternion rotation) {
RCC_SceneManager.Instance.Transport(position, rotation);
}
/// <summary>
/// Transport the target vehicle to specified position and rotation.
/// </summary>
/// <param name="vehicle"></param>
/// <param name="position"></param>
/// <param name="rotation"></param>
public static void Transport(RCC_CarControllerV3 vehicle, Vector3 position, Quaternion rotation) {
RCC_SceneManager.Instance.Transport(vehicle, position, rotation);
}
/// <summary>
/// Cleans all skidmarks on the current scene.
/// </summary>
public static void CleanSkidmarks() {
RCC_SkidmarksManager.Instance.CleanSkidmarks();
}
/// <summary>
/// Cleans target skidmarks on the current scene.
/// </summary>
public static void CleanSkidmarks(int index) {
RCC_SkidmarksManager.Instance.CleanSkidmarks(index);
}
/// <summary>
/// Repairs the target vehicle.
/// </summary>
/// <param name="carController"></param>
public static void Repair(RCC_CarControllerV3 carController) {
carController.damage.repairNow = true;
}
/// <summary>
/// Repairs the player vehicle.
/// </summary>
public static void Repair() {
RCC_CarControllerV3 carController = RCC_SceneManager.Instance.activePlayerVehicle;
if (!carController)
carController.damage.repairNow = true;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dec7f534be3fc544eb1a084c41f72e9f
timeCreated: 1511617544
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,23 @@
//----------------------------------------------
// 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>
/// Brake Zones are meant to be used for slowing AI vehicles. If you have a sharp turn on your scene, you can simply use one of these Brake Zones. It has a target speed. AI will adapt its speed to this target speed while in this Brake Zone. It's simple.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/AI/RCC AI Brake Zone")]
public class RCC_AIBrakeZone : MonoBehaviour {
public float targetSpeed = 50;
public float distance = 100f;
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7f3c2217fbfb5bb42bfcb71512f1e30d
timeCreated: 1437565475
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
//----------------------------------------------
// 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>
/// Used for holding a list for brake zones, and drawing gizmos for all of them.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/AI/RCC AI Brake Zones Container")]
public class RCC_AIBrakeZonesContainer : MonoBehaviour {
public List<Transform> brakeZones = new List<Transform>(); // Brake Zones list.
private void Awake() {
// Changing all layers to ignore raycasts to prevent lens flare occlusion.
foreach (var item in brakeZones)
item.gameObject.layer = LayerMask.NameToLayer("Ignore Raycast");
}
/// <summary>
/// Used for drawing gizmos on Editor.
/// </summary>
private void OnDrawGizmos() {
for (int i = 0; i < brakeZones.Count; i++) {
Gizmos.matrix = brakeZones[i].transform.localToWorldMatrix;
Gizmos.color = new Color(1f, 0f, 0f, .25f);
Vector3 colliderBounds = brakeZones[i].GetComponent<BoxCollider>().size;
Gizmos.DrawCube(Vector3.zero, colliderBounds);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9c2bc58c9c7eeb34298e2b02c795a05d
timeCreated: 1437775041
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,716 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.AI;
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// AI Controller of RCC. It's not professional, but it does the job. Follows all waypoints, or follows/chases the target gameobject.
/// </summary>
[RequireComponent(typeof(RCC_CarControllerV3))]
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/AI/RCC AI Car Controller")]
public class RCC_AICarController : MonoBehaviour {
// Car controller.
public RCC_CarControllerV3 CarController {
get {
if (_carController == null)
_carController = GetComponentInParent<RCC_CarControllerV3>();
return _carController;
}
}
private RCC_CarControllerV3 _carController;
public RCC_AIWaypointsContainer waypointsContainer; // Waypoints Container.
public int currentWaypointIndex = 0; // Current index in Waypoint Container.
public string targetTag = "Player"; // Search and chase Gameobjects with tags.
// AI Type
public NavigationMode navigationMode = NavigationMode.FollowWaypoints;
public enum NavigationMode { FollowWaypoints, ChaseTarget, FollowTarget }
// Raycast distances used for detecting obstacles at front of the AI vehicle.
[Range(5f, 30f)] public float raycastLength = 3f;
[Range(10f, 90f)] public float raycastAngle = 30f;
public LayerMask obstacleLayers = -1;
public GameObject obstacle;
public bool useRaycasts = true; // Using forward and sideways raycasts to avoid obstacles.
private float rayInput = 0f; // Total ray input affected by raycast distances.
private bool raycasting = false; // Raycasts hits an obstacle now?
private float resetTime = 0f; // This timer was used for deciding go back or not, after crashing.
private bool reversingNow = false; // Reversing now?
// Steer, Motor, And Brake inputs. Will feed RCC_CarController with these inputs.
public float steerInput = 0f;
public float throttleInput = 0f;
public float brakeInput = 0f;
public float handbrakeInput = 0f;
// Limit speed.
public bool limitSpeed = false;
public float maximumSpeed = 100f;
// Smoothed steering.
public bool smoothedSteer = true;
// Counts laps and how many waypoints were passed.
public int lap = 0;
public bool stopAfterLap = false;
public int stopLap = 10;
public int totalWaypointPassed = 0;
public bool ignoreWaypointNow = false;
// Detector radius.
public int detectorRadius = 200;
public int startFollowDistance = 300;
public int stopFollowDistance = 30;
private bool updateTargets = false;
private float lastUpdatedTargets = 0f;
// Unity's Navigator.
private NavMeshAgent navigator;
// Detector with Sphere Collider. Used for finding target Gameobjects in chasing mode.
public List<Transform> targetsInZone = new List<Transform>();
public List<RCC_AIBrakeZone> brakeZones = new List<RCC_AIBrakeZone>();
public Transform targetChase; // Target Gameobject for chasing.
public RCC_AIBrakeZone targetBrake; // Target brakezone.
// Firing an event when each RCC AI vehicle spawned / enabled.
public delegate void onRCCAISpawned(RCC_AICarController RCCAI);
public static event onRCCAISpawned OnRCCAISpawned;
// Firing an event when each RCC AI vehicle disabled / destroyed.
public delegate void onRCCAIDestroyed(RCC_AICarController RCCAI);
public static event onRCCAIDestroyed OnRCCAIDestroyed;
private void Awake() {
// If Waypoints Container is not selected in Inspector Panel, find it on scene.
if (!waypointsContainer)
waypointsContainer = FindObjectOfType(typeof(RCC_AIWaypointsContainer)) as RCC_AIWaypointsContainer;
// Creating our Navigator and setting properties.
GameObject navigatorObject = new GameObject("Navigator");
navigatorObject.transform.SetParent(transform, false);
navigator = navigatorObject.AddComponent<NavMeshAgent>();
navigator.radius = 1;
navigator.speed = 1;
navigator.angularSpeed = 100000f;
navigator.acceleration = 100000f;
navigator.height = 1;
navigator.avoidancePriority = 0;
}
private void OnEnable() {
// Setting external controller on enable.
CarController.externalController = true;
// Calling this event when AI vehicle spawned.
if (OnRCCAISpawned != null)
OnRCCAISpawned(this);
}
private void Update() {
// If not controllable, no need to go further.
if (!CarController.canControl)
return;
// If limit speed is not enabled, maximum speed is same with vehicle's maximum speed.
if (!limitSpeed)
maximumSpeed = CarController.maxspeed;
// Assigning navigator's position to front wheels of the vehicle
navigator.transform.localPosition = Vector3.zero;
navigator.transform.localPosition += Vector3.forward * CarController.FrontLeftWheelCollider.transform.localPosition.z;
CheckTargets(); // Checking targets if navigation mode is set to chase or follow target mode.
CheckBrakeZones(); // Checking existing brake zones in the scene.
if (!updateTargets)
lastUpdatedTargets += Time.deltaTime;
if (lastUpdatedTargets >= 1f)
updateTargets = true;
}
private void FixedUpdate() {
// If not controllable, no need to go further.
if (!CarController.canControl)
return;
// If enabled, raycasts will be used to avoid obstacles at runtime.
if (useRaycasts)
FixedRaycasts(); // Recalculates steerInput if one of raycasts detects an object front of AI vehicle.
Navigation(); // Calculates steerInput based on navigator.
CheckReset(); // Used for deciding go back or not after crashing.
FeedRCC(); // Feeds inputs of the RCC.
}
private void Navigation() {
// Navigator Input is multiplied by 1.5f for fast reactions.
float navigatorInput = Mathf.Clamp(transform.InverseTransformDirection(navigator.desiredVelocity).x * 1f, -1f, 1f);
if (navigatorInput > .4f)
navigatorInput = 1f;
if (navigatorInput < -.4f)
navigatorInput = -1f;
// Navigation has three modes.
switch (navigationMode) {
case NavigationMode.FollowWaypoints:
// If our scene doesn't have a Waypoint Container, stop and return with error.
if (!waypointsContainer) {
Debug.LogError("Waypoints Container Couldn't Found!");
Stop();
return;
}
// If our scene has Waypoints Container and it doesn't have any waypoints, stop and return with error.
if (waypointsContainer && waypointsContainer.waypoints.Count < 1) {
Debug.LogError("Waypoints Container Doesn't Have Any Waypoints!");
Stop();
return;
}
// If stop after lap is enabled, stop at target lap.
if (stopAfterLap && lap >= stopLap) {
Stop();
return;
}
// Next waypoint and its position.
RCC_Waypoint currentWaypoint = waypointsContainer.waypoints[currentWaypointIndex];
// Checks for the distance to next waypoint. If it is less than written value, then pass to next waypoint.
float distanceToNextWaypoint = Vector3.Distance(transform.position, currentWaypoint.transform.position);
// Setting destination of the Navigator.
if (navigator.isOnNavMesh)
navigator.SetDestination(waypointsContainer.waypoints[currentWaypointIndex].transform.position);
// If distance to the next waypoint is not 0, and close enough to the vehicle, increase index of the current waypoint and total waypoint.
if (distanceToNextWaypoint != 0 && distanceToNextWaypoint < waypointsContainer.waypoints[currentWaypointIndex].radius) {
currentWaypointIndex++;
totalWaypointPassed++;
// If all waypoints were passed, sets the current waypoint to first waypoint and increase lap.
if (currentWaypointIndex >= waypointsContainer.waypoints.Count) {
currentWaypointIndex = 0;
lap++;
}
// Setting destination of the Navigator.
if (navigator.isOnNavMesh)
navigator.SetDestination(waypointsContainer.waypoints[currentWaypointIndex].transform.position);
}
// If vehicle goes forward, calculate throttle and brake inputs.
if (!reversingNow) {
throttleInput = (distanceToNextWaypoint < (waypointsContainer.waypoints[currentWaypointIndex].radius * (CarController.speed / 30f))) ? (Mathf.Clamp01(currentWaypoint.targetSpeed - CarController.speed)) : 1f;
throttleInput *= Mathf.Clamp01(Mathf.Lerp(10f, 0f, (CarController.speed) / maximumSpeed));
brakeInput = (distanceToNextWaypoint < (waypointsContainer.waypoints[currentWaypointIndex].radius * (CarController.speed / 30f))) ? (Mathf.Clamp01(CarController.speed - currentWaypoint.targetSpeed)) : 0f;
handbrakeInput = 0f;
// If vehicle speed is high enough, calculate them related to navigator input. This will reduce throttle input, and increase brake input on sharp turns.
if (CarController.speed > 30f) {
throttleInput -= Mathf.Abs(navigatorInput) / 3f;
brakeInput += Mathf.Abs(navigatorInput) / 3f;
}
}
break;
case NavigationMode.ChaseTarget:
// If our scene doesn't have a target to chase, stop and return.
if (!targetChase) {
Stop();
return;
}
// Setting destination of the Navigator.
if (navigator.isOnNavMesh)
navigator.SetDestination(targetChase.position);
// If vehicle goes forward, calculate throttle and brake inputs.
if (!reversingNow) {
throttleInput = 1f;
throttleInput *= Mathf.Clamp01(Mathf.Lerp(10f, 0f, (CarController.speed) / maximumSpeed));
brakeInput = 0f;
handbrakeInput = 0f;
// If vehicle speed is high enough, calculate them related to navigator input. This will reduce throttle input, and increase brake input on sharp turns.
if (CarController.speed > 30f) {
throttleInput -= Mathf.Abs(navigatorInput) / 3f;
brakeInput += Mathf.Abs(navigatorInput) / 3f;
}
}
break;
case NavigationMode.FollowTarget:
// If our scene doesn't have a Waypoints Container, return with error.
if (!targetChase) {
Stop();
return;
}
// Setting destination of the Navigator.
if (navigator.isOnNavMesh)
navigator.SetDestination(targetChase.position);
// Checks for the distance to target.
float distanceToTarget = Vector3.Distance(transform.position, targetChase.position);
// If vehicle goes forward, calculate throttle and brake inputs.
if (!reversingNow) {
throttleInput = distanceToTarget < (stopFollowDistance * Mathf.Lerp(1f, 5f, CarController.speed / 50f)) ? Mathf.Lerp(-5f, 1f, distanceToTarget / (stopFollowDistance / 1f)) : 1f;
throttleInput *= Mathf.Clamp01(Mathf.Lerp(10f, 0f, (CarController.speed) / maximumSpeed));
brakeInput = distanceToTarget < (stopFollowDistance * Mathf.Lerp(1f, 5f, CarController.speed / 50f)) ? Mathf.Lerp(5f, 0f, distanceToTarget / (stopFollowDistance / 1f)) : 0f;
handbrakeInput = 0f;
// If vehicle speed is high enough, calculate them related to navigator input. This will reduce throttle input, and increase brake input on sharp turns.
if (CarController.speed > 30f) {
throttleInput -= Mathf.Abs(navigatorInput) / 3f;
brakeInput += Mathf.Abs(navigatorInput) / 3f;
}
if (throttleInput < .05f)
throttleInput = 0f;
if (brakeInput < .05f)
brakeInput = 0f;
}
break;
}
// If vehicle is in brake zone, apply brake input.
if (targetBrake) {
// If vehicle is in brake zone and speed of the vehicle is higher than the target speed, apply brake input.
if (Vector3.Distance(transform.position, targetBrake.transform.position) < targetBrake.distance && CarController.speed > targetBrake.targetSpeed) {
throttleInput = 0f;
brakeInput = 1f;
}
}
if (brakeInput > .25f)
throttleInput = 0f;
// Steer input.
steerInput = (ignoreWaypointNow ? rayInput : navigatorInput + rayInput);
steerInput = Mathf.Clamp(steerInput, -1f, 1f) * CarController.direction;
// Clamping inputs.
throttleInput = Mathf.Clamp01(throttleInput);
brakeInput = Mathf.Clamp01(brakeInput);
handbrakeInput = Mathf.Clamp01(handbrakeInput);
// If vehicle goes backwards, set brake input to 1 for reversing.
if (reversingNow) {
throttleInput = 0f;
brakeInput = 1f;
handbrakeInput = 0f;
} else {
if (CarController.speed < 5f && brakeInput >= .5f) {
brakeInput = 0f;
handbrakeInput = 1f;
}
}
}
/// <summary>
/// Vehicle will try to go backwards if crashed or stucked.
/// </summary>
private void CheckReset() {
// If navigation mode is set to follow, this means vehicle may stop. If vehicle is stopped near the target, no need to go backwards.
if (targetChase && navigationMode == NavigationMode.FollowTarget && Vector3.Distance(transform.position, targetChase.position) < stopFollowDistance) {
reversingNow = false;
resetTime = 0;
return;
}
// If unable to move forward, puts the gear to R.
if (CarController.speed <= 5 && transform.InverseTransformDirection(CarController.Rigid.velocity).z <= 1f)
resetTime += Time.deltaTime;
// If car is stucked for 2 seconds, reverse now.
if (resetTime >= 2)
reversingNow = true;
// If car is stucked for 4 seconds, or speed exceeds 25, go forward.
if (resetTime >= 4 || CarController.speed >= 25) {
reversingNow = false;
resetTime = 0;
}
}
/// <summary>
/// Using raycasts to avoid obstacles.
/// </summary>
private void FixedRaycasts() {
// Creating five raycasts with angles.
int[] anglesOfRaycasts = new int[5];
anglesOfRaycasts[0] = 0;
anglesOfRaycasts[1] = Mathf.FloorToInt(raycastAngle / 3f);
anglesOfRaycasts[2] = Mathf.FloorToInt(raycastAngle / 1f);
anglesOfRaycasts[3] = -Mathf.FloorToInt(raycastAngle / 1f);
anglesOfRaycasts[4] = -Mathf.FloorToInt(raycastAngle / 3f);
// Ray pivot position.
Vector3 pivotPos = transform.position;
pivotPos += transform.forward * CarController.FrontLeftWheelCollider.transform.localPosition.z;
// Ray hit.
RaycastHit hit;
rayInput = 0f;
bool casted = false;
// Casting rays.
for (int i = 0; i < anglesOfRaycasts.Length; i++) {
// Drawing normal gizmos.
Debug.DrawRay(pivotPos, Quaternion.AngleAxis(anglesOfRaycasts[i], transform.up) * transform.forward * raycastLength, Color.white);
// Casting the ray. If ray hits another obstacle...
if (Physics.Raycast(pivotPos, Quaternion.AngleAxis(anglesOfRaycasts[i], transform.up) * transform.forward, out hit, raycastLength, obstacleLayers) && !hit.collider.isTrigger && hit.transform.root != transform) {
switch (navigationMode) {
case NavigationMode.FollowWaypoints:
// Drawing hit gizmos.
Debug.DrawRay(pivotPos, Quaternion.AngleAxis(anglesOfRaycasts[i], transform.up) * transform.forward * raycastLength, Color.red);
casted = true;
// Setting ray input related to distance to the obstacle.
if (i != 0)
rayInput -= Mathf.Lerp(Mathf.Sign(anglesOfRaycasts[i]), 0f, (hit.distance / raycastLength));
break;
case NavigationMode.ChaseTarget:
if (targetChase && hit.transform != targetChase && !hit.transform.IsChildOf(targetChase)) {
// Drawing hit gizmos.
Debug.DrawRay(pivotPos, Quaternion.AngleAxis(anglesOfRaycasts[i], transform.up) * transform.forward * raycastLength, Color.red);
casted = true;
// Setting ray input related to distance to the obstacle.
if (i != 0)
rayInput -= Mathf.Lerp(Mathf.Sign(anglesOfRaycasts[i]), 0f, (hit.distance / raycastLength));
}
break;
case NavigationMode.FollowTarget:
// Drawing hit gizmos.
Debug.DrawRay(pivotPos, Quaternion.AngleAxis(anglesOfRaycasts[i], transform.up) * transform.forward * raycastLength, Color.red);
casted = true;
// Setting ray input related to distance to the obstacle.
if (i != 0)
rayInput -= Mathf.Lerp(Mathf.Sign(anglesOfRaycasts[i]), 0f, (hit.distance / raycastLength));
break;
}
// If ray hits an obstacle, set obstacle. Otherwise set it to null.
if (casted)
obstacle = hit.transform.gameObject;
else
obstacle = null;
}
}
// Ray hits an obstacle or not?
raycasting = casted;
// If so, clamp the ray input.
rayInput = Mathf.Clamp(rayInput, -1f, 1f);
// If ray input is high enough, ignore the navigator input and directly use the ray input for steering.
if (raycasting && Mathf.Abs(rayInput) > .5f)
ignoreWaypointNow = true;
else
ignoreWaypointNow = false;
}
/// <summary>
/// Feeding the RCC with throttle, brake, steer, and handbrake inputs.
/// </summary>
private void FeedRCC() {
// Feeding throttleInput of the RCC.
if (!CarController.changingGear && !CarController.cutGas)
CarController.throttleInput = (CarController.direction == 1 ? Mathf.Clamp01(throttleInput) : Mathf.Clamp01(brakeInput));
else
CarController.throttleInput = 0f;
if (!CarController.changingGear && !CarController.cutGas)
CarController.brakeInput = (CarController.direction == 1 ? Mathf.Clamp01(brakeInput) : Mathf.Clamp01(throttleInput));
else
CarController.brakeInput = 0f;
// Feeding steerInput of the RCC.
if (smoothedSteer)
CarController.steerInput = Mathf.Lerp(CarController.steerInput, steerInput, Time.deltaTime * 20f);
else
CarController.steerInput = steerInput;
CarController.handbrakeInput = handbrakeInput;
}
/// <summary>
/// Stops the vehicle immediately.
/// </summary>
private void Stop() {
throttleInput = 0f;
brakeInput = 0f;
steerInput = 0f;
handbrakeInput = 1f;
}
/// <summary>
/// Checks the near targets if navigation mode is set to follow or chase mode.
/// </summary>
private void CheckTargets() {
if (!updateTargets)
return;
updateTargets = false;
lastUpdatedTargets = 0f;
Collider[] colliders = Physics.OverlapSphere(transform.position, detectorRadius);
for (int i = 0; i < colliders.Length; i++) {
// If a target in the zone, add it to the list.
if (colliders[i].transform.root.CompareTag(targetTag)) {
if (!targetsInZone.Contains(colliders[i].transform.root))
targetsInZone.Add(colliders[i].transform.root);
}
// If a brake zone in the zone, add it to the list.
if (colliders[i].GetComponent<RCC_AIBrakeZone>()) {
if (!brakeZones.Contains(colliders[i].GetComponent<RCC_AIBrakeZone>()))
brakeZones.Add(colliders[i].GetComponent<RCC_AIBrakeZone>());
}
}
// Removing unnecessary targets in list first. If target is null or not active, remove it from the list.
for (int i = 0; i < targetsInZone.Count; i++) {
if (targetsInZone[i] == null)
targetsInZone.RemoveAt(i);
if (!targetsInZone[i].gameObject.activeInHierarchy)
targetsInZone.RemoveAt(i);
else {
// If distance to the target is far away, remove it from the list.
if (Vector3.Distance(transform.position, targetsInZone[i].transform.position) > (detectorRadius * 1.1f))
targetsInZone.RemoveAt(i);
}
}
// If there is a target in the zone, get closest enemy.
if (targetsInZone.Count > 0)
targetChase = GetClosestEnemy(targetsInZone.ToArray());
else
targetChase = null;
}
/// <summary>
/// Checks the brake zones.
/// </summary>
private void CheckBrakeZones() {
// Removing unnecessary brake zones in list. If brake zone is null or not active, remove it from the list.
for (int i = 0; i < brakeZones.Count; i++) {
if (brakeZones[i] == null)
brakeZones.RemoveAt(i);
if (!brakeZones[i].gameObject.activeInHierarchy)
brakeZones.RemoveAt(i);
else {
// If distance to the brake zone is far away, remove it from the list.
if (Vector3.Distance(transform.position, brakeZones[i].transform.position) > (detectorRadius * 1.1f))
brakeZones.RemoveAt(i);
}
}
// If there is a brake zone, get closest one.
if (brakeZones.Count > 0)
targetBrake = GetClosestBrakeZone(brakeZones.ToArray());
else
targetBrake = null;
}
/// <summary>
/// Gets the closest enemy.
/// </summary>
/// <param name="enemies"></param>
/// <returns></returns>
private Transform GetClosestEnemy(Transform[] enemies) {
Transform bestTarget = null;
float closestDistanceSqr = Mathf.Infinity;
Vector3 currentPosition = transform.position;
foreach (Transform potentialTarget in enemies) {
Vector3 directionToTarget = potentialTarget.position - currentPosition;
float dSqrToTarget = directionToTarget.sqrMagnitude;
if (dSqrToTarget < closestDistanceSqr) {
closestDistanceSqr = dSqrToTarget;
bestTarget = potentialTarget;
}
}
return bestTarget;
}
/// <summary>
/// Gets the closest brake zone.
/// </summary>
/// <param name="enemies"></param>
/// <returns></returns>
private RCC_AIBrakeZone GetClosestBrakeZone(RCC_AIBrakeZone[] enemies) {
RCC_AIBrakeZone bestTarget = null;
float closestDistanceSqr = Mathf.Infinity;
Vector3 currentPosition = transform.position;
foreach (RCC_AIBrakeZone potentialTarget in enemies) {
Vector3 directionToTarget = potentialTarget.transform.position - currentPosition;
float dSqrToTarget = directionToTarget.sqrMagnitude;
if (dSqrToTarget < closestDistanceSqr) {
closestDistanceSqr = dSqrToTarget;
bestTarget = potentialTarget;
}
}
return bestTarget;
}
private void OnDisable() {
// Disabling external controller of the vehicle on disable.
CarController.externalController = false;
// Calling this event when AI vehicle is destroyed.
if (OnRCCAIDestroyed != null)
OnRCCAIDestroyed(this);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 93dcd0266b466224f8d1d8ae405f4d73
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,114 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// RCC All In One playable demo scene manager.
/// </summary>
public class RCC_AIO : MonoBehaviour {
// Instance of the script.
private static RCC_AIO instance;
public GameObject levels; // Levels menu.
public GameObject photonLevels; // Photon levels menu.
public GameObject BCGLevels; // Enter exit levels menu.
public GameObject back; //Back button.
private AsyncOperation async; //Async.
public Slider slider; // Loading slider.
private void Start() {
// Getting instance. If same exists, destroy it.
if (instance) {
Destroy(gameObject);
return;
} else {
instance = this;
DontDestroyOnLoad(gameObject);
}
#if !RCC_PHOTON
Toggle[] pbuttons = photonLevels.GetComponentsInChildren<Toggle>();
foreach (var button in pbuttons)
button.interactable = false;
#endif
#if !BCG_ENTEREXIT
Toggle[] bbuttons = BCGLevels.GetComponentsInChildren<Toggle>();
foreach (var button in bbuttons)
button.interactable = false;
#endif
}
private void Update() {
// If level load is in progress, enable and adjust loading slider. Otherwise, disable it.
if (async != null && !async.isDone) {
if (!slider.gameObject.activeSelf)
slider.gameObject.SetActive(true);
slider.value = async.progress;
} else {
if (slider.gameObject.activeSelf)
slider.gameObject.SetActive(false);
}
}
/// <summary>
/// Loads the target level.
/// </summary>
/// <param name="levelName">Level name.</param>
public void LoadLevel(string levelName) {
async = SceneManager.LoadSceneAsync(levelName, LoadSceneMode.Single);
}
/// <summary>
/// Toggles the UI menu.
/// </summary>
/// <param name="menu">Menu.</param>
public void ToggleMenu(GameObject menu) {
levels.SetActive(false);
back.SetActive(false);
menu.SetActive(true);
}
/// <summary>
/// Closes application.
/// </summary>
public void Quit() {
Application.Quit();
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c434bd80684e08e42875240351f8d25d
timeCreated: 1523968883
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,73 @@
//----------------------------------------------
// 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;
using System.Linq;
/// <summary>
/// Used for holding a list for waypoints, and drawing gizmos for all of them.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/AI/RCC AI Waypoints Container")]
public class RCC_AIWaypointsContainer : MonoBehaviour {
public List<RCC_Waypoint> waypoints = new List<RCC_Waypoint>(); // All waypoints.
private void Start() {
RCC_Waypoint[] childWaypoints = GetComponentsInChildren<RCC_Waypoint>();
waypoints = childWaypoints.ToList();
}
/// <summary>
/// Used for drawing gizmos on Editor.
/// </summary>
private void OnDrawGizmos() {
// If waypoints list is null, return.
if (waypoints == null)
return;
// Counting all waypoints.
for (int i = 0; i < waypoints.Count; i++) {
// If current waypoint is not null, continue.
if (waypoints[i] != null) {
// Drawing gizmos.
Gizmos.color = new Color(0.0f, 1.0f, 1.0f, 0.3f);
Gizmos.DrawSphere(waypoints[i].transform.position, 2);
Gizmos.DrawWireSphere(waypoints[i].transform.position, waypoints[i].radius);
// If current waypoint is not last waypoint...
if (i < waypoints.Count - 1) {
// if current waypoint has next waypoint...
if (waypoints[i] && waypoints[i + 1]) {
Gizmos.color = Color.green;
if (i < waypoints.Count - 1)
Gizmos.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position);
if (i < waypoints.Count - 2)
Gizmos.DrawLine(waypoints[waypoints.Count - 1].transform.position, waypoints[0].transform.position);
}
}
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ab5524b2342312d4f8db4668effe1306
timeCreated: 1437565430
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,79 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///<summary>
/// An example script to show how the RCC API works.
///</summary>
public class RCC_APIExample : MonoBehaviour {
public RCC_CarControllerV3 spawnVehiclePrefab; // Vehicle prefab we gonna spawn.
private RCC_CarControllerV3 currentVehiclePrefab; // Spawned vehicle.
public Transform spawnTransform; // Spawn transform.
public bool playerVehicle; // Spawn as a player vehicle?
public bool controllable; // Spawn as controllable vehicle?
public bool engineRunning; // Spawn with running engine?
/// <summary>
/// Spawning the vehicle with given settings.
/// </summary>
public void Spawn() {
// Spawning the vehicle with given settings.
currentVehiclePrefab = RCC.SpawnRCC(spawnVehiclePrefab, spawnTransform.position, spawnTransform.rotation, playerVehicle, controllable, engineRunning);
}
/// <summary>
/// Sets the player vehicle.
/// </summary>
public void SetPlayer() {
// Registers the vehicle as player vehicle.
RCC.RegisterPlayerVehicle(currentVehiclePrefab);
}
/// <summary>
/// Sets controllable state of the player vehicle.
/// </summary>
/// <param name="control"></param>
public void SetControl(bool control) {
// Enables / disables controllable state of the vehicle.
RCC.SetControl(currentVehiclePrefab, control);
}
/// <summary>
/// Sets the engine state of the player vehicle.
/// </summary>
/// <param name="engine"></param>
public void SetEngine(bool engine) {
// Starts / kills engine of the vehicle.
RCC.SetEngine(currentVehiclePrefab, engine);
}
/// <summary>
/// Deregisters the player vehicle.
/// </summary>
public void DeRegisterPlayer() {
// Deregisters the vehicle from as player vehicle.
RCC.DeRegisterPlayerVehicle();
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f7c5a9a38dbb3b0429683770769ac1f7
timeCreated: 1511620450
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,68 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Paths of the projects, links, and assets.
/// </summary>
public class RCC_AssetPaths {
public const string BCGSharedAssetsPath = "Assets/RealisticCarControllerV3/Addon Packages/For BCG Shared Assets (Enter-Exit)/BCG Shared Assets.unitypackage";
public const string PUN2AssetsPath = "Assets/RealisticCarControllerV3/Addon Packages/For Photon PUN 2/Photon PUN 2 Scripts and Photon Vehicles.unitypackage";
public const string ProFlareAssetsPath = "Assets/RealisticCarControllerV3/Addon Packages/For ProFlares/Pro Flares Integration.unitypackage";
public const string LogiAssetsPath = "Assets/RealisticCarControllerV3/Addon Packages/For Logitech Steering Wheel/Logitech Integration.unitypackage";
public const string projectSettingsPath = "Assets/RealisticCarControllerV3/Addon Packages/Project Settings/RCC_ProjectSettings.unitypackage";
public const string editorPreferences = "Assets/RealisticCarControllerV3/Editor/RCC_Preferences.asset";
public const string inputsPath = "RCC_InputActions";
public const string assetStorePath = "https://assetstore.unity.com/packages/tools/physics/realistic-car-controller-16296#content";
public const string photonPUN2 = "https://assetstore.unity.com/packages/tools/network/pun-2-free-119922";
public const string logitech = "https://assetstore.unity.com/packages/tools/integration/logitech-gaming-sdk-6630";
public const string proFlares = "https://assetstore.unity.com/packages/tools/particles-effects/proflares-ultimate-lens-flares-for-unity3d-12845";
public const string documentations = "https://www.bonecrackergames.com/bonecrackergames.com/admin/AssetStoreDocs/RCC_Documentations.rar";
public const string YTVideos = "https://www.youtube.com/playlist?list=PLRXTqAVrLDpoW58lKf8XA1AWD6kDkoKb1";
public const string otherAssets = "https://assetstore.unity.com/publishers/5425";
public const string demo_AIO = "Assets/RealisticCarControllerV3/Demo Scenes/RCC City AIO.unity";
public const string demo_City = "Assets/RealisticCarControllerV3/Demo Scenes/RCC City.unity";
public const string demo_CarSelection = "Assets/RealisticCarControllerV3/Demo Scenes/RCC City (Car Selection).unity";
public const string demo_CarSelectionLoadNextScene = "Assets/RealisticCarControllerV3/Demo Scenes/RCC City (Car Selection with Load Next Scene).unity";
public const string demo_CarSelectionLoadedScene = "Assets/RealisticCarControllerV3/Demo Scenes/RCC City (Car Selection with Loaded Scene).unity";
public const string demo_OverrideInputs = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Blank Override Inputs Scene.unity";
public const string demo_Customization = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Blank Customization Scene.unity";
public const string demo_APIBlank = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Blank API Test Scene.unity";
public const string demo_BlankMobile = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Blank Test Scene.unity";
public const string demo_Damage = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Damage Test Scene.unity";
public const string demo_MultipleTerrain = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Multiple Terrain Test Scene.unity";
public const string demo_CityFPS = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Enter Exit Scenes/RCC City (Enter-Exit FPS).unity";
public const string demo_CityTPS = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Enter Exit Scenes/RCC City (Enter-Exit TPS).unity";
public const string demo_PUN2Lobby = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Photon Scenes/RCC Lobby (Photon PUN2).unity";
public const string demo_PUN2City = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Photon Scenes/RCC City (Photon PUN2).unity";
public const string demo_PUN2CityEnterExit = "Assets/RealisticCarControllerV3/Demo Scenes/RCC Photon Scenes/RCC City Enter Exit FPS (Photon PUN2).unity";
public readonly static string[] demoAssetPaths = new string[]{
"Assets/RealisticCarControllerV3/Models",
"Assets/RealisticCarControllerV3/Demo Scenes",
"Assets/RealisticCarControllerV3/Textures/City Textures",
"Assets/RealisticCarControllerV3/Textures/Vehicle Textures",
"Assets/RealisticCarControllerV3/Prefabs/Demo Vehicles",
"Assets/RealisticCarControllerV3/Resources/Changable Wheels",
"Assets/RealisticCarControllerV3/Resources/Photon Vehicles"
};
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bfc45fe2f86bcc246be789c1e89e81c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,67 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Rotates the brake caliper.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Visual Brake Caliper")]
public class RCC_Caliper : MonoBehaviour {
public RCC_WheelCollider wheelCollider; // Actual WheelCollider.
private GameObject newPivot; // Creating new center pivot for correct position.
private Quaternion defLocalRotation; // Default local rotation.
private void Awake() {
// No need to go further if no wheelcollider found.
if (!wheelCollider) {
Debug.LogError("WheelCollider is not selected for this caliper named " + transform.name);
enabled = false;
return;
}
// Creating new center pivot for correct position.
newPivot = new GameObject("Pivot_" + transform.name);
newPivot.transform.SetParent(wheelCollider.WheelCollider.transform, false);
transform.SetParent(newPivot.transform, true);
// Assigning default rotation.
defLocalRotation = newPivot.transform.localRotation;
}
private void LateUpdate() {
// No need to go further if no wheelcollider or no wheelmodel found.
if (!wheelCollider.wheelModel || !wheelCollider.WheelCollider)
return;
// Left or right side?
int side = 1;
// If left side...
if (wheelCollider.transform.localPosition.x < 0)
side = -1;
// Re-positioning camber pivot.
newPivot.transform.position = wheelCollider.wheelPosition;
newPivot.transform.localPosition += Vector3.up * wheelCollider.WheelCollider.suspensionDistance / 2f;
// Re-rotationing camber pivot.
newPivot.transform.localRotation = defLocalRotation * Quaternion.Euler(wheelCollider.caster * side, wheelCollider.WheelCollider.steerAngle, wheelCollider.camber * side);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ea4288f07c3e8e544a77f2b9b4fb4b66
timeCreated: 1507399781
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c260b9344a9770347934a90c90132918
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,113 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
/// <summary>
/// Showroom camera while selecting the vehicles.
/// </summary>
public class RCC_CameraCarSelection : MonoBehaviour {
public Transform target; // Camera target.
public float distance = 10.0f; // Distance to the target.
public float xSpeed = 250f; // X speed of the camera.
public float ySpeed = 120f; // Y speed of the camera.
public float yMinLimit = -20f; // Minimum Y angle of the camera.
public float yMaxLimit = 80f; // Maximum Y angle of the camera.
private float x = 0f; // Current X input.
private float y = 0f; // Current Y input.
private bool selfTurn = true; // Camera should turn around the target?
private float selfTurnTime = 0f;
private void Start() {
// Getting initial X and Y angles.
x = transform.eulerAngles.y;
y = transform.eulerAngles.x;
}
private void LateUpdate() {
// If there is no target, return.
if (!target)
return;
// If self turn is enabled, increase X related to time with multiplier.
if (selfTurn)
x += xSpeed / 2f * Time.deltaTime;
// Clamping Y angle.
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
Vector3 position = rotation * new Vector3(0f, 0f, -distance) + target.position;
// Setting position and rotation of the camera.
transform.SetPositionAndRotation(position, rotation);
// Increasing self turn time with time.deltatime.
if (selfTurnTime <= 1f)
selfTurnTime += Time.deltaTime;
if (selfTurnTime >= 1f)
selfTurn = true;
}
/// <summary>
/// Clamping angle.
/// </summary>
/// <param name="angle"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
private float ClampAngle(float angle, float min, float max) {
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
/// <summary>
/// When player uses UI drag to rotate the camera.
/// </summary>
/// <param name="data"></param>
public void OnDrag(BaseEventData data) {
PointerEventData pointerData = data as PointerEventData;
x += pointerData.delta.x * xSpeed * 0.02f;
y -= pointerData.delta.y * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(y, x, 0);
Vector3 position = rotation * new Vector3(0f, 0f, -distance) + target.position;
transform.SetPositionAndRotation(position, rotation);
selfTurn = false;
selfTurnTime = 0f;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 59dd0be47aef4e24e9117d5f6df1d7f9
timeCreated: 1512392770
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c25271813931d814680ab7c84ef90710
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,184 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// A simple example manager for how the car selection scene works.
/// </summary>
public class RCC_CarSelectionExample : MonoBehaviour {
private List<RCC_CarControllerV3> _spawnedVehicles = new List<RCC_CarControllerV3>(); // Our spawned vehicle list. No need to instantiate same vehicles over and over again.
public Transform spawnPosition; // Spawn transform.
public int selectedIndex = 0; // Selected vehicle index. Next and previous buttons are affecting this value.
public RCC_Camera RCCCamera; // Enabling / disabling camera selection script on RCC Camera if choosen.
public string nextScene; // Name of the target scene when we select the vehicle.
private void Start() {
// Getting RCC Camera.
if (!RCCCamera)
RCCCamera = RCC_SceneManager.Instance.activePlayerCamera;
// First, we are instantiating all vehicles and store them in _spawnedVehicles list.
CreateVehicles();
}
/// <summary>
/// Creating all vehicles at once.
/// </summary>
private void CreateVehicles() {
for (int i = 0; i < RCC_DemoVehicles.Instance.vehicles.Length; i++) {
// Spawning the vehicle with no controllable, no player, and engine off. We don't want to let player control the vehicle while in selection menu.
RCC_CarControllerV3 spawnedVehicle = RCC.SpawnRCC(RCC_DemoVehicles.Instance.vehicles[i], spawnPosition.position, spawnPosition.rotation, false, false, false);
// Disabling spawned vehicle.
spawnedVehicle.gameObject.SetActive(false);
// Adding and storing it in _spawnedVehicles list.
_spawnedVehicles.Add(spawnedVehicle);
}
SpawnVehicle();
// If RCC Camera is choosen, it wil enable RCC_CameraCarSelection script. This script was used for orbiting camera.
if (RCCCamera) {
if (RCCCamera.GetComponent<RCC_CameraCarSelection>())
RCCCamera.GetComponent<RCC_CameraCarSelection>().enabled = true;
}
}
/// <summary>
/// Increasing selected index, disabling all other vehicles, enabling current selected vehicle.
/// </summary>
public void NextVehicle() {
selectedIndex++;
// If index exceeds maximum, return to 0.
if (selectedIndex > _spawnedVehicles.Count - 1)
selectedIndex = 0;
SpawnVehicle();
}
/// <summary>
/// Decreasing selected index, disabling all other vehicles, enabling current selected vehicle.
/// </summary>
public void PreviousVehicle() {
selectedIndex--;
// If index is below 0, return to maximum.
if (selectedIndex < 0)
selectedIndex = _spawnedVehicles.Count - 1;
SpawnVehicle();
}
/// <summary>
/// Spawns the current selected vehicle.
/// </summary>
public void SpawnVehicle() {
// Disabling all vehicles.
for (int i = 0; i < _spawnedVehicles.Count; i++)
_spawnedVehicles[i].gameObject.SetActive(false);
// And enabling only selected vehicle.
_spawnedVehicles[selectedIndex].gameObject.SetActive(true);
RCC_SceneManager.Instance.activePlayerVehicle = _spawnedVehicles[selectedIndex];
}
/// <summary>
/// Registering the spawned vehicle as player vehicle, enabling controllable.
/// </summary>
public void SelectVehicle() {
// Registers the vehicle as player vehicle.
RCC.RegisterPlayerVehicle(_spawnedVehicles[selectedIndex]);
// Starts engine and enabling controllable when selected.
_spawnedVehicles[selectedIndex].StartEngine();
_spawnedVehicles[selectedIndex].SetCanControl(true);
// Save the selected vehicle for instantianting it on next scene.
PlayerPrefs.SetInt("SelectedRCCVehicle", selectedIndex);
// If RCC Camera is choosen, it will disable RCC_CameraCarSelection script. This script was used for orbiting camera.
if (RCCCamera) {
if (RCCCamera.GetComponent<RCC_CameraCarSelection>())
RCCCamera.GetComponent<RCC_CameraCarSelection>().enabled = false;
}
if (!string.IsNullOrEmpty(nextScene))
OpenScene();
}
/// <summary>
/// Deactivates selected vehicle and returns to the car selection.
/// </summary>
public void DeSelectVehicle() {
// De-registers the vehicle.
RCC.DeRegisterPlayerVehicle();
// Resets position and rotation.
_spawnedVehicles[selectedIndex].transform.position = spawnPosition.position;
_spawnedVehicles[selectedIndex].transform.rotation = spawnPosition.rotation;
// Kills engine and disables controllable.
_spawnedVehicles[selectedIndex].KillEngine();
_spawnedVehicles[selectedIndex].SetCanControl(false);
// Resets the velocity of the vehicle.
_spawnedVehicles[selectedIndex].GetComponent<Rigidbody>().ResetInertiaTensor();
_spawnedVehicles[selectedIndex].GetComponent<Rigidbody>().velocity = Vector3.zero;
_spawnedVehicles[selectedIndex].GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
// If RCC Camera is choosen, it wil enable RCC_CameraCarSelection script. This script was used for orbiting camera.
if (RCCCamera) {
if (RCCCamera.GetComponent<RCC_CameraCarSelection>())
RCCCamera.GetComponent<RCC_CameraCarSelection>().enabled = true;
}
}
/// <summary>
/// Loads the target scene.
/// </summary>
public void OpenScene() {
// Loads next scene.
SceneManager.LoadScene(nextScene);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3527a50da896fcf4c8078f912b0e569f
timeCreated: 1514506080
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
//----------------------------------------------
// 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>
/// Changes wheels at runtime. It holds changable wheels as prefab in an array.
/// </summary>
[System.Serializable]
public class RCC_ChangableWheels : ScriptableObject {
#region singleton
private static RCC_ChangableWheels instance;
public static RCC_ChangableWheels Instance { get { if (instance == null) instance = Resources.Load("RCC Assets/RCC_ChangableWheels") as RCC_ChangableWheels; return instance; } }
#endregion
[System.Serializable]
public class ChangableWheels {
public GameObject wheel;
}
public ChangableWheels[] wheels;
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 970691d06b945c24b8c66a63db94e31b
timeCreated: 1457867857
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,111 @@
//----------------------------------------------
// 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>
/// Animates Driver Sofie (Credits to 3DMaesen). Simply feeds floats and bools of Sofie's animator component.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Animator Controller")]
public class RCC_CharacterController : MonoBehaviour {
// Car controller.
public RCC_CarControllerV3 CarController {
get {
if (_carController == null)
_carController = GetComponentInParent<RCC_CarControllerV3>();
return _carController;
}
}
private RCC_CarControllerV3 _carController;
// Animator.
public Animator animator;
// String parameters of animator.
public string driverSteeringParameter;
public string driverShiftingGearParameter;
public string driverDangerParameter;
public string driverReversingParameter;
// Inputs for feeding animator.
public float steerInput = 0f;
public float directionInput = 0f;
public bool reversing = false;
public float impactInput = 0f;
public float gearInput = 0f;
private void Update() {
// Getting steer input.
steerInput = Mathf.Lerp(steerInput, CarController.steerInput, Time.deltaTime * 5f);
directionInput = CarController.transform.InverseTransformDirection(CarController.Rigid.velocity).z;
impactInput -= Time.deltaTime * 5f;
// Clamping impact input.
if (impactInput < 0)
impactInput = 0f;
if (impactInput > 1)
impactInput = 1f;
// If vehicle is going backwards or not.
if (directionInput <= -2f)
reversing = true;
else if (directionInput > -1f)
reversing = false;
// If changing gear.
if (CarController.changingGear)
gearInput = 1f;
else
gearInput -= Time.deltaTime * 5f;
// Clamping gear input.
if (gearInput < 0)
gearInput = 0f;
if (gearInput > 1)
gearInput = 1f;
// If reversing.
if (!reversing)
animator.SetBool(driverReversingParameter, false);
else
animator.SetBool(driverReversingParameter, true);
// If impact is high enough, animate collision animation by setting bool.
if (impactInput > .5f)
animator.SetBool(driverDangerParameter, true);
else
animator.SetBool(driverDangerParameter, false);
// If changing gear, animate change gear animation by setting bool.
if (gearInput > .5f)
animator.SetBool(driverShiftingGearParameter, true);
else
animator.SetBool(driverShiftingGearParameter, false);
// Setting steer input of the animator by setting float.
animator.SetFloat(driverSteeringParameter, steerInput);
}
private void OnCollisionEnter(Collision col) {
// If collision is not high enough, return.
if (col.relativeVelocity.magnitude < 2.5f)
return;
// Setting impact to 1 on collisions.
impactInput = 1f;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4524a01d9615771478418d3e824f1ecd
timeCreated: 1437410100
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,245 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Checks the overall setup and configuration of the vehicle.
/// </summary>
public class RCC_CheckUp {
/// <summary>
/// Gets all mesh colliders with trigger enabled.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static MeshCollider[] GetTriggerMeshColliders(GameObject vehicle) {
MeshCollider[] meshcolliders = vehicle.GetComponentsInChildren<MeshCollider>(true);
List<MeshCollider> triggers = new List<MeshCollider>();
for (int i = 0; i < meshcolliders.Length; i++) {
if (meshcolliders[i].isTrigger == true)
triggers.Add(meshcolliders[i]);
}
return triggers.ToArray();
}
/// <summary>
/// Gets all colliders.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static Collider[] GetColliders(GameObject vehicle) {
Collider[] colliders = vehicle.GetComponentsInChildren<Collider>(true);
List<Collider> coll = new List<Collider>();
for (int i = 0; i < colliders.Length; i++)
coll.Add(colliders[i]);
return coll.ToArray();
}
/// <summary>
/// Vehicle has a collider or not?
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static bool HaveCollider(GameObject vehicle) {
Collider[] colliders = vehicle.GetComponentsInChildren<Collider>(true);
List<Collider> coll = new List<Collider>();
for (int i = 0; i < colliders.Length; i++) {
if (colliders[i].enabled && colliders[i].GetType() != typeof(WheelCollider))
coll.Add(colliders[i]);
}
if (coll.Count >= 1)
return true;
else
return false;
}
/// <summary>
/// Gets all rigidbodies.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static Rigidbody[] GetRigids(GameObject vehicle) {
Rigidbody[] rigidbodies = vehicle.GetComponentsInChildren<Rigidbody>(true);
List<Rigidbody> rigids = new List<Rigidbody>();
for (int i = 0; i < rigidbodies.Length; i++) {
if (rigidbodies[i] != vehicle.GetComponent<Rigidbody>() && rigidbodies[i].GetComponent<RCC_HoodCamera>() == null && rigidbodies[i].GetComponent<RCC_WheelCamera>() == null && rigidbodies[i] != vehicle.GetComponent<RCC_DetachablePart>())
rigids.Add(rigidbodies[i]);
}
return rigids.ToArray();
}
/// <summary>
/// Gets all wheelcolliders.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static WheelCollider[] GetWheelColliders(GameObject vehicle) {
WheelCollider[] wheelColliders = vehicle.GetComponentsInChildren<WheelCollider>(true);
List<WheelCollider> wheels = new List<WheelCollider>();
for (int i = 0; i < wheelColliders.Length; i++) {
if (wheelColliders[i].radius == 0 || wheelColliders[i].suspensionDistance <= 0.01)
wheels.Add(wheelColliders[i]);
}
return wheels.ToArray();
}
/// <summary>
/// Gets all sphere colliders.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static SphereCollider[] GetSphereColliders(GameObject vehicle) {
SphereCollider[] sphereColliders = vehicle.GetComponentsInChildren<SphereCollider>(true);
List<SphereCollider> spheres = new List<SphereCollider>();
for (int i = 0; i < sphereColliders.Length; i++) {
if (sphereColliders[i].enabled)
spheres.Add(sphereColliders[i]);
}
return spheres.ToArray();
}
/// <summary>
/// Checks incorrect configurations.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static string[] IncorrectConfiguration(RCC_CarControllerV3 vehicle) {
float minEngineRPM = vehicle.minEngineRPM;
float maxEngineRPM = vehicle.maxEngineRPM;
float gearDownRPM = vehicle.gearShiftDownRPM;
float gearUpRPM = vehicle.gearShiftUpRPM;
List<string> errorMessages = new List<string>();
if (minEngineRPM >= maxEngineRPM)
errorMessages.Add("Min engine rpm must be lower than max engine rpm!");
if (maxEngineRPM <= minEngineRPM)
errorMessages.Add("Max engine rpm must be higher than min engine rpm!");
if (gearDownRPM >= gearUpRPM)
errorMessages.Add("Gear shift down rpm must be lower than gear shift up rpm!");
if (gearUpRPM <= gearDownRPM)
errorMessages.Add("Gear shift up rpm must be higher than gear shift down rpm!");
if (gearDownRPM <= minEngineRPM)
errorMessages.Add("Gear shift down rpm must be higher than min engine rpm!");
if (gearUpRPM >= maxEngineRPM)
errorMessages.Add("Gear shift up rpm must be lower than max engine rpm!");
if ((Mathf.Abs(maxEngineRPM) - Mathf.Abs(minEngineRPM)) < 3000f)
errorMessages.Add("Max and min engine rpms are too close to each other!");
if ((Mathf.Abs(gearUpRPM) - Mathf.Abs(gearDownRPM)) < 1000f)
errorMessages.Add("Gear shift up and down rpms are too close to each other!");
return errorMessages.ToArray();
}
/// <summary>
/// Checks meshes with wrong axes.
/// </summary>
/// <param name="vehicle"></param>
/// <param name="meshes"></param>
/// <returns></returns>
public static bool HaveWrongAxis(GameObject vehicle, MeshFilter[] meshes) {
for (int i = 0; i < meshes.Length; i++) {
if (meshes[i]) {
if (1 - Mathf.Abs(Quaternion.Dot(meshes[i].transform.rotation, vehicle.transform.rotation)) > .01f)
return true;
}
}
return false;
}
/// <summary>
/// Checks the wheel configuration.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static bool[] HaveWrongOverride(RCC_CarControllerV3 vehicle) {
RCC_WheelCollider[] allWheels = vehicle.GetComponentsInChildren<RCC_WheelCollider>(true);
bool powerFound = false;
bool steerFound = false;
bool brakeFround = false;
bool ebrakeFound = false;
for (int i = 0; i < allWheels.Length; i++) {
if (allWheels[i].canPower)
powerFound = true;
if (allWheels[i].canSteer)
steerFound = true;
if (allWheels[i].canBrake)
brakeFround = true;
if (allWheels[i].canHandbrake)
ebrakeFound = true;
}
bool[] found = { powerFound, steerFound, brakeFround, ebrakeFound };
return found;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e9913d6f13b760a4b90d0c8b74dfa6d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,66 @@
//----------------------------------------------
// 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>
/// Tracks the player vehicle and keeps orientation nicely for cinematic angles. It has a pivot gameobject named "Animation Pivot". This pivot gameobject has 3 animations itself.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Camera/RCC Cinematic Camera")]
public class RCC_CinematicCamera : RCC_Singleton<RCC_CinematicCamera> {
public GameObject pivot; // Animation Pivot.
private Vector3 targetPosition; // Target position for tracking.
public float targetFOV = 60f; // Target field of view.
private void Start() {
// If pivot is not selected in the Inspector Panel, create it.
if (!pivot) {
pivot = new GameObject("Pivot");
pivot.transform.SetParent(transform);
pivot.transform.localPosition = Vector3.zero;
pivot.transform.localRotation = Quaternion.identity;
}
}
private void Update() {
// If current camera is null, return.
if (!RCC_SceneManager.Instance.activePlayerCamera)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget == null)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle == null)
return;
Transform target = RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle.transform;
// Rotates smoothly towards to vehicle.
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(transform.eulerAngles.x, target.eulerAngles.y + 180f, transform.eulerAngles.z), Time.deltaTime * 3f);
// Calculating target position.
targetPosition = target.position;
targetPosition -= transform.rotation * Vector3.forward * 10f;
// Assigning transform.position to targetPosition.
transform.position = targetPosition;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b3114d680cf22e54da110807ceaeebe6
timeCreated: 1479217270
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,33 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// Color Picker with UI Sliders.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC Color Picker By UI Sliders")]
public class RCC_ColorPickerBySliders : MonoBehaviour {
public Color color; // Main color.
// Sliders per color channel.
public Slider redSlider;
public Slider greenSlider;
public Slider blueSlider;
private void Update() {
// Assigning new color to main color.
color = new Color(redSlider.value, greenSlider.value, blueSlider.value);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0357d8b11b6651c4c8146491eb5ce0ec
timeCreated: 1506125162
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,488 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
public class RCC_Core : MonoBehaviour {
#region Create AudioSource
/// <summary>
/// Creates new audiosource with specified settings.
/// </summary>
public static AudioSource NewAudioSource(AudioMixerGroup audioMixer, GameObject go, string audioName, float minDistance, float maxDistance, float volume, AudioClip audioClip, bool loop, bool playNow, bool destroyAfterFinished) {
GameObject audioSourceObject = new GameObject(audioName);
if (go.transform.Find("All Audio Sources")) {
audioSourceObject.transform.SetParent(go.transform.Find("All Audio Sources"));
} else {
GameObject allAudioSources = new GameObject("All Audio Sources");
allAudioSources.transform.SetParent(go.transform, false);
audioSourceObject.transform.SetParent(allAudioSources.transform, false);
}
audioSourceObject.transform.SetPositionAndRotation(go.transform.position, go.transform.rotation);
audioSourceObject.AddComponent<AudioSource>();
AudioSource source = audioSourceObject.GetComponent<AudioSource>();
if (audioMixer)
source.outputAudioMixerGroup = audioMixer;
//audioSource.GetComponent<AudioSource>().priority =1;
source.minDistance = minDistance;
source.maxDistance = maxDistance;
source.volume = volume;
source.clip = audioClip;
source.loop = loop;
source.dopplerLevel = .5f;
source.ignoreListenerPause = false;
source.ignoreListenerVolume = false;
if (minDistance == 0 && maxDistance == 0)
source.spatialBlend = 0f;
else
source.spatialBlend = 1f;
if (playNow) {
source.playOnAwake = true;
source.Play();
} else {
source.playOnAwake = false;
}
if (destroyAfterFinished) {
if (audioClip)
Destroy(audioSourceObject, audioClip.length);
else
Destroy(audioSourceObject);
}
return source;
}
/// <summary>
/// Creates new audiosource with specified settings.
/// </summary>
public static AudioSource NewAudioSource(GameObject go, string audioName, float minDistance, float maxDistance, float volume, AudioClip audioClip, bool loop, bool playNow, bool destroyAfterFinished) {
GameObject audioSourceObject = new GameObject(audioName);
if (go.transform.Find("All Audio Sources")) {
audioSourceObject.transform.SetParent(go.transform.Find("All Audio Sources"));
} else {
GameObject allAudioSources = new GameObject("All Audio Sources");
allAudioSources.transform.SetParent(go.transform, false);
audioSourceObject.transform.SetParent(allAudioSources.transform, false);
}
audioSourceObject.transform.SetPositionAndRotation(go.transform.position, go.transform.rotation);
audioSourceObject.AddComponent<AudioSource>();
AudioSource source = audioSourceObject.GetComponent<AudioSource>();
//audioSource.GetComponent<AudioSource>().priority =1;
source.minDistance = minDistance;
source.maxDistance = maxDistance;
source.volume = volume;
source.clip = audioClip;
source.loop = loop;
source.dopplerLevel = .5f;
if (minDistance == 0 && maxDistance == 0)
source.spatialBlend = 0f;
else
source.spatialBlend = 1f;
if (playNow) {
source.playOnAwake = true;
source.Play();
} else {
source.playOnAwake = false;
}
if (destroyAfterFinished) {
if (audioClip)
Destroy(audioSourceObject, audioClip.length);
else
Destroy(audioSourceObject);
}
return source;
}
/// <summary>
/// Creates new audiosource with specified settings.
/// </summary>
public static AudioSource NewAudioSource(AudioMixerGroup audioMixer, GameObject go, Vector3 localPosition, string audioName, float minDistance, float maxDistance, float volume, AudioClip audioClip, bool loop, bool playNow, bool destroyAfterFinished) {
GameObject audioSourceObject = new GameObject(audioName);
if (go.transform.Find("All Audio Sources")) {
audioSourceObject.transform.SetParent(go.transform.Find("All Audio Sources"));
} else {
GameObject allAudioSources = new GameObject("All Audio Sources");
allAudioSources.transform.SetParent(go.transform, false);
audioSourceObject.transform.SetParent(allAudioSources.transform, false);
}
audioSourceObject.transform.SetPositionAndRotation(go.transform.position, go.transform.rotation);
audioSourceObject.transform.localPosition = localPosition;
audioSourceObject.AddComponent<AudioSource>();
AudioSource source = audioSourceObject.GetComponent<AudioSource>();
if (audioMixer)
source.outputAudioMixerGroup = audioMixer;
//audioSource.GetComponent<AudioSource>().priority =1;
source.minDistance = minDistance;
source.maxDistance = maxDistance;
source.volume = volume;
source.clip = audioClip;
source.loop = loop;
source.dopplerLevel = .5f;
if (minDistance == 0 && maxDistance == 0)
source.spatialBlend = 0f;
else
source.spatialBlend = 1f;
if (playNow) {
source.playOnAwake = true;
source.Play();
} else {
source.playOnAwake = false;
}
if (destroyAfterFinished) {
if (audioClip)
Destroy(audioSourceObject, audioClip.length);
else
Destroy(audioSourceObject);
}
return source;
}
/// <summary>
/// Creates new audiosource with specified settings.
/// </summary>
public static AudioSource NewAudioSource(GameObject go, Vector3 localPosition, string audioName, float minDistance, float maxDistance, float volume, AudioClip audioClip, bool loop, bool playNow, bool destroyAfterFinished) {
GameObject audioSourceObject = new GameObject(audioName);
if (go.transform.Find("All Audio Sources")) {
audioSourceObject.transform.SetParent(go.transform.Find("All Audio Sources"));
} else {
GameObject allAudioSources = new GameObject("All Audio Sources");
allAudioSources.transform.SetParent(go.transform, false);
audioSourceObject.transform.SetParent(allAudioSources.transform, false);
}
audioSourceObject.transform.SetPositionAndRotation(go.transform.position, go.transform.rotation);
audioSourceObject.transform.localPosition = localPosition;
audioSourceObject.AddComponent<AudioSource>();
AudioSource source = audioSourceObject.GetComponent<AudioSource>();
//audioSource.GetComponent<AudioSource>().priority =1;
source.minDistance = minDistance;
source.maxDistance = maxDistance;
source.volume = volume;
source.clip = audioClip;
source.loop = loop;
source.dopplerLevel = .5f;
if (minDistance == 0 && maxDistance == 0)
source.spatialBlend = 0f;
else
source.spatialBlend = 1f;
if (playNow) {
source.playOnAwake = true;
source.Play();
} else {
source.playOnAwake = false;
}
if (destroyAfterFinished) {
if (audioClip)
Destroy(audioSourceObject, audioClip.length);
else
Destroy(audioSourceObject);
}
return source;
}
/// <summary>
/// Adds High Pass Filter to audiosource. Used for turbo.
/// </summary>
public static void NewHighPassFilter(AudioSource source, float freq, int level) {
if (source == null)
return;
AudioHighPassFilter highFilter = source.gameObject.AddComponent<AudioHighPassFilter>();
highFilter.cutoffFrequency = freq;
highFilter.highpassResonanceQ = level;
}
/// <summary>
/// Adds Low Pass Filter to audiosource. Used for engine off sounds.
/// </summary>
public static void NewLowPassFilter(AudioSource source, float freq) {
if (source == null)
return;
AudioLowPassFilter lowFilter = source.gameObject.AddComponent<AudioLowPassFilter>();
lowFilter.cutoffFrequency = freq;
// lowFilter.highpassResonanceQ = level;
}
#endregion
#region Create WheelColliders
/// <summary>
/// Creates the wheel colliders.
/// </summary>
public void CreateWheelColliders(RCC_CarControllerV3 carController) {
// Creating a list for all wheel models.
List<Transform> allWheelModels = new List<Transform>();
allWheelModels.Add(carController.FrontLeftWheelTransform); allWheelModels.Add(carController.FrontRightWheelTransform); allWheelModels.Add(carController.RearLeftWheelTransform); allWheelModels.Add(carController.RearRightWheelTransform);
// If we have additional rear wheels, add them too.
if (carController.ExtraRearWheelsTransform != null && carController.ExtraRearWheelsTransform.Length > 0 && carController.ExtraRearWheelsTransform[0] != null) {
foreach (Transform t in carController.ExtraRearWheelsTransform)
allWheelModels.Add(t);
}
// If we don't have any wheelmodels, throw an error.
bool missingWheelFound = false;
for (int i = 0; i < allWheelModels.Count; i++) {
if (allWheelModels[i] == null) {
missingWheelFound = true;
break;
}
}
if (missingWheelFound) {
Debug.LogError("You haven't choosen your Wheel Models. Please select all of your Wheel Models before creating Wheel Colliders. Script needs to know their sizes and positions, aye?");
return;
}
// Holding default rotation.
Quaternion currentRotation = carController.transform.rotation;
// Resetting rotation.
carController.transform.rotation = Quaternion.identity;
// Creating a new gameobject called Wheel Colliders for all Wheel Colliders, and parenting it to this gameobject.
GameObject WheelColliders = new GameObject("Wheel Colliders");
WheelColliders.transform.SetParent(carController.transform, false);
WheelColliders.transform.localRotation = Quaternion.identity;
WheelColliders.transform.localPosition = Vector3.zero;
WheelColliders.transform.localScale = Vector3.one;
// Creating WheelColliders.
foreach (Transform wheel in allWheelModels) {
GameObject wheelcollider = new GameObject(wheel.transform.name);
wheelcollider.transform.SetPositionAndRotation(RCC_GetBounds.GetBoundsCenter(wheel.transform), carController.transform.rotation);
wheelcollider.transform.name = wheel.transform.name;
wheelcollider.transform.SetParent(WheelColliders.transform);
wheelcollider.transform.localScale = Vector3.one;
wheelcollider.AddComponent<WheelCollider>();
wheelcollider.AddComponent<RCC_WheelCollider>();
Bounds biggestBound = new Bounds();
Renderer[] renderers = wheel.GetComponentsInChildren<Renderer>();
foreach (Renderer render in renderers) {
if (render != GetComponent<Renderer>()) {
if (render.bounds.size.z > biggestBound.size.z)
biggestBound = render.bounds;
}
}
wheelcollider.GetComponent<WheelCollider>().radius = (biggestBound.extents.y) / carController.transform.localScale.y;
JointSpring spring = wheelcollider.GetComponent<WheelCollider>().suspensionSpring;
spring.spring = RCC_InitialSettings.Instance.suspensionSpring;
spring.damper = RCC_InitialSettings.Instance.suspensionDamping;
spring.targetPosition = .5f;
wheelcollider.GetComponent<WheelCollider>().suspensionSpring = spring;
wheelcollider.GetComponent<WheelCollider>().suspensionDistance = RCC_InitialSettings.Instance.suspensionDistance;
wheelcollider.GetComponent<WheelCollider>().forceAppPointDistance = RCC_InitialSettings.Instance.forceAppPoint;
wheelcollider.GetComponent<WheelCollider>().mass = 40f;
wheelcollider.GetComponent<WheelCollider>().wheelDampingRate = 1f;
WheelFrictionCurve sidewaysFriction;
WheelFrictionCurve forwardFriction;
sidewaysFriction = wheelcollider.GetComponent<WheelCollider>().sidewaysFriction;
forwardFriction = wheelcollider.GetComponent<WheelCollider>().forwardFriction;
forwardFriction.extremumSlip = RCC_InitialSettings.Instance.forwardExtremumSlip;
forwardFriction.extremumValue = RCC_InitialSettings.Instance.forwardExtremumValue;
forwardFriction.asymptoteSlip = RCC_InitialSettings.Instance.forwardAsymptoteSlip;
forwardFriction.asymptoteValue = RCC_InitialSettings.Instance.forwardAsymptoteValue;
forwardFriction.stiffness = RCC_InitialSettings.Instance.forwardStiffness;
sidewaysFriction.extremumSlip = RCC_InitialSettings.Instance.sidewaysExtremumSlip;
sidewaysFriction.extremumValue = RCC_InitialSettings.Instance.sidewaysExtremumValue;
sidewaysFriction.asymptoteSlip = RCC_InitialSettings.Instance.sidewaysAsymptoteSlip;
sidewaysFriction.asymptoteValue = RCC_InitialSettings.Instance.sidewaysAsymptoteValue;
sidewaysFriction.stiffness = RCC_InitialSettings.Instance.sidewaysStiffness;
wheelcollider.GetComponent<WheelCollider>().sidewaysFriction = sidewaysFriction;
wheelcollider.GetComponent<WheelCollider>().forwardFriction = forwardFriction;
}
RCC_WheelCollider[] allWheelColliders = new RCC_WheelCollider[allWheelModels.Count];
allWheelColliders = GetComponentsInChildren<RCC_WheelCollider>();
carController.FrontLeftWheelCollider = allWheelColliders[0];
carController.FrontRightWheelCollider = allWheelColliders[1];
carController.RearLeftWheelCollider = allWheelColliders[2];
carController.RearRightWheelCollider = allWheelColliders[3];
if (carController.ExtraRearWheelsTransform != null) {
carController.ExtraRearWheelsCollider = new RCC_WheelCollider[carController.ExtraRearWheelsTransform.Length];
for (int i = 0; i < carController.ExtraRearWheelsTransform.Length; i++)
carController.ExtraRearWheelsCollider[i] = allWheelColliders[i + 4];
}
carController.transform.rotation = currentRotation;
}
#endregion
#region Set Behavior
/// <summary>
/// Overrides the behavior.
/// </summary>
public void SetBehavior(RCC_CarControllerV3 carController) {
if (RCC_Settings.Instance.selectedBehaviorType == null)
return;
RCC_Settings.BehaviorType currentBehaviorType = RCC_Settings.Instance.selectedBehaviorType;
carController.steeringHelper = currentBehaviorType.steeringHelper;
carController.tractionHelper = currentBehaviorType.tractionHelper;
carController.angularDragHelper = currentBehaviorType.angularDragHelper;
carController.useSteeringLimiter = currentBehaviorType.limitSteering;
carController.useSteeringSensitivity = currentBehaviorType.steeringSensitivity;
carController.steeringSensitivityFactor = Mathf.Clamp(carController.steeringSensitivityFactor, currentBehaviorType.steeringSensitivityMinimum, currentBehaviorType.steeringSensitivityMaximum);
carController.steeringType = currentBehaviorType.steeringType;
carController.COMAssister = currentBehaviorType.comAssister;
if (carController.steeringType == RCC_CarControllerV3.SteeringType.Curve)
carController.steerAngleCurve = currentBehaviorType.steeringCurve;
carController.useCounterSteering = currentBehaviorType.counterSteering;
carController.ABS = currentBehaviorType.ABS;
carController.ESP = currentBehaviorType.ESP;
carController.TCS = currentBehaviorType.TCS;
carController.highspeedsteerAngle = Mathf.Clamp(carController.highspeedsteerAngle, currentBehaviorType.highSpeedSteerAngleMinimum, currentBehaviorType.highSpeedSteerAngleMaximum);
carController.highspeedsteerAngleAtspeed = Mathf.Clamp(carController.highspeedsteerAngleAtspeed, currentBehaviorType.highSpeedSteerAngleAtspeedMinimum, currentBehaviorType.highSpeedSteerAngleAtspeedMaximum);
carController.counterSteeringFactor = Mathf.Clamp(carController.counterSteeringFactor, currentBehaviorType.counterSteeringMinimum, currentBehaviorType.counterSteeringMaximum);
carController.counterSteerInput = 0f;
carController.steerHelperAngularVelStrength = Mathf.Clamp(carController.steerHelperAngularVelStrength, currentBehaviorType.steerHelperAngularVelStrengthMinimum, currentBehaviorType.steerHelperAngularVelStrengthMaximum);
carController.steerHelperLinearVelStrength = Mathf.Clamp(carController.steerHelperLinearVelStrength, currentBehaviorType.steerHelperLinearVelStrengthMinimum, currentBehaviorType.steerHelperLinearVelStrengthMaximum);
carController.tractionHelperStrength = Mathf.Clamp(carController.tractionHelperStrength, currentBehaviorType.tractionHelperStrengthMinimum, currentBehaviorType.tractionHelperStrengthMaximum);
carController.antiRollFrontHorizontal = Mathf.Clamp(carController.antiRollFrontHorizontal, currentBehaviorType.antiRollFrontHorizontalMinimum, Mathf.Infinity);
carController.antiRollRearHorizontal = Mathf.Clamp(carController.antiRollRearHorizontal, currentBehaviorType.antiRollRearHorizontalMinimum, Mathf.Infinity);
carController.gearShiftingDelay = Mathf.Clamp(carController.gearShiftingDelay, 0f, currentBehaviorType.gearShiftingDelayMaximum);
carController.Rigid.angularDrag = currentBehaviorType.angularDrag;
carController.angularDragHelperStrength = Mathf.Clamp(carController.angularDragHelperStrength, currentBehaviorType.angularDragHelperMinimum, currentBehaviorType.angularDragHelperMaximum);
}
#endregion
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ac3a208bf35686a4ba7e2063a72bb752
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,98 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Operates the hammer in the damage demo scene.
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class RCC_CrashHammer : MonoBehaviour {
public Transform hingePoint; // Hinge point of the joint.
private Rigidbody rigid; // Rigidbody.
public Vector3 torque; // Torque.
public float length = 1f; // Length of the wave.
public float speed = 1f; // Speed of the wave.
private void Start() {
// Getting rigidbody.
rigid = GetComponent<Rigidbody>();
// Creating hinge with configurable joint.
CreateHinge();
}
private void FixedUpdate() {
// If no rigid, return.
if (!rigid)
return;
// Apply force.
rigid.AddRelativeForce(torque * ((float)Mathf.Sin(Time.time * speed) * length), ForceMode.Acceleration);
}
/// <summary>
/// Creates hinge with configurable joint.
/// </summary>
private void CreateHinge() {
GameObject hinge = new GameObject("Hinge_" + transform.name);
hinge.transform.position = hingePoint.position;
hinge.transform.rotation = hingePoint.rotation;
Rigidbody hingeRigid = hinge.AddComponent<Rigidbody>();
hingeRigid.isKinematic = true;
hingeRigid.useGravity = false;
AttachHinge(hingeRigid);
}
/// <summary>
/// Sets connected body of the configurable joint.
/// </summary>
/// <param name="hingeRigid"></param>
private void AttachHinge(Rigidbody hingeRigid) {
ConfigurableJoint joint = GetComponent<ConfigurableJoint>();
if (!joint) {
print("Configurable Joint of the " + transform.name + " not found! Be sure this gameobject has Configurable Joint with right config.");
enabled = false;
return;
}
joint.autoConfigureConnectedAnchor = false;
joint.connectedBody = hingeRigid;
joint.connectedAnchor = Vector3.zero;
}
private void Reset() {
if (hingePoint == null) {
hingePoint = new GameObject("Hinge Point").transform;
hingePoint.SetParent(transform, false);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e23a054a8419be74ebe617b898bffac3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,96 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Operates the press in the damage demo scene.
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class RCC_CrashPress : MonoBehaviour {
public Transform hingePoint; // Hinge point of the joint.
private Rigidbody rigid; // Rigidbody.
public float length = 1f; // Length of the wave.
public float speed = 1f; // Speed of the wave.
private void Start() {
// Getting rigidbody.
rigid = GetComponent<Rigidbody>();
// Creating hinge with configurable joint.
CreateHinge();
}
private void FixedUpdate() {
// If no rigid, return.
if (!rigid)
return;
// Apply force.
rigid.AddRelativeForce(Vector3.up * ((float)Mathf.Sin(Time.time * speed) * length), ForceMode.Acceleration);
}
/// <summary>
/// Creates hinge with configurable joint.
/// </summary>
private void CreateHinge() {
GameObject hinge = new GameObject("Hinge_" + transform.name);
hinge.transform.position = hingePoint.position;
hinge.transform.rotation = hingePoint.rotation;
Rigidbody hingeRigid = hinge.AddComponent<Rigidbody>();
hingeRigid.isKinematic = true;
hingeRigid.useGravity = false;
AttachHinge(hingeRigid);
}
/// <summary>
/// Sets connected body of the configurable joint.
/// </summary>
/// <param name="hingeRigid"></param>
private void AttachHinge(Rigidbody hingeRigid) {
ConfigurableJoint joint = GetComponent<ConfigurableJoint>();
if (!joint) {
print("Configurable Joint of the " + transform.name + " not found! Be sure this gameobject has Configurable Joint with right config.");
return;
}
joint.autoConfigureConnectedAnchor = false;
joint.connectedBody = hingeRigid;
joint.connectedAnchor = Vector3.zero;
}
private void Reset() {
if (hingePoint == null) {
hingePoint = new GameObject("Hinge Point").transform;
hingePoint.SetParent(transform, false);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c1a178fe5c643549aeaaf97fd8f0f08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,96 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Operates the shredder in the damage demo scene.
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class RCC_CrashShredder : MonoBehaviour {
public Transform hingePoint; // Hinge joint.
private Rigidbody rigid; // Rigid.
public Vector3 direction; // Direction of the force.
public float force = 1f; // Strength of the force.
private void Start() {
// Getting rigidbody.
rigid = GetComponent<Rigidbody>();
// Creating hinge with configurable joint.
CreateHinge();
}
private void FixedUpdate() {
// If no rigid, return.
if (!rigid)
return;
// Apply force.
rigid.AddRelativeTorque(direction * force, ForceMode.Acceleration);
}
/// <summary>
/// Creates hinge with configurable joint.
/// </summary>
private void CreateHinge() {
GameObject hinge = new GameObject("Hinge_" + transform.name);
hinge.transform.position = hingePoint.position;
hinge.transform.rotation = hingePoint.rotation;
Rigidbody hingeRigid = hinge.AddComponent<Rigidbody>();
hingeRigid.isKinematic = true;
hingeRigid.useGravity = false;
AttachHinge(hingeRigid);
}
/// <summary>
/// Sets connected body of the configurable joint.
/// </summary>
/// <param name="hingeRigid"></param>
private void AttachHinge(Rigidbody hingeRigid) {
ConfigurableJoint joint = GetComponent<ConfigurableJoint>();
if (!joint) {
print("Configurable Joint of the " + transform.name + " not found! Be sure this gameobject has Configurable Joint with right config.");
return;
}
joint.autoConfigureConnectedAnchor = false;
joint.connectedBody = hingeRigid;
joint.connectedAnchor = Vector3.zero;
}
private void Reset() {
if (hingePoint == null) {
hingePoint = new GameObject("Hinge Point").transform;
hingePoint.SetParent(transform, false);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c28cf663b615d14bae50da6f96966f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,884 @@
//----------------------------------------------
// 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>
/// Main Customization Class For RCC.
///</summary>
public class RCC_Customization : MonoBehaviour {
/// <summary>
/// Set Customization Mode. This will enable / disable controlling the vehicle, and enable / disable orbit camera mode.
/// </summary>
public static void SetCustomizationMode(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!vehicle) {
Debug.LogError("Player vehicle is not selected for customization! Use RCC_Customization.SetCustomizationMode(playerVehicle, true/false); for enabling / disabling customization mode for player vehicle.");
return;
}
// Finding camera and dashboard.
RCC_Camera cam = RCC_SceneManager.Instance.activePlayerCamera;
RCC_UIDashboardDisplay UI = RCC_SceneManager.Instance.activePlayerCanvas;
// If enabled customization mode, set camera mode to TPS and set UI type to Customization. Set controllable state of the vehicle to false, we don't want to control the vehicle while customizing.
if (state) {
vehicle.SetCanControl(false);
if (cam)
cam.ChangeCamera(RCC_Camera.CameraMode.TPS);
if (UI)
UI.SetDisplayType(RCC_UIDashboardDisplay.DisplayType.Customization);
} else {
// If disabled the customization mode, set camera mode to TPS and set UI type to Full. Set controllable state of the vehicle to true, and make sure previewing flames and exhaust is set to false.
SetSmokeParticle(vehicle, false);
SetExhaustFlame(vehicle, false);
vehicle.SetCanControl(true);
if (cam)
cam.ChangeCamera(RCC_Camera.CameraMode.TPS);
if (UI)
UI.SetDisplayType(RCC_UIDashboardDisplay.DisplayType.Full);
}
}
/// <summary>
/// Enable / Disable Smoke Particles. You can use it for previewing current wheel smokes.
/// </summary>
public static void SetSmokeParticle(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.PreviewSmokeParticle(state);
}
/// <summary>
/// Set Smoke Color.
/// </summary>
public static void SetSmokeColor(RCC_CarControllerV3 vehicle, int indexOfGroundMaterial, Color color) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Getting all wheelcolliders.
RCC_WheelCollider[] wheels = vehicle.GetComponentsInChildren<RCC_WheelCollider>();
// And setting color of the particles.
foreach (RCC_WheelCollider wheel in wheels) {
for (int i = 0; i < wheel.allWheelParticles.Count; i++) {
ParticleSystem ps = wheel.allWheelParticles[i];
ParticleSystem.MainModule psmain = ps.main;
color.a = psmain.startColor.color.a;
psmain.startColor = color;
}
}
}
/// <summary>
/// Set Headlights Color.
/// </summary>
public static void SetHeadlightsColor(RCC_CarControllerV3 vehicle, Color color) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Enabling headlights.
vehicle.lowBeamHeadLightsOn = true;
// Getting all lights.
RCC_Light[] lights = vehicle.GetComponentsInChildren<RCC_Light>();
// If light is headlight, set color.
foreach (RCC_Light l in lights) {
if (l.lightType == RCC_Light.LightType.HeadLight || l.lightType == RCC_Light.LightType.HighBeamHeadLight)
l.GetComponent<Light>().color = color;
}
}
/// <summary>
/// Enable / Disable Exhaust Flame Particles.
/// </summary>
public static void SetExhaustFlame(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Getting all exhausts.
RCC_Exhaust[] exhausts = vehicle.GetComponentsInChildren<RCC_Exhaust>();
// Enabling preview mode for all exhausts.
foreach (RCC_Exhaust exhaust in exhausts)
exhaust.previewFlames = state;
}
/// <summary>
/// Set Front Wheel Cambers.
/// </summary>
public static void SetFrontCambers(RCC_CarControllerV3 vehicle, float camberAngle) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Getting all wheelcolliders.
RCC_WheelCollider[] wc = vehicle.GetComponentsInChildren<RCC_WheelCollider>();
// Setting camber variable of front wheelcolliders.
foreach (RCC_WheelCollider w in wc) {
if (w == vehicle.FrontLeftWheelCollider || w == vehicle.FrontRightWheelCollider)
w.camber = camberAngle;
}
}
/// <summary>
/// Set Rear Wheel Cambers.
/// </summary>
public static void SetRearCambers(RCC_CarControllerV3 vehicle, float camberAngle) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Getting all wheelcolliders.
RCC_WheelCollider[] wc = vehicle.GetComponentsInChildren<RCC_WheelCollider>();
// Setting camber variable of rear wheelcolliders.
foreach (RCC_WheelCollider w in wc) {
if (w != vehicle.FrontLeftWheelCollider && w != vehicle.FrontRightWheelCollider)
w.camber = camberAngle;
}
}
/// <summary>
/// Change Wheel Models. You can find your wheel models array in Tools --> BCG --> RCC --> Configure Changable Wheels.
/// </summary>
public static void ChangeWheels(RCC_CarControllerV3 vehicle, GameObject wheel, bool applyRadius) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Getting all wheelcolliders.
for (int i = 0; i < vehicle.AllWheelColliders.Length; i++) {
// Disabling renderer of the wheelmodel.
if (vehicle.AllWheelColliders[i].wheelModel.GetComponent<MeshRenderer>())
vehicle.AllWheelColliders[i].wheelModel.GetComponent<MeshRenderer>().enabled = false;
// Disabling all child models of the wheel.
foreach (Transform t in vehicle.AllWheelColliders[i].wheelModel.GetComponentInChildren<Transform>())
t.gameObject.SetActive(false);
// Instantiating new wheel.
GameObject newWheel = Instantiate(wheel, vehicle.AllWheelColliders[i].wheelModel.position, vehicle.AllWheelColliders[i].wheelModel.rotation, vehicle.AllWheelColliders[i].wheelModel);
// If wheel is at right side, multiply scale X by -1 for symetry.
if (vehicle.AllWheelColliders[i].wheelModel.localPosition.x > 0f)
newWheel.transform.localScale = new Vector3(newWheel.transform.localScale.x * -1f, newWheel.transform.localScale.y, newWheel.transform.localScale.z);
// If apply radius is set to true, calculate the radius.
if (applyRadius)
vehicle.AllWheelColliders[i].WheelCollider.radius = RCC_GetBounds.MaxBoundsExtent(wheel.transform);
}
}
/// <summary>
/// Set Front Suspension targetPositions. It changes targetPosition of the front WheelColliders.
/// </summary>
public static void SetFrontSuspensionsTargetPos(RCC_CarControllerV3 vehicle, float targetPosition) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Sets target position.
targetPosition = Mathf.Clamp01(targetPosition);
JointSpring spring1 = vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring;
spring1.targetPosition = 1f - targetPosition;
vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring = spring1;
JointSpring spring2 = vehicle.FrontRightWheelCollider.WheelCollider.suspensionSpring;
spring2.targetPosition = 1f - targetPosition;
vehicle.FrontRightWheelCollider.WheelCollider.suspensionSpring = spring2;
}
/// <summary>
/// Set Rear Suspension targetPositions. It changes targetPosition of the rear WheelColliders.
/// </summary>
public static void SetRearSuspensionsTargetPos(RCC_CarControllerV3 vehicle, float targetPosition) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Sets target position.
targetPosition = Mathf.Clamp01(targetPosition);
JointSpring spring1 = vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring;
spring1.targetPosition = 1f - targetPosition;
vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring = spring1;
JointSpring spring2 = vehicle.RearRightWheelCollider.WheelCollider.suspensionSpring;
spring2.targetPosition = 1f - targetPosition;
vehicle.RearRightWheelCollider.WheelCollider.suspensionSpring = spring2;
}
/// <summary>
/// Set All Suspension targetPositions. It changes targetPosition of the all WheelColliders.
/// </summary>
public static void SetAllSuspensionsTargetPos(RCC_CarControllerV3 vehicle, float targetPosition) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Sets target position.
targetPosition = Mathf.Clamp01(targetPosition);
JointSpring spring1 = vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring;
spring1.targetPosition = 1f - targetPosition;
vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring = spring1;
JointSpring spring2 = vehicle.RearRightWheelCollider.WheelCollider.suspensionSpring;
spring2.targetPosition = 1f - targetPosition;
vehicle.RearRightWheelCollider.WheelCollider.suspensionSpring = spring2;
JointSpring spring3 = vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring;
spring3.targetPosition = 1f - targetPosition;
vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring = spring3;
JointSpring spring4 = vehicle.FrontRightWheelCollider.WheelCollider.suspensionSpring;
spring4.targetPosition = 1f - targetPosition;
vehicle.FrontRightWheelCollider.WheelCollider.suspensionSpring = spring4;
}
/// <summary>
/// Set Front Suspension Distances.
/// </summary>
public static void SetFrontSuspensionsDistances(RCC_CarControllerV3 vehicle, float distance) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Make sure new distance is not close to 0.
if (distance <= .01)
distance = .05f;
// Setting suspension distance of front wheelcolliders.
vehicle.FrontLeftWheelCollider.WheelCollider.suspensionDistance = distance;
vehicle.FrontRightWheelCollider.WheelCollider.suspensionDistance = distance;
}
/// <summary>
/// Set Rear Suspension Distances.
/// </summary>
public static void SetRearSuspensionsDistances(RCC_CarControllerV3 vehicle, float distance) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Make sure new distance is not close to 0.
if (distance <= .01)
distance = .05f;
// Setting suspension distance of front wheelcolliders.
vehicle.RearLeftWheelCollider.WheelCollider.suspensionDistance = distance;
vehicle.RearRightWheelCollider.WheelCollider.suspensionDistance = distance;
if (vehicle.ExtraRearWheelsCollider != null && vehicle.ExtraRearWheelsCollider.Length > 0) {
foreach (RCC_WheelCollider wc in vehicle.ExtraRearWheelsCollider)
wc.WheelCollider.suspensionDistance = distance;
}
}
/// <summary>
/// Set Drivetrain Mode.
/// </summary>
public static void SetDrivetrainMode(RCC_CarControllerV3 vehicle, RCC_CarControllerV3.WheelType mode) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.wheelTypeChoise = mode;
}
/// <summary>
/// Set Gear Shifting Threshold. Automatic gear will shift up at earlier rpm on lower values. Automatic gear will shift up at later rpm on higher values.
/// </summary>
public static void SetGearShiftingThreshold(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.gearShiftingThreshold = targetValue;
}
/// <summary>
/// Set Clutch Threshold. Automatic gear will shift up at earlier rpm on lower values. Automatic gear will shift up at later rpm on higher values.
/// </summary>
public static void SetClutchThreshold(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.clutchInertia = targetValue;
}
/// <summary>
/// Enable / Disable Counter Steering while vehicle is drifting. Useful for avoid spinning.
/// </summary>
public static void SetCounterSteering(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useCounterSteering = state;
}
/// <summary>
/// Enable / Disable Steering Limiter while vehicle is drifting. Useful for avoid spinning.
/// </summary>
public static void SetSteeringLimit(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useSteeringLimiter = state;
}
/// <summary>
/// Enable / Disable NOS.
/// </summary>
public static void SetNOS(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useNOS = state;
}
/// <summary>
/// Enable / Disable Turbo.
/// </summary>
public static void SetTurbo(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useTurbo = state;
}
/// <summary>
/// Enable / Disable Exhaust Flames.
/// </summary>
public static void SetUseExhaustFlame(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useExhaustFlame = state;
}
/// <summary>
/// Enable / Disable Rev Limiter.
/// </summary>
public static void SetRevLimiter(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.useRevLimiter = state;
}
/// <summary>
/// Set Front Suspension Spring Force.
/// </summary>
public static void SetFrontSuspensionsSpringForce(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
JointSpring spring = vehicle.FrontLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring;
spring.spring = targetValue;
vehicle.FrontLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
vehicle.FrontRightWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
}
/// <summary>
/// Set Rear Suspension Spring Force.
/// </summary>
public static void SetRearSuspensionsSpringForce(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
JointSpring spring = vehicle.RearLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring;
spring.spring = targetValue;
vehicle.RearLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
vehicle.RearRightWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
}
/// <summary>
/// Set Front Suspension Spring Damper.
/// </summary>
public static void SetFrontSuspensionsSpringDamper(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
JointSpring spring = vehicle.FrontLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring;
spring.damper = targetValue;
vehicle.FrontLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
vehicle.FrontRightWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
}
/// <summary>
/// Set Rear Suspension Spring Damper.
/// </summary>
public static void SetRearSuspensionsSpringDamper(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
JointSpring spring = vehicle.RearLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring;
spring.damper = targetValue;
vehicle.RearLeftWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
vehicle.RearRightWheelCollider.GetComponent<WheelCollider>().suspensionSpring = spring;
}
/// <summary>
/// Set Maximum Speed of the vehicle.
/// </summary>
public static void SetMaximumSpeed(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.maxspeed = Mathf.Clamp(targetValue, 10f, 400f);
}
/// <summary>
/// Set Maximum Engine Torque of the vehicle.
/// </summary>
public static void SetMaximumTorque(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.maxEngineTorque = Mathf.Clamp(targetValue, 50f, 50000f);
}
/// <summary>
/// Set Maximum Brake of the vehicle.
/// </summary>
public static void SetMaximumBrake(RCC_CarControllerV3 vehicle, float targetValue) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.brakeTorque = Mathf.Clamp(targetValue, 0f, 50000f);
}
/// <summary>
/// Repair vehicle.
/// </summary>
public static void Repair(RCC_CarControllerV3 vehicle) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.Repair();
}
/// <summary>
/// Enable / Disable ESP.
/// </summary>
public static void SetESP(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.ESP = state;
}
/// <summary>
/// Enable / Disable ABS.
/// </summary>
public static void SetABS(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.ABS = state;
}
/// <summary>
/// Enable / Disable TCS.
/// </summary>
public static void SetTCS(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.TCS = state;
}
/// <summary>
/// Enable / Disable Steering Helper.
/// </summary>
public static void SetSH(RCC_CarControllerV3 vehicle, bool state) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.steeringHelper = state;
}
/// <summary>
/// Set Steering Helper strength.
/// </summary>
public static void SetSHStrength(RCC_CarControllerV3 vehicle, float value) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.steeringHelper = true;
vehicle.steerHelperLinearVelStrength = value;
vehicle.steerHelperAngularVelStrength = value;
}
/// <summary>
/// Set Transmission of the vehicle.
/// </summary>
public static void SetTransmission(RCC_CarControllerV3 vehicle, bool automatic) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
vehicle.AutomaticGear = automatic;
}
/// <summary>
/// Save all stats with PlayerPrefs.
/// </summary>
public static void SaveStats(RCC_CarControllerV3 vehicle) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Saving all major settings of the vehicle with PlayerPrefs.
PlayerPrefs.SetFloat(vehicle.transform.name + "_FrontCamber", vehicle.FrontLeftWheelCollider.camber);
PlayerPrefs.SetFloat(vehicle.transform.name + "_RearCamber", vehicle.RearLeftWheelCollider.camber);
PlayerPrefs.SetFloat(vehicle.transform.name + "_FrontSuspensionsDistance", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionDistance);
PlayerPrefs.SetFloat(vehicle.transform.name + "_RearSuspensionsDistance", vehicle.RearLeftWheelCollider.WheelCollider.suspensionDistance);
PlayerPrefs.SetFloat(vehicle.transform.name + "_FrontSuspensionsSpring", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.spring);
PlayerPrefs.SetFloat(vehicle.transform.name + "_RearSuspensionsSpring", vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.spring);
PlayerPrefs.SetFloat(vehicle.transform.name + "_FrontSuspensionsDamper", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.damper);
PlayerPrefs.SetFloat(vehicle.transform.name + "_RearSuspensionsDamper", vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.damper);
PlayerPrefs.SetFloat(vehicle.transform.name + "_MaximumSpeed", vehicle.maxspeed);
PlayerPrefs.SetFloat(vehicle.transform.name + "_MaximumBrake", vehicle.brakeTorque);
PlayerPrefs.SetFloat(vehicle.transform.name + "_MaximumTorque", vehicle.maxEngineTorque);
PlayerPrefs.SetString(vehicle.transform.name + "_DrivetrainMode", vehicle.wheelTypeChoise.ToString());
PlayerPrefs.SetFloat(vehicle.transform.name + "_GearShiftingThreshold", vehicle.gearShiftingThreshold);
PlayerPrefs.SetFloat(vehicle.transform.name + "_ClutchingThreshold", vehicle.clutchInertia);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "_CounterSteering", vehicle.useCounterSteering);
foreach (RCC_Light _light in vehicle.GetComponentsInChildren<RCC_Light>()) {
if (_light.lightType == RCC_Light.LightType.HeadLight) {
RCC_PlayerPrefsX.SetColor(vehicle.transform.name + "_HeadlightsColor", _light.GetComponentInChildren<Light>().color);
break;
}
}
ParticleSystem ps = vehicle.RearLeftWheelCollider.allWheelParticles[0];
ParticleSystem.MainModule psmain = ps.main;
RCC_PlayerPrefsX.SetColor(vehicle.transform.name + "_WheelsSmokeColor", psmain.startColor.color);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "_ABS", vehicle.ABS);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "_ESP", vehicle.ESP);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "_TCS", vehicle.TCS);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "_SH", vehicle.steeringHelper);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "NOS", vehicle.useNOS);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "Turbo", vehicle.useTurbo);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "ExhaustFlame", vehicle.useExhaustFlame);
RCC_PlayerPrefsX.SetBool(vehicle.transform.name + "RevLimiter", vehicle.useRevLimiter);
}
/// <summary>
/// Load all stats with PlayerPrefs.
/// </summary>
public static void LoadStats(RCC_CarControllerV3 vehicle) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// Loading all major settings of the vehicle with PlayerPrefs.
SetFrontCambers(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_FrontCamber", vehicle.FrontLeftWheelCollider.camber));
SetRearCambers(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_RearCamber", vehicle.RearLeftWheelCollider.camber));
SetFrontSuspensionsDistances(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_FrontSuspensionsDistance", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionDistance));
SetRearSuspensionsDistances(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_RearSuspensionsDistance", vehicle.RearLeftWheelCollider.WheelCollider.suspensionDistance));
SetFrontSuspensionsSpringForce(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_FrontSuspensionsSpring", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.spring));
SetRearSuspensionsSpringForce(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_RearSuspensionsSpring", vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.spring));
SetFrontSuspensionsSpringDamper(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_FrontSuspensionsDamper", vehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.damper));
SetRearSuspensionsSpringDamper(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_RearSuspensionsDamper", vehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.damper));
SetMaximumSpeed(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_MaximumSpeed", vehicle.maxspeed));
SetMaximumBrake(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_MaximumBrake", vehicle.brakeTorque));
SetMaximumTorque(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_MaximumTorque", vehicle.maxEngineTorque));
string drvtrn = PlayerPrefs.GetString(vehicle.transform.name + "_DrivetrainMode", vehicle.wheelTypeChoise.ToString());
switch (drvtrn) {
case "FWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.FWD;
break;
case "RWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.RWD;
break;
case "AWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.AWD;
break;
}
SetGearShiftingThreshold(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_GearShiftingThreshold", vehicle.gearShiftingThreshold));
SetClutchThreshold(vehicle, PlayerPrefs.GetFloat(vehicle.transform.name + "_ClutchingThreshold", vehicle.clutchInertia));
SetCounterSteering(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "_CounterSteering", vehicle.useCounterSteering));
SetABS(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "_ABS", vehicle.ABS));
SetESP(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "_ESP", vehicle.ESP));
SetTCS(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "_TCS", vehicle.TCS));
SetSH(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "_SH", vehicle.steeringHelper));
SetNOS(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "NOS", vehicle.useNOS));
SetTurbo(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "Turbo", vehicle.useTurbo));
SetUseExhaustFlame(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "ExhaustFlame", vehicle.useExhaustFlame));
SetRevLimiter(vehicle, RCC_PlayerPrefsX.GetBool(vehicle.transform.name + "RevLimiter", vehicle.useRevLimiter));
if (PlayerPrefs.HasKey(vehicle.transform.name + "_WheelsSmokeColor"))
SetSmokeColor(vehicle, 0, RCC_PlayerPrefsX.GetColor(vehicle.transform.name + "_WheelsSmokeColor"));
if (PlayerPrefs.HasKey(vehicle.transform.name + "_HeadlightsColor"))
SetHeadlightsColor(vehicle, RCC_PlayerPrefsX.GetColor(vehicle.transform.name + "_HeadlightsColor"));
}
/// <summary>
/// Resets all stats and saves default values with PlayerPrefs.
/// </summary>
public static void ResetStats(RCC_CarControllerV3 vehicle, RCC_CarControllerV3 defaultCar) {
// If no vehicle found, return.
if (!CheckVehicle(vehicle))
return;
// If no default vehicle found, return.
if (!CheckVehicle(defaultCar))
return;
SetFrontCambers(vehicle, defaultCar.FrontLeftWheelCollider.camber);
SetRearCambers(vehicle, defaultCar.RearLeftWheelCollider.camber);
SetFrontSuspensionsDistances(vehicle, defaultCar.FrontLeftWheelCollider.WheelCollider.suspensionDistance);
SetRearSuspensionsDistances(vehicle, defaultCar.RearLeftWheelCollider.WheelCollider.suspensionDistance);
SetFrontSuspensionsSpringForce(vehicle, defaultCar.FrontLeftWheelCollider.WheelCollider.suspensionSpring.spring);
SetRearSuspensionsSpringForce(vehicle, defaultCar.RearLeftWheelCollider.WheelCollider.suspensionSpring.spring);
SetFrontSuspensionsSpringDamper(vehicle, defaultCar.FrontLeftWheelCollider.WheelCollider.suspensionSpring.damper);
SetRearSuspensionsSpringDamper(vehicle, defaultCar.RearLeftWheelCollider.WheelCollider.suspensionSpring.damper);
SetMaximumSpeed(vehicle, defaultCar.maxspeed);
SetMaximumBrake(vehicle, defaultCar.brakeTorque);
SetMaximumTorque(vehicle, defaultCar.maxEngineTorque);
string drvtrn = defaultCar.wheelTypeChoise.ToString();
switch (drvtrn) {
case "FWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.FWD;
break;
case "RWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.RWD;
break;
case "AWD":
vehicle.wheelTypeChoise = RCC_CarControllerV3.WheelType.AWD;
break;
}
SetGearShiftingThreshold(vehicle, defaultCar.gearShiftingThreshold);
SetClutchThreshold(vehicle, defaultCar.clutchInertia);
SetCounterSteering(vehicle, defaultCar.useCounterSteering);
SetABS(vehicle, defaultCar.ABS);
SetESP(vehicle, defaultCar.ESP);
SetTCS(vehicle, defaultCar.TCS);
SetSH(vehicle, defaultCar.steeringHelper);
SetNOS(vehicle, defaultCar.useNOS);
SetTurbo(vehicle, defaultCar.useTurbo);
SetUseExhaustFlame(vehicle, defaultCar.useExhaustFlame);
SetRevLimiter(vehicle, defaultCar.useRevLimiter);
SetSmokeColor(vehicle, 0, Color.white);
SetHeadlightsColor(vehicle, Color.white);
SaveStats(vehicle);
}
/// <summary>
/// Checks the player vehicle.
/// </summary>
/// <param name="vehicle"></param>
/// <returns></returns>
public static bool CheckVehicle(RCC_CarControllerV3 vehicle) {
// If no vehicle found, return with an error.
if (!vehicle) {
Debug.LogError("Vehicle is missing!");
return false;
}
return true;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ada86cec0aa8545408cde609b197be0f
timeCreated: 1474065565
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,172 @@
//----------------------------------------------
// 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>
/// Customization applier for vehicles. Needs to be attached to the vehicle.
/// 5 Upgrade managers for paints, wheels, upgrades, spoilers, and sirens.
/// </summary>
[RequireComponent(typeof(RCC_CarControllerV3))]
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Customization/RCC Customization Applier")]
public class RCC_CustomizationApplier : MonoBehaviour {
// Car controller.
private RCC_CarControllerV3 _carController;
public RCC_CarControllerV3 CarController {
get {
if (_carController == null)
_carController = GetComponentInChildren<RCC_CarControllerV3>();
return _carController;
}
}
#region All upgrade managers
private RCC_VehicleUpgrade_PaintManager _paintManager;
public RCC_VehicleUpgrade_PaintManager PaintManager {
get {
if (_paintManager == null)
_paintManager = GetComponentInChildren<RCC_VehicleUpgrade_PaintManager>();
return _paintManager;
}
}
private RCC_VehicleUpgrade_WheelManager _wheelManager;
public RCC_VehicleUpgrade_WheelManager WheelManager {
get {
if (_wheelManager == null)
_wheelManager = GetComponentInChildren<RCC_VehicleUpgrade_WheelManager>();
return _wheelManager;
}
}
private RCC_VehicleUpgrade_UpgradeManager _upgradeManager;
public RCC_VehicleUpgrade_UpgradeManager UpgradeManager {
get {
if (_upgradeManager == null)
_upgradeManager = GetComponentInChildren<RCC_VehicleUpgrade_UpgradeManager>();
return _upgradeManager;
}
}
private RCC_VehicleUpgrade_SpoilerManager _spoilerManager;
public RCC_VehicleUpgrade_SpoilerManager SpoilerManager {
get {
if (_spoilerManager == null)
_spoilerManager = GetComponentInChildren<RCC_VehicleUpgrade_SpoilerManager>();
return _spoilerManager;
}
}
private RCC_VehicleUpgrade_SirenManager _sirenManager;
public RCC_VehicleUpgrade_SirenManager SirenManager {
get {
if (_sirenManager == null)
_sirenManager = GetComponentInChildren<RCC_VehicleUpgrade_SirenManager>();
return _sirenManager;
}
}
#endregion
public string saveFileName = ""; // Save file name of the vehicle.
public bool autoLoadLoadout = true; // Loads the latest loadout.
public RCC_CustomizationLoadout loadout = new RCC_CustomizationLoadout(); // Loadout class.
private void OnEnable() {
// Loads the latest loadout.
if (autoLoadLoadout)
LoadLoadout();
// Initializes paint manager.
if (PaintManager)
PaintManager.Initialize();
// Initializes wheel manager.
if (WheelManager)
WheelManager.Initialize();
// Initializes upgrade manager.
if (UpgradeManager)
UpgradeManager.Initialize();
// Initializes spoiler manager.
if (SpoilerManager)
SpoilerManager.Initialize();
// Initializes siren manager.
if (SirenManager)
SirenManager.Initialize();
}
/// <summary>
/// Saves the current loadout with Json.
/// </summary>
public void SaveLoadout() {
PlayerPrefs.SetString(saveFileName, JsonUtility.ToJson(loadout));
}
/// <summary>
/// Loads the latest saved loadout with Json.
/// </summary>
public void LoadLoadout() {
loadout = new RCC_CustomizationLoadout();
if (PlayerPrefs.HasKey(saveFileName))
loadout = (RCC_CustomizationLoadout)JsonUtility.FromJson(PlayerPrefs.GetString(saveFileName), typeof(RCC_CustomizationLoadout));
}
private void Reset() {
saveFileName = transform.name;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab717b6306496214c9a0b503faccd2f4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 100
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,65 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Customization demo used in the demo scene. Enables disables cameras and canvases.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Customization/RCC Customization Demo")]
public class RCC_CustomizationDemo : MonoBehaviour{
private static RCC_CustomizationDemo instance;
public static RCC_CustomizationDemo Instance {
get {
if (instance == null)
instance = FindObjectOfType<RCC_CustomizationDemo>();
return instance;
}
}
private RCC_CarControllerV3 vehicle;
public RCC_ShowroomCamera showroomCamera;
public RCC_Camera RCCCamera;
public GameObject RCCCanvas;
public GameObject modificationCanvas;
public Transform location;
public void EnableCustomization(RCC_CarControllerV3 carController) {
vehicle = carController;
RCCCamera.gameObject.SetActive(false);
showroomCamera.gameObject.SetActive(true);
RCCCanvas.SetActive(false);
modificationCanvas.SetActive(true);
RCC.Transport(vehicle, location.position, location.rotation);
RCC.SetControl(vehicle, false);
}
public void DisableCustomization() {
RCCCamera.gameObject.SetActive(true);
showroomCamera.gameObject.SetActive(false);
RCCCanvas.SetActive(true);
modificationCanvas.SetActive(false);
RCC.SetControl(vehicle, true);
vehicle = null;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87c077b502ca107428c9b34b9050500d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,30 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Customization loadout.
/// </summary>
[System.Serializable]
public class RCC_CustomizationLoadout{
public Color paint = new Color(1f, 1f, 1f, 0f);
public int spoiler = -1;
public int siren = -1;
public int wheel = -1;
public int engineLevel = 0;
public int handlingLevel = 0;
public int brakeLevel = 0;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: de20e2086fa3b5642a464c251c3a0c87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,150 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
/// <summary>
/// Modification manager. You'll need this script in your scene to make customization work. UI elements are not required, optional.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Customization/RCC Customization Manager")]
public class RCC_CustomizationManager : RCC_Singleton<RCC_CustomizationManager> {
public RCC_CustomizationApplier vehicle; // Current player vehicle.
public bool autoRegisterPlayerVehicle = true;
private void OnEnable() {
RCC_SceneManager.OnVehicleChanged += RCC_SceneManager_OnVehicleChanged;
}
private void RCC_SceneManager_OnVehicleChanged() {
vehicle = RCC_SceneManager.Instance.activePlayerVehicle.GetComponent<RCC_CustomizationApplier>();
}
/// <summary>
/// Sets the new target as currentApplier.
/// </summary>
/// <param name="newTarget"></param>
public void SetTarget(RCC_CustomizationApplier newTarget) {
vehicle = newTarget;
}
/// <summary>
/// Paints the target vehicle.
/// </summary>
/// <param name="color"></param>
public void Paint(Color color) {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.PaintManager.Paint(color);
if (vehicle.SpoilerManager && vehicle.SpoilerManager.paintSpoilers)
vehicle.SpoilerManager.Paint(color);
}
/// <summary>
/// Changes the wheels of the target vehicle.
/// </summary>
/// <param name="wheelIndex"></param>
public void ChangeWheels(int wheelIndex) {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.WheelManager.UpdateWheel(wheelIndex);
}
/// <summary>
/// Upgrades speed of the target vehicle.
/// </summary>
public void UpgradeSpeed() {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.UpgradeManager.UpgradeEngine();
}
/// <summary>
/// Upgrades handling of the target vehicle.
/// </summary>
public void UpgradeHandling() {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.UpgradeManager.UpgradeHandling();
}
/// <summary>
/// Upgrades brakes of the target vehicle.
/// </summary>
public void UpgradeBrake() {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.UpgradeManager.UpgradeBrake();
}
/// <summary>
/// Changes the spoiler of the target vehicle.
/// </summary>
/// <param name="index"></param>
public void Spoiler(int index) {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.SpoilerManager.Upgrade(index);
}
/// <summary>
/// Changes the siren of the target vehicle.
/// </summary>
/// <param name="index"></param>
public void Siren(int index) {
// If no any player vehicle, return.
if (!vehicle)
return;
vehicle.SirenManager.Upgrade(index);
}
private void OnDisable() {
RCC_SceneManager.OnVehicleChanged -= RCC_SceneManager_OnVehicleChanged;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14f38464e4f562846a75d65f36de8938
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Customization trigger used on customization demo scene. It will enable customization mode when player vehicle triggers.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Customization/RCC Customization Trigger")]
public class RCC_CustomizationTrigger : MonoBehaviour {
public GameObject trigger; // Trigger object.
private RCC_CarControllerV3 vehicle; // Current vehicle.
private void OnTriggerEnter(Collider other) {
// Getting car controller.
RCC_CarControllerV3 carController = other.GetComponentInParent<RCC_CarControllerV3>();
// If trigger is not a vehicle, return.
if (!carController)
return;
// Enable customization mode, disable trigger.
RCC_CustomizationDemo.Instance.EnableCustomization(carController);
trigger.SetActive(false);
vehicle = carController;
}
private void Update() {
// If no any vehicle triggered, return.
if (!vehicle || trigger.activeSelf)
return;
// Id distance is higher than 30 meters, reenable the trigger again.
if (Vector3.Distance(transform.position, vehicle.transform.position) > 30f) {
trigger.SetActive(true);
vehicle = null;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e95e295923ae86b4f924081deba3a14e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,481 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// A simple customizer example script used for receiving methods from UI elements and send them to RCC_Customization script. Also updates all UI elements for new spawned vehicles too.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC Customizer Example")]
public class RCC_CustomizerExample : RCC_Singleton<RCC_CustomizerExample> {
[Header("UI Menus")]
public GameObject wheelsMenu;
public GameObject configurationMenu;
public GameObject steeringAssistancesMenu;
public GameObject colorsMenu;
[Header("UI Sliders")]
public Slider frontCamber;
public Slider rearCamber;
public Slider frontSuspensionDistances;
public Slider rearSuspensionDistances;
public Slider frontSuspensionDampers;
public Slider rearSuspensionDampers;
public Slider frontSuspensionSprings;
public Slider rearSuspensionSprings;
public Slider gearShiftingThreshold;
public Slider clutchThreshold;
[Header("UI Toggles")]
public Toggle TCS;
public Toggle ABS;
public Toggle ESP;
public Toggle SH;
public Toggle counterSteering;
public Toggle steeringSensitivity;
public Toggle NOS;
public Toggle turbo;
public Toggle exhaustFlame;
public Toggle revLimiter;
public Toggle transmission;
[Header("UI InputFields")]
public InputField maxSpeed;
public InputField maxBrake;
public InputField maxTorque;
[Header("UI Dropdown Menus")]
public Dropdown drivetrainMode;
private void Start() {
CheckUIs();
}
public void CheckUIs() {
if (!RCC_SceneManager.Instance.activePlayerVehicle)
return;
if (frontCamber)
frontCamber.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.FrontLeftWheelCollider.camber);
if (rearCamber)
rearCamber.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.RearLeftWheelCollider.camber);
if (frontSuspensionDistances)
frontSuspensionDistances.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.FrontLeftWheelCollider.WheelCollider.suspensionDistance);
if (rearSuspensionDistances)
rearSuspensionDistances.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.RearLeftWheelCollider.WheelCollider.suspensionDistance);
if (frontSuspensionDampers)
frontSuspensionDampers.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.damper);
if (rearSuspensionDampers)
rearSuspensionDampers.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.damper);
if (frontSuspensionSprings)
frontSuspensionSprings.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.FrontLeftWheelCollider.WheelCollider.suspensionSpring.spring);
if (rearSuspensionSprings)
rearSuspensionSprings.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.RearLeftWheelCollider.WheelCollider.suspensionSpring.spring);
if (gearShiftingThreshold)
gearShiftingThreshold.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.gearShiftingThreshold);
if (clutchThreshold)
clutchThreshold.SetValueWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.clutchInertia);
if (TCS)
TCS.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.TCS);
if (ABS)
ABS.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.ABS);
if (ESP)
ESP.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.ESP);
if (SH)
SH.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.steeringHelper);
if (counterSteering)
counterSteering.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.useCounterSteering);
if (NOS)
NOS.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.useNOS);
if (turbo)
turbo.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.useTurbo);
if (exhaustFlame)
exhaustFlame.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.useExhaustFlame);
if (revLimiter)
revLimiter.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.useRevLimiter);
if (transmission)
transmission.SetIsOnWithoutNotify(RCC_SceneManager.Instance.activePlayerVehicle.AutomaticGear);
if (maxSpeed)
maxSpeed.text = RCC_SceneManager.Instance.activePlayerVehicle.maxspeed.ToString();
if (maxBrake)
maxBrake.text = RCC_SceneManager.Instance.activePlayerVehicle.brakeTorque.ToString();
if (maxTorque)
maxTorque.text = RCC_SceneManager.Instance.activePlayerVehicle.maxEngineTorque.ToString();
if (drivetrainMode) {
switch (RCC_SceneManager.Instance.activePlayerVehicle.wheelTypeChoise) {
case RCC_CarControllerV3.WheelType.FWD:
drivetrainMode.SetValueWithoutNotify(0);
break;
case RCC_CarControllerV3.WheelType.RWD:
drivetrainMode.SetValueWithoutNotify(1);
break;
case RCC_CarControllerV3.WheelType.AWD:
drivetrainMode.SetValueWithoutNotify(2);
break;
case RCC_CarControllerV3.WheelType.BIASED:
drivetrainMode.SetValueWithoutNotify(3);
break;
}
}
}
public void OpenMenu(GameObject activeMenu) {
if (activeMenu && activeMenu.activeInHierarchy) {
activeMenu.SetActive(false);
return;
}
if (wheelsMenu)
wheelsMenu.SetActive(false);
if (configurationMenu)
configurationMenu.SetActive(false);
if (steeringAssistancesMenu)
steeringAssistancesMenu.SetActive(false);
if (colorsMenu)
colorsMenu.SetActive(false);
if (activeMenu)
activeMenu.SetActive(true);
}
public void CloseAllMenus() {
if (wheelsMenu)
wheelsMenu.SetActive(false);
if (configurationMenu)
configurationMenu.SetActive(false);
if (steeringAssistancesMenu)
steeringAssistancesMenu.SetActive(false);
if (colorsMenu)
colorsMenu.SetActive(false);
}
public void SetCustomizationMode(bool state) {
if (!RCC_SceneManager.Instance.activePlayerVehicle)
return;
RCC_Customization.SetCustomizationMode(RCC_SceneManager.Instance.activePlayerVehicle, state);
if (state)
CheckUIs();
}
public void SetFrontCambersBySlider(Slider slider) {
RCC_Customization.SetFrontCambers(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetRearCambersBySlider(Slider slider) {
RCC_Customization.SetRearCambers(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void TogglePreviewSmokeByToggle(Toggle toggle) {
RCC_Customization.SetSmokeParticle(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void TogglePreviewExhaustFlameByToggle(Toggle toggle) {
RCC_Customization.SetExhaustFlame(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetSmokeColorByColorPicker(RCC_ColorPickerBySliders color) {
RCC_Customization.SetSmokeColor(RCC_SceneManager.Instance.activePlayerVehicle, 0, color.color);
}
public void SetHeadlightColorByColorPicker(RCC_ColorPickerBySliders color) {
RCC_Customization.SetHeadlightsColor(RCC_SceneManager.Instance.activePlayerVehicle, color.color);
}
public void ChangeWheelsBySlider(Slider slider) {
RCC_Customization.ChangeWheels(RCC_SceneManager.Instance.activePlayerVehicle, RCC_ChangableWheels.Instance.wheels[(int)slider.value].wheel, true);
}
public void SetFrontSuspensionTargetsBySlider(Slider slider) {
RCC_Customization.SetFrontSuspensionsTargetPos(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetRearSuspensionTargetsBySlider(Slider slider) {
RCC_Customization.SetRearSuspensionsTargetPos(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetAllSuspensionTargetsByButton(float strength) {
RCC_Customization.SetAllSuspensionsTargetPos(RCC_SceneManager.Instance.activePlayerVehicle, strength);
}
public void SetFrontSuspensionDistancesBySlider(Slider slider) {
RCC_Customization.SetFrontSuspensionsDistances(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetRearSuspensionDistancesBySlider(Slider slider) {
RCC_Customization.SetRearSuspensionsDistances(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetGearShiftingThresholdBySlider(Slider slider) {
RCC_Customization.SetGearShiftingThreshold(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, .5f, .95f));
}
public void SetClutchThresholdBySlider(Slider slider) {
RCC_Customization.SetClutchThreshold(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, .1f, .9f));
}
public void SetDriveTrainModeByDropdown(Dropdown dropdown) {
switch (dropdown.value) {
case 0:
RCC_Customization.SetDrivetrainMode(RCC_SceneManager.Instance.activePlayerVehicle, RCC_CarControllerV3.WheelType.FWD);
break;
case 1:
RCC_Customization.SetDrivetrainMode(RCC_SceneManager.Instance.activePlayerVehicle, RCC_CarControllerV3.WheelType.RWD);
break;
case 2:
RCC_Customization.SetDrivetrainMode(RCC_SceneManager.Instance.activePlayerVehicle, RCC_CarControllerV3.WheelType.AWD);
break;
}
}
public void SetCounterSteeringByToggle(Toggle toggle) {
RCC_Customization.SetCounterSteering(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetSteeringLimitByToggle(Toggle toggle) {
RCC_Customization.SetSteeringLimit(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetNOSByToggle(Toggle toggle) {
RCC_Customization.SetNOS(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetTurboByToggle(Toggle toggle) {
RCC_Customization.SetTurbo(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetExhaustFlameByToggle(Toggle toggle) {
RCC_Customization.SetUseExhaustFlame(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetRevLimiterByToggle(Toggle toggle) {
RCC_Customization.SetRevLimiter(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetFrontSuspensionsSpringForceBySlider(Slider slider) {
RCC_Customization.SetFrontSuspensionsSpringForce(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, 10000f, 100000f));
}
public void SetRearSuspensionsSpringForceBySlider(Slider slider) {
RCC_Customization.SetRearSuspensionsSpringForce(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, 10000f, 100000f));
}
public void SetFrontSuspensionsSpringDamperBySlider(Slider slider) {
RCC_Customization.SetFrontSuspensionsSpringDamper(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, 1000f, 10000f));
}
public void SetRearSuspensionsSpringDamperBySlider(Slider slider) {
RCC_Customization.SetRearSuspensionsSpringDamper(RCC_SceneManager.Instance.activePlayerVehicle, Mathf.Clamp(slider.value, 1000f, 10000f));
}
public void SetMaximumSpeedByInputField(InputField inputField) {
RCC_Customization.SetMaximumSpeed(RCC_SceneManager.Instance.activePlayerVehicle, StringToFloat(inputField.text, 200f));
inputField.text = RCC_SceneManager.Instance.activePlayerVehicle.maxspeed.ToString();
}
public void SetMaximumTorqueByInputField(InputField inputField) {
RCC_Customization.SetMaximumTorque(RCC_SceneManager.Instance.activePlayerVehicle, StringToFloat(inputField.text, 2000f));
inputField.text = RCC_SceneManager.Instance.activePlayerVehicle.maxEngineTorque.ToString();
}
public void SetMaximumBrakeByInputField(InputField inputField) {
RCC_Customization.SetMaximumBrake(RCC_SceneManager.Instance.activePlayerVehicle, StringToFloat(inputField.text, 2000f));
inputField.text = RCC_SceneManager.Instance.activePlayerVehicle.brakeTorque.ToString();
}
public void RepairCar() {
RCC_Customization.Repair(RCC_SceneManager.Instance.activePlayerVehicle);
}
public void SetESP(Toggle toggle) {
RCC_Customization.SetESP(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetABS(Toggle toggle) {
RCC_Customization.SetABS(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetTCS(Toggle toggle) {
RCC_Customization.SetTCS(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetSH(Toggle toggle) {
RCC_Customization.SetSH(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SetSHStrength(Slider slider) {
RCC_Customization.SetSHStrength(RCC_SceneManager.Instance.activePlayerVehicle, slider.value);
}
public void SetTransmission(Toggle toggle) {
RCC_Customization.SetTransmission(RCC_SceneManager.Instance.activePlayerVehicle, toggle.isOn);
}
public void SaveStats() {
RCC_Customization.SaveStats(RCC_SceneManager.Instance.activePlayerVehicle);
}
public void LoadStats() {
RCC_Customization.LoadStats(RCC_SceneManager.Instance.activePlayerVehicle);
CheckUIs();
}
public void ResetStats() {
int selectedVehicleIndex = 0;
if (FindObjectOfType<RCC_Demo>())
selectedVehicleIndex = FindObjectOfType<RCC_Demo>().selectedVehicleIndex;
RCC_Customization.ResetStats(RCC_SceneManager.Instance.activePlayerVehicle, RCC_DemoVehicles.Instance.vehicles[selectedVehicleIndex]);
CheckUIs();
}
private float StringToFloat(string stringValue, float defaultValue) {
float result = defaultValue;
float.TryParse(stringValue, out result);
return result;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8e5c2785c18fc424088dd743bf4bfff0
timeCreated: 1478460282
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,805 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Damage class.
/// </summary>
[System.Serializable]
public class RCC_Damage {
internal RCC_CarControllerV3 carController; // Car controller.
public bool automaticInstallation = true; // If set to enabled, all parts of the vehicle will be processed. If disabled, each part can be selected individually.
// Mesh deformation
[Space()]
[Header("Mesh Deformation")]
public bool meshDeformation = true;
public DeformationMode deformationMode = DeformationMode.Fast;
public enum DeformationMode { Accurate, Fast }
[Range(1, 100)] public int damageResolution = 100; // Resolution of the deformation.
public LayerMask damageFilter = -1; // LayerMask filter. Damage will be taken from the objects with these layers.
public float damageRadius = .5f; // Verticies in this radius will be effected on collisions.
public float damageMultiplier = 1f; // Damage multiplier.
public float maximumDamage = .5f; // Maximum Vert Distance For Limiting Damage. 0 Value Will Disable The Limit.
private readonly float minimumCollisionImpulse = .5f; // Minimum collision force.
private readonly float minimumVertDistanceForDamagedMesh = .002f; // Comparing Original Vertex Positions Between Last Vertex Positions To Decide Mesh Is Repaired Or Not.
public struct OriginalMeshVerts { public Vector3[] meshVerts; } // Struct for Original Mesh Verticies positions.
public struct OriginalWheelPos { public Vector3 wheelPosition; public Quaternion wheelRotation; }
public struct MeshCol { public Collider col; public bool created; }
public OriginalMeshVerts[] originalMeshData; // Array for struct above.
public OriginalMeshVerts[] damagedMeshData; // Array for struct above.
public OriginalWheelPos[] originalWheelData; // Array for struct above.
public OriginalWheelPos[] damagedWheelData; // Array for struct above.
[Space()]
[HideInInspector] public bool repairNow = false; // Repairing now.
[HideInInspector] public bool repaired = true; // Returns true if vehicle is completely repaired.
private bool deformingNow = false; // Deforming the mesh now.
private bool deformed = true; // Returns true if vehicle is completely deformed.
private float deformationTime = 0f; // Timer for deforming the vehicle.
[Space()]
public bool recalculateNormals = true; // Recalculate normals while deforming / restoring the mesh.
public bool recalculateBounds = true; // Recalculate bounds while deforming / restoring the mesh.
// Wheel deformation
[Space()]
[Header("Wheel Deformation")]
public bool wheelDamage = true; // Use wheel damage.
public float wheelDamageRadius = .5f; // Wheel damage radius.
public float wheelDamageMultiplier = 1f; // Wheel damage multiplier.
public bool wheelDetachment = true; // Use wheel detachment.
// Light deformation
[Space()]
[Header("Light Deformation")]
public bool lightDamage = true; // Use light damage.
public float lightDamageRadius = .5f; //Light damage radius.
public float lightDamageMultiplier = 1f; //Light damage multiplier.
// Part deformation
[Space()]
[Header("Part Deformation")]
public bool partDamage = true; // Use part damage.
public float partDamageRadius = .5f; //Light damage radius.
public float partDamageMultiplier = 1f; //Light damage multiplier.
[Space()]
public MeshFilter[] meshFilters; // Collected mesh filters.
public RCC_DetachablePart[] detachableParts; // Collected detachable parts.
public RCC_Light[] lights; // Collected lights.
public RCC_WheelCollider[] wheels; // Collected wheels.
private Vector3 contactPoint = Vector3.zero;
private Vector3[] contactPoints;
/// <summary>
/// Collecting all meshes and detachable parts of the vehicle.
/// </summary>
public void Initialize(RCC_CarControllerV3 _carController) {
// Getting the main car controller.
carController = _carController;
if (automaticInstallation) {
if (meshDeformation) {
MeshFilter[] allMeshFilters = carController.gameObject.GetComponentsInChildren<MeshFilter>(true);
List<MeshFilter> properMeshFilters = new List<MeshFilter>();
// Model import must be readable. If it's not readable, inform the developer. We don't wanna deform wheel meshes. Exclude any meshes belongs to the wheels.
foreach (MeshFilter mf in allMeshFilters) {
if (mf.mesh != null) {
if (!mf.mesh.isReadable)
Debug.LogError("Not deformable mesh detected. Mesh of the " + mf.transform.name + " isReadable is false; Read/Write must be enabled in import settings for this model!");
else if (!mf.transform.IsChildOf(carController.FrontLeftWheelTransform) && !mf.transform.IsChildOf(carController.FrontRightWheelTransform) && !mf.transform.IsChildOf(carController.RearLeftWheelTransform) && !mf.transform.IsChildOf(carController.RearRightWheelTransform))
properMeshFilters.Add(mf);
}
}
GetMeshes(properMeshFilters.ToArray());
}
if (lightDamage)
GetLights(carController.GetComponentsInChildren<RCC_Light>());
if (partDamage)
GetParts(carController.GetComponentsInChildren<RCC_DetachablePart>());
if (wheelDamage)
GetWheels(carController.GetComponentsInChildren<RCC_WheelCollider>());
}
}
/// <summary>
/// Gets all meshes.
/// </summary>
/// <param name="allMeshFilters"></param>
public void GetMeshes(MeshFilter[] allMeshFilters) {
meshFilters = allMeshFilters;
}
/// <summary>
/// Gets all lights.
/// </summary>
/// <param name="allLights"></param>
public void GetLights(RCC_Light[] allLights) {
lights = allLights;
}
/// <summary>
/// Gets all detachable parts.
/// </summary>
/// <param name="allParts"></param>
public void GetParts(RCC_DetachablePart[] allParts) {
detachableParts = allParts;
}
/// <summary>
/// Gets all wheels
/// </summary>
/// <param name="allWheels"></param>
public void GetWheels(RCC_WheelCollider[] allWheels) {
wheels = allWheels;
}
/// <summary>
/// We will be using two structs for deformed sections. Original part struction, and deformed part struction.
/// All damaged meshes and wheel transforms will be using these structs. At this section, we're creating them with original struction.
/// </summary>
//private void CheckMeshData() {
// originalMeshData = new OriginalMeshVerts[meshFilters.Length];
// for (int i = 0; i < meshFilters.Length; i++)
// originalMeshData[i].meshVerts = meshFilters[i].mesh.vertices;
// damagedMeshData = new OriginalMeshVerts[meshFilters.Length];
// for (int i = 0; i < meshFilters.Length; i++)
// damagedMeshData[i].meshVerts = meshFilters[i].mesh.vertices;
//}
/// <summary>
/// We will be using two structs for deformed sections. Original part struction, and deformed part struction.
/// All damaged meshes and wheel transforms will be using these structs. At this section, we're creating them with original struction.
/// </summary>
private void CheckWheelData() {
originalWheelData = new OriginalWheelPos[wheels.Length];
for (int i = 0; i < wheels.Length; i++) {
originalWheelData[i].wheelPosition = wheels[i].transform.localPosition;
originalWheelData[i].wheelRotation = wheels[i].transform.localRotation;
}
damagedWheelData = new OriginalWheelPos[wheels.Length];
for (int i = 0; i < wheels.Length; i++) {
damagedWheelData[i].wheelPosition = wheels[i].transform.localPosition;
damagedWheelData[i].wheelRotation = wheels[i].transform.localRotation;
}
}
/// <summary>
/// Moving deformed vertices to their original positions while repairing.
/// </summary>
public void UpdateRepair() {
if (!carController)
return;
// If vehicle is not repaired completely, and repairNow is enabled, restore all deformed meshes to their original structions.
if (!repaired && repairNow) {
//if (originalMeshData == null || originalMeshData.Length < 1)
// CheckMeshData();
int k;
repaired = true;
// If deformable mesh is still exists, get all verticies of the mesh first. And then move all single verticies to the original positions. If verticies are close enough to the original
// position, repaired = true;
for (k = 0; k < meshFilters.Length; k++) {
if (meshFilters[k] != null && meshFilters[k].mesh != null) {
// Get all verticies of the mesh first.
Vector3[] vertices = meshFilters[k].mesh.vertices;
for (int i = 0; i < vertices.Length; i++) {
// And then move all single verticies to the original positions
if (deformationMode == DeformationMode.Accurate)
vertices[i] += (originalMeshData[k].meshVerts[i] - vertices[i]) * (Time.deltaTime * 5f);
else
vertices[i] += (originalMeshData[k].meshVerts[i] - vertices[i]);
// If verticies are close enough to their original positions, repaired = true;
if ((originalMeshData[k].meshVerts[i] - vertices[i]).magnitude >= minimumVertDistanceForDamagedMesh)
repaired = false;
}
// We were using the variable named "vertices" above, therefore we need to set the new verticies to the damaged mesh data.
// Damaged mesh data also restored while repairing with this proccess.
damagedMeshData[k].meshVerts = vertices;
// Setting new verticies to the all meshes. Recalculating normals and bounds, and then optimizing. This proccess can be heavy for high poly meshes.
// You may want to disable last three lines.
meshFilters[k].mesh.SetVertices(vertices);
if (recalculateNormals)
meshFilters[k].mesh.RecalculateNormals();
if (recalculateBounds)
meshFilters[k].mesh.RecalculateBounds();
}
}
for (k = 0; k < wheels.Length; k++) {
if (wheels[k] != null) {
// Get all verticies of the mesh first.
Vector3 wheelPos = wheels[k].transform.localPosition;
// And then move all single verticies to the original positions
if (deformationMode == DeformationMode.Accurate)
wheelPos += (originalWheelData[k].wheelPosition - wheelPos) * (Time.deltaTime * 5f);
else
wheelPos += (originalWheelData[k].wheelPosition - wheelPos);
// If verticies are close enough to their original positions, repaired = true;
if ((originalWheelData[k].wheelPosition - wheelPos).magnitude >= minimumVertDistanceForDamagedMesh)
repaired = false;
// We were using the variable named "vertices" above, therefore we need to set the new verticies to the damaged mesh data.
// Damaged mesh data also restored while repairing with this proccess.
damagedWheelData[k].wheelPosition = wheelPos;
wheels[k].transform.localPosition = wheelPos;
wheels[k].transform.localRotation = Quaternion.identity;
if (!wheels[k].gameObject.activeSelf)
wheels[k].gameObject.SetActive(true);
carController.ESPBroken = false;
wheels[k].Inflate();
}
}
// Repairing and restoring all detachable parts of the vehicle.
for (int i = 0; i < detachableParts.Length; i++) {
if (detachableParts[i] != null)
detachableParts[i].OnRepair();
}
// Repairing and restoring all lights of the vehicle.
for (int i = 0; i < lights.Length; i++) {
if (lights[i] != null)
lights[i].OnRepair();
}
// If all meshes are completely restored, make sure repairing now is false.
if (repaired)
repairNow = false;
}
}
/// <summary>
/// Moving vertices of the collided meshes to the damaged positions while deforming.
/// </summary>
public void UpdateDamage() {
if (!carController)
return;
//if (originalMeshData == null || originalMeshData.Length < 1)
// CheckMeshData();
// If vehicle is not deformed completely, and deforming is enabled, deform all meshes to their damaged structions.
if (!deformed && deformingNow) {
int k;
deformed = true;
deformationTime += Time.deltaTime;
// If deformable mesh is still exists, get all verticies of the mesh first. And then move all single verticies to the damaged positions. If verticies are close enough to the original
// position, deformed = true;
for (k = 0; k < meshFilters.Length; k++) {
if (meshFilters[k] != null && meshFilters[k].mesh != null) {
// Get all verticies of the mesh first.
Vector3[] vertices = meshFilters[k].mesh.vertices;
// And then move all single verticies to the damaged positions.
for (int i = 0; i < vertices.Length; i++) {
if (deformationMode == DeformationMode.Accurate)
vertices[i] += (damagedMeshData[k].meshVerts[i] - vertices[i]) * (Time.deltaTime * 5f);
else
vertices[i] += (damagedMeshData[k].meshVerts[i] - vertices[i]);
}
// Setting new verticies to the all meshes. Recalculating normals and bounds, and then optimizing. This proccess can be heavy for high poly meshes.
meshFilters[k].mesh.SetVertices(vertices);
if (recalculateNormals)
meshFilters[k].mesh.RecalculateNormals();
if (recalculateBounds)
meshFilters[k].mesh.RecalculateBounds();
}
}
for (k = 0; k < wheels.Length; k++) {
if (wheels[k] != null) {
Vector3 vertices = wheels[k].transform.localPosition;
if (deformationMode == DeformationMode.Accurate)
vertices += (damagedWheelData[k].wheelPosition - vertices) * (Time.deltaTime * 5f);
else
vertices += (damagedWheelData[k].wheelPosition - vertices);
wheels[k].transform.localPosition = vertices;
//wheels[k].transform.localRotation = Quaternion.Euler(vertices);
}
}
// Make sure deforming proccess takes only 1 second.
if (deformationMode == DeformationMode.Accurate && deformationTime <= 1f)
deformed = false;
// If all meshes are completely deformed, make sure deforming is false and timer is set to 0.
if (deformed) {
deformingNow = false;
deformationTime = 0f;
}
}
}
/// <summary>
/// Deforming meshes.
/// </summary>
/// <param name="collision"></param>
/// <param name="impulse"></param>
private void DamageMesh(float impulse) {
if (!carController)
return;
//if (originalMeshData == null || originalMeshData.Length < 1)
// CheckMeshData();
// We will be checking all mesh filters with these contact points. If contact point is close enough to the mesh, deformation will be applied.
for (int i = 0; i < meshFilters.Length; i++) {
// If mesh filter is not null, enabled, and has a valid mesh data...
if (meshFilters[i] != null && meshFilters[i].mesh != null && meshFilters[i].gameObject.activeSelf) {
// Getting closest point to the mesh. Distance value will be set to closest point of the mesh - contact point.
float distance = Vector3.Distance(NearestVertex(meshFilters[i].transform, meshFilters[i], contactPoint), contactPoint);
// If distance between contact point and closest point of the mesh is in range...
if (distance <= damageRadius) {
// Collision direction.
Vector3 collisionDirection = contactPoint - carController.transform.position;
collisionDirection = -collisionDirection.normalized;
// All vertices of the mesh.
Vector3[] vertices = damagedMeshData[i].meshVerts;
for (int k = 0; k < vertices.Length; k++) {
// Contact point is a world space unit. We need to transform to the local space unit with mesh origin. Verticies are local space units.
Vector3 point = meshFilters[i].transform.InverseTransformPoint(contactPoint);
// Distance between vertex and contact point.
float distanceToVert = (point - vertices[k]).magnitude;
// If distance between vertex and contact point is in range...
if (distanceToVert <= damageRadius) {
// Default impulse of the collision.
float damage = impulse;
// The damage should decrease with distance from the contact point.
damage -= damage * Mathf.Clamp01(distanceToVert / damageRadius);
Quaternion rot = Quaternion.identity;
Vector3 vW = carController.transform.TransformPoint(vertices[k]);
vW += rot * (collisionDirection * damage * (damageMultiplier / 10f));
vertices[k] = carController.transform.InverseTransformPoint(vW);
// If distance between original vertex position and deformed vertex position exceeds limits, make sure they are in the limits.
if (maximumDamage > 0 && ((vertices[k] - originalMeshData[i].meshVerts[k]).magnitude) > maximumDamage)
vertices[k] = originalMeshData[i].meshVerts[k] + (vertices[k] - originalMeshData[i].meshVerts[k]).normalized * (maximumDamage);
}
}
}
}
}
}
/// <summary>
/// Deforming wheels. Actually changing their local positions and rotations based on the impact.
/// </summary>
/// <param name="collision"></param>
/// <param name="impulse"></param>
private void DamageWheel(float impulse) {
if (!carController)
return;
if (originalWheelData == null || originalWheelData.Length < 1)
CheckWheelData();
for (int i = 0; i < wheels.Length; i++) {
if (wheels[i] != null && wheels[i].gameObject.activeSelf) {
Vector3 wheelPos = damagedWheelData[i].wheelPosition;
Vector3 collisionDirection = contactPoint - carController.transform.position;
collisionDirection = -collisionDirection.normalized;
Vector3 closestPoint = wheels[i].WheelCollider.ClosestPointOnBounds(contactPoint);
float distance = Vector3.Distance(closestPoint, contactPoint);
if (distance < wheelDamageRadius) {
float damage = (impulse * wheelDamageMultiplier) / 30f;
// The damage should decrease with distance from the contact point.
damage -= damage * Mathf.Clamp01(distance / wheelDamageRadius);
Vector3 vW = carController.transform.TransformPoint(wheelPos);
vW += (collisionDirection * damage);
wheelPos = carController.transform.InverseTransformPoint(vW);
if (maximumDamage > 0 && ((wheelPos - originalWheelData[i].wheelPosition).magnitude) > maximumDamage) {
//wheelPos = originalWheelData[i].wheelPosition + (wheelPos - originalWheelData[i].wheelPosition).normalized * (maximumDamage);
if (wheelDetachment && wheels[i].gameObject.activeSelf)
DetachWheel(wheels[i]);
}
damagedWheelData[i].wheelPosition = wheelPos;
}
}
}
}
/// <summary>
/// Deforming the detachable parts.
/// </summary>
/// <param name="collision"></param>
/// <param name="impulse"></param>
private void DamagePart(float impulse) {
if (!carController)
return;
if (detachableParts != null && detachableParts.Length >= 1) {
for (int i = 0; i < detachableParts.Length; i++) {
if (detachableParts[i] != null && detachableParts[i].gameObject.activeSelf) {
if (detachableParts[i].partCollider != null) {
Vector3 closestPoint = detachableParts[i].partCollider.ClosestPointOnBounds(contactPoint);
float distance = Vector3.Distance(closestPoint, contactPoint);
float damage = impulse * partDamageMultiplier;
// The damage should decrease with distance from the contact point.
damage -= damage * Mathf.Clamp01(distance / damageRadius);
if (distance <= damageRadius)
detachableParts[i].OnCollision(damage);
} else {
if ((contactPoint - detachableParts[i].transform.position).magnitude < 1f)
detachableParts[i].OnCollision(impulse);
}
}
}
}
}
/// <summary>
/// Deforming the lights.
/// </summary>
/// <param name="collision"></param>
/// <param name="impulse"></param>
private void DamageLight(float impulse) {
if (!carController)
return;
if (lights != null && lights.Length >= 1) {
for (int i = 0; i < lights.Length; i++) {
if (lights[i] != null && lights[i].gameObject.activeSelf) {
if ((contactPoint - lights[i].transform.position).magnitude < lightDamageRadius)
lights[i].OnCollision(impulse * lightDamageMultiplier);
}
}
}
}
/// <summary>
/// Detaches the target wheel.
/// </summary>
/// <param name="wheelCollider"></param>
public void DetachWheel(RCC_WheelCollider wheelCollider) {
if (!carController)
return;
if (!wheelCollider)
return;
if (!wheelCollider.gameObject.activeSelf)
return;
wheelCollider.gameObject.SetActive(false);
Transform wheelModel = wheelCollider.wheelModel;
GameObject clonedWheel = GameObject.Instantiate(wheelModel.gameObject, wheelModel.transform.position, wheelModel.transform.rotation, null);
clonedWheel.SetActive(true);
clonedWheel.AddComponent<Rigidbody>();
GameObject clonedMeshCollider = new GameObject("Mesh Collider");
clonedMeshCollider.transform.SetParent(clonedWheel.transform, false);
clonedMeshCollider.transform.position = RCC_GetBounds.GetBoundsCenter(clonedWheel.transform);
MeshCollider mc = clonedMeshCollider.AddComponent<MeshCollider>();
MeshFilter biggestMesh = RCC_GetBounds.GetBiggestMesh(clonedWheel.transform);
mc.sharedMesh = biggestMesh.mesh;
mc.convex = true;
carController.ESPBroken = true;
}
/// <summary>
/// Raises the collision enter event.
/// </summary>
/// <param name="collision">Collision.</param>
public void OnCollision(Collision collision) {
if (!carController)
return;
if (!carController.useDamage)
return;
if (((1 << collision.gameObject.layer) & damageFilter) != 0) {
float impulse = collision.impulse.magnitude / 10000f;
if (collision.rigidbody)
impulse *= collision.rigidbody.mass / 1000f;
if (impulse < minimumCollisionImpulse)
impulse = 0f;
if (impulse > 10f)
impulse = 10f;
if (impulse > 0f) {
deformingNow = true;
deformed = false;
repairNow = false;
repaired = false;
// First, we are getting all contact points.
ContactPoint[] contacts = collision.contacts;
contactPoints = new Vector3[contacts.Length];
for (int i = 0; i < contactPoints.Length; i++)
contactPoints[i] = contacts[i].point;
contactPoint = ContactPointsMagnitude();
if (meshFilters != null && meshFilters.Length >= 1 && meshDeformation)
DamageMesh(impulse);
if (wheels != null && wheels.Length >= 1 && wheelDamage)
DamageWheel(impulse);
if (detachableParts != null && detachableParts.Length >= 1 && partDamage)
DamagePart(impulse);
if (lights != null && lights.Length >= 1 && lightDamage)
DamageLight(impulse);
}
}
}
/// <summary>
/// Raises the collision enter event.
/// </summary>
/// <param name="collision">Collision.</param>
public void OnCollisionWithRay(RaycastHit hit, float impulse) {
if (!carController)
return;
if (!carController.useDamage)
return;
if (impulse < minimumCollisionImpulse)
impulse = 0f;
if (impulse > 10f)
impulse = 10f;
if (impulse > 0f) {
deformingNow = true;
deformed = false;
repairNow = false;
repaired = false;
// First, we are getting all contact points.
contactPoint = hit.point;
if (meshFilters != null && meshFilters.Length >= 1 && meshDeformation)
DamageMesh(impulse);
if (wheels != null && wheels.Length >= 1 && wheelDamage)
DamageWheel(impulse);
if (detachableParts != null && detachableParts.Length >= 1 && partDamage)
DamagePart(impulse);
if (lights != null && lights.Length >= 1 && lightDamage)
DamageLight(impulse);
}
}
private Vector3 ContactPointsMagnitude() {
Vector3 magnitude = Vector3.zero;
for (int i = 0; i < contactPoints.Length; i++)
magnitude += contactPoints[i];
magnitude /= contactPoints.Length;
return magnitude;
}
/// <summary>
/// Finds closest vertex to the target point.
/// </summary>
/// <param name="trans"></param>
/// <param name="mf"></param>
/// <param name="point"></param>
/// <returns></returns>
public static Vector3 NearestVertex(Transform trans, MeshFilter mf, Vector3 point) {
// Convert point to local space.
point = trans.InverseTransformPoint(point);
float minDistanceSqr = Mathf.Infinity;
Vector3 nearestVertex = Vector3.zero;
// Check all vertices to find nearest.
foreach (Vector3 vertex in mf.mesh.vertices) {
Vector3 diff = point - vertex;
float distSqr = diff.sqrMagnitude;
if (distSqr < minDistanceSqr) {
minDistanceSqr = distSqr;
nearestVertex = vertex;
}
}
// Convert nearest vertex back to the world space.
return trans.TransformPoint(nearestVertex);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70a63d26439cf904a8f9682ba12ec483
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
//----------------------------------------------
// 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;
using UnityEngine.UI;
/// <summary>
/// Changes HUD image colors by UI Sliders.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC UI Dashboard Colors")]
public class RCC_DashboardColors : MonoBehaviour {
public Image[] huds;
public Color hudColor = Color.white;
public Slider hudColor_R;
public Slider hudColor_G;
public Slider hudColor_B;
private void Start() {
if (huds == null || huds.Length < 1)
enabled = false;
if (hudColor_R && hudColor_G && hudColor_B) {
hudColor_R.value = hudColor.r;
hudColor_G.value = hudColor.g;
hudColor_B.value = hudColor.b;
}
}
private void Update() {
if (hudColor_R && hudColor_G && hudColor_B)
hudColor = new Color(hudColor_R.value, hudColor_G.value, hudColor_B.value);
for (int i = 0; i < huds.Length; i++) {
if (huds[i] != null)
huds[i].color = new Color(hudColor.r, hudColor.g, hudColor.b, huds[i].color.a);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bbc9f1adb9945a54bb5b394902ad2699
timeCreated: 1460237445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,208 @@
//----------------------------------------------
// 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>
/// Receiving inputs from active vehicle on your scene, and feeds dashboard needles, texts, images.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC UI Dashboard Inputs")]
public class RCC_DashboardInputs : MonoBehaviour {
public RCC_CarControllerV3 vehicle; // Target vehicle.
public bool autoAssignVehicle = true; // Auto assign target vehicle as player vehicle from the RCC_SceneManager.
// Needles.
[Header("Needles")]
public GameObject RPMNeedle;
public GameObject KMHNeedle;
public GameObject turboGauge;
public GameObject turboNeedle;
public GameObject NOSGauge;
public GameObject NoSNeedle;
public GameObject heatGauge;
public GameObject heatNeedle;
public GameObject fuelGauge;
public GameObject fuelNeedle;
// Needle rotations.
private float RPMNeedleRotation = 0f;
private float KMHNeedleRotation = 0f;
private float BoostNeedleRotation = 0f;
private float NoSNeedleRotation = 0f;
private float heatNeedleRotation = 0f;
private float fuelNeedleRotation = 0f;
// Variables of the player vehicle.
[HideInInspector] public float RPM;
[HideInInspector] public float KMH;
[HideInInspector] public int direction = 1;
[HideInInspector] public float Gear;
[HideInInspector] public bool changingGear = false;
[HideInInspector] public bool NGear = false;
[HideInInspector] public bool ABS = false;
[HideInInspector] public bool ESP = false;
[HideInInspector] public bool Park = false;
[HideInInspector] public bool Headlights = false;
[HideInInspector] public RCC_CarControllerV3.IndicatorsOn indicators;
private void Update() {
if (autoAssignVehicle && RCC_SceneManager.Instance.activePlayerVehicle)
vehicle = RCC_SceneManager.Instance.activePlayerVehicle;
else
vehicle = null;
// If no any player vehicle, return.
if (!vehicle)
return;
// If player vehicle is not controllable or controlled by AI, return.
if (!vehicle.canControl || vehicle.externalController)
return;
// If nos gauge is selected, enable or disable gauge related to vehicle.
if (NOSGauge) {
if (vehicle.useNOS) {
if (!NOSGauge.activeSelf)
NOSGauge.SetActive(true);
} else {
if (NOSGauge.activeSelf)
NOSGauge.SetActive(false);
}
}
// If turbo gauge is selected, enable or disable turbo gauge related to vehicle.
if (turboGauge) {
if (vehicle.useTurbo) {
if (!turboGauge.activeSelf)
turboGauge.SetActive(true);
} else {
if (turboGauge.activeSelf)
turboGauge.SetActive(false);
}
}
// If heat gauge is selected, enable or disable heat gauge related to vehicle.
if (heatGauge) {
if (vehicle.useEngineHeat) {
if (!heatGauge.activeSelf)
heatGauge.SetActive(true);
} else {
if (heatGauge.activeSelf)
heatGauge.SetActive(false);
}
}
// If fuel gauge is selected, enable or disable fuel gauge related to vehicle.
if (fuelGauge) {
if (vehicle.useFuelConsumption) {
if (!fuelGauge.activeSelf)
fuelGauge.SetActive(true);
} else {
if (fuelGauge.activeSelf)
fuelGauge.SetActive(false);
}
}
// Getting variables from the player vehicle.
RPM = vehicle.engineRPM;
KMH = vehicle.speed;
direction = vehicle.direction;
Gear = vehicle.currentGear;
changingGear = vehicle.changingGear;
NGear = vehicle.NGear;
ABS = vehicle.ABSAct;
ESP = vehicle.ESPAct;
Park = vehicle.handbrakeInput > .1f ? true : false;
Headlights = vehicle.lowBeamHeadLightsOn || vehicle.highBeamHeadLightsOn;
indicators = vehicle.indicatorsOn;
// If RPM needle is selected, assign rotation of the needle.
if (RPMNeedle) {
RPMNeedleRotation = (vehicle.engineRPM / 50f);
RPMNeedleRotation = Mathf.Clamp(RPMNeedleRotation, 0f, 180f);
RPMNeedle.transform.eulerAngles = new Vector3(RPMNeedle.transform.eulerAngles.x, RPMNeedle.transform.eulerAngles.y, -RPMNeedleRotation);
}
// If KMH needle is selected, assign rotation of the needle.
if (KMHNeedle) {
if (RCC_Settings.Instance.units == RCC_Settings.Units.KMH)
KMHNeedleRotation = (vehicle.speed);
else
KMHNeedleRotation = (vehicle.speed * 0.62f);
KMHNeedle.transform.eulerAngles = new Vector3(KMHNeedle.transform.eulerAngles.x, KMHNeedle.transform.eulerAngles.y, -KMHNeedleRotation);
}
// If turbo needle is selected, assign rotation of the needle.
if (turboNeedle) {
BoostNeedleRotation = (vehicle.turboBoost / 30f) * 270f;
turboNeedle.transform.eulerAngles = new Vector3(turboNeedle.transform.eulerAngles.x, turboNeedle.transform.eulerAngles.y, -BoostNeedleRotation);
}
// If nos needle is selected, assign rotation of the needle.
if (NoSNeedle) {
NoSNeedleRotation = (vehicle.NoS / 100f) * 270f;
NoSNeedle.transform.eulerAngles = new Vector3(NoSNeedle.transform.eulerAngles.x, NoSNeedle.transform.eulerAngles.y, -NoSNeedleRotation);
}
// If heat needle is selected, assign rotation of the needle.
if (heatNeedle) {
heatNeedleRotation = (vehicle.engineHeat / 110f) * 270f;
heatNeedle.transform.eulerAngles = new Vector3(heatNeedle.transform.eulerAngles.x, heatNeedle.transform.eulerAngles.y, -heatNeedleRotation);
}
// If fuel needle is selected, assign rotation of the needle.
if (fuelNeedle) {
fuelNeedleRotation = (vehicle.fuelTank / vehicle.fuelTankCapacity) * 270f;
fuelNeedle.transform.eulerAngles = new Vector3(fuelNeedle.transform.eulerAngles.x, fuelNeedle.transform.eulerAngles.y, -fuelNeedleRotation);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9316b71f8f092f44094427586ee457fa
timeCreated: 1425905462
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,296 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// Receiving inputs from active vehicle on your scene, and feeds visual dashboard needles (Not UI).
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Visual Dashboard Objects")]
public class RCC_DashboardObjects : MonoBehaviour {
// Car controller.
public RCC_CarControllerV3 CarController {
get {
if (carController == null)
carController = GetComponentInParent<RCC_CarControllerV3>();
return carController;
}
}
private RCC_CarControllerV3 carController;
[System.Serializable]
public class RPMDial {
public GameObject dial;
public float multiplier = .05f;
public RotateAround rotateAround = RotateAround.Z;
private Quaternion dialOrgRotation = Quaternion.identity;
public Text text;
public void Init() {
if (dial)
dialOrgRotation = dial.transform.localRotation;
}
public void Update(float value) {
Vector3 targetAxis = Vector3.forward;
switch (rotateAround) {
case RotateAround.X:
targetAxis = Vector3.right;
break;
case RotateAround.Y:
targetAxis = Vector3.up;
break;
case RotateAround.Z:
targetAxis = Vector3.forward;
break;
}
dial.transform.localRotation = dialOrgRotation * Quaternion.AngleAxis(-multiplier * value, targetAxis);
if (text)
text.text = value.ToString("F0");
}
}
[System.Serializable]
public class SpeedoMeterDial {
public GameObject dial;
public float multiplier = 1f;
public RotateAround rotateAround = RotateAround.Z;
private Quaternion dialOrgRotation = Quaternion.identity;
public Text text;
public void Init() {
if (dial)
dialOrgRotation = dial.transform.localRotation;
}
public void Update(float value) {
Vector3 targetAxis = Vector3.forward;
switch (rotateAround) {
case RotateAround.X:
targetAxis = Vector3.right;
break;
case RotateAround.Y:
targetAxis = Vector3.up;
break;
case RotateAround.Z:
targetAxis = Vector3.forward;
break;
}
dial.transform.localRotation = dialOrgRotation * Quaternion.AngleAxis(-multiplier * value, targetAxis);
if (text)
text.text = value.ToString("F0");
}
}
[System.Serializable]
public class FuelDial {
public GameObject dial;
public float multiplier = .1f;
public RotateAround rotateAround = RotateAround.Z;
private Quaternion dialOrgRotation = Quaternion.identity;
public Text text;
public void Init() {
if (dial)
dialOrgRotation = dial.transform.localRotation;
}
public void Update(float value) {
Vector3 targetAxis = Vector3.forward;
switch (rotateAround) {
case RotateAround.X:
targetAxis = Vector3.right;
break;
case RotateAround.Y:
targetAxis = Vector3.up;
break;
case RotateAround.Z:
targetAxis = Vector3.forward;
break;
}
dial.transform.localRotation = dialOrgRotation * Quaternion.AngleAxis(-multiplier * value, targetAxis);
if (text)
text.text = value.ToString("F0");
}
}
[System.Serializable]
public class HeatDial {
public GameObject dial;
public float multiplier = .1f;
public RotateAround rotateAround = RotateAround.Z;
private Quaternion dialOrgRotation = Quaternion.identity;
public Text text;
public void Init() {
if (dial)
dialOrgRotation = dial.transform.localRotation;
}
public void Update(float value) {
Vector3 targetAxis = Vector3.forward;
switch (rotateAround) {
case RotateAround.X:
targetAxis = Vector3.right;
break;
case RotateAround.Y:
targetAxis = Vector3.up;
break;
case RotateAround.Z:
targetAxis = Vector3.forward;
break;
}
dial.transform.localRotation = dialOrgRotation * Quaternion.AngleAxis(-multiplier * value, targetAxis);
if (text)
text.text = value.ToString("F0");
}
}
[System.Serializable]
public class InteriorLight {
public Light light;
public float intensity = 1f;
public LightRenderMode renderMode = LightRenderMode.Auto;
public void Update(bool state) {
if (!light.enabled)
light.enabled = true;
light.renderMode = renderMode;
light.intensity = state ? intensity : 0f;
}
}
[Space()]
public RPMDial rPMDial = new RPMDial();
[Space()]
public SpeedoMeterDial speedDial = new SpeedoMeterDial();
[Space()]
public FuelDial fuelDial = new FuelDial();
[Space()]
public HeatDial heatDial = new HeatDial();
[Space()]
public InteriorLight[] interiorLights = new InteriorLight[0];
public enum RotateAround { X, Y, Z }
private void Awake() {
// Initializing dials.
rPMDial.Init();
speedDial.Init();
fuelDial.Init();
heatDial.Init();
}
private void Update() {
// If no vehicle found, return.
if (!CarController)
return;
Dials();
Lights();
}
/// <summary>
/// Updates dials rotation.
/// </summary>
private void Dials() {
if (rPMDial.dial != null)
rPMDial.Update(CarController.engineRPM);
if (speedDial.dial != null)
speedDial.Update(CarController.speed);
if (fuelDial.dial != null)
fuelDial.Update(CarController.fuelTank);
if (heatDial.dial != null)
heatDial.Update(CarController.engineHeat);
}
/// <summary>
/// Updates lights of the dash.
/// </summary>
private void Lights() {
for (int i = 0; i < interiorLights.Length; i++)
interiorLights[i].Update(CarController.lowBeamHeadLightsOn);
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a4a253835d939a94dbd5fefa86ceba6e
timeCreated: 1499564966
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,194 @@
//----------------------------------------------
// 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;
using UnityEngine.SceneManagement;
/// <summary>
/// A simple manager script for all demo scenes. It has an array of spawnable player vehicles, public methods, setting new behavior modes, restart, and quit application.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC Demo Manager")]
public class RCC_Demo : MonoBehaviour {
[HideInInspector] public int selectedVehicleIndex = 0; // An integer index value used to spawn a new vehicle.
[HideInInspector] public int selectedBehaviorIndex = 0; // An integer index value used to set a new behavior mode.
/// <summary>
/// An integer index value used for spawning a new vehicle.
/// </summary>
/// <param name="index"></param>
public void SelectVehicle(int index) {
selectedVehicleIndex = index;
}
/// <summary>
/// Spawns the player vehicle.
/// </summary>
public void Spawn() {
// Last known position and rotation of last active vehicle.
Vector3 lastKnownPos = new Vector3();
Quaternion lastKnownRot = new Quaternion();
// Checking if there is a player vehicle on the scene.
if (RCC_SceneManager.Instance.activePlayerVehicle) {
lastKnownPos = RCC_SceneManager.Instance.activePlayerVehicle.transform.position;
lastKnownRot = RCC_SceneManager.Instance.activePlayerVehicle.transform.rotation;
}
// If last known position and rotation is not assigned, camera's position and rotation will be used.
if (lastKnownPos == Vector3.zero) {
if (RCC_SceneManager.Instance.activePlayerCamera) {
lastKnownPos = RCC_SceneManager.Instance.activePlayerCamera.transform.position;
lastKnownRot = RCC_SceneManager.Instance.activePlayerCamera.transform.rotation;
}
}
// We don't need X and Z rotation angle. Just Y.
lastKnownRot.x = 0f;
lastKnownRot.z = 0f;
// Is there any last vehicle?
RCC_CarControllerV3 lastVehicle = RCC_SceneManager.Instance.activePlayerVehicle;
#if BCG_ENTEREXIT
BCG_EnterExitVehicle lastEnterExitVehicle;
bool enterExitVehicleFound = false;
if (lastVehicle) {
lastEnterExitVehicle = lastVehicle.GetComponentInChildren<BCG_EnterExitVehicle>();
if (lastEnterExitVehicle && lastEnterExitVehicle.driver) {
enterExitVehicleFound = true;
BCG_EnterExitManager.Instance.waitTime = 10f;
lastEnterExitVehicle.driver.GetOut();
}
}
#endif
// If we have controllable vehicle by player on scene, destroy it.
if (lastVehicle)
Destroy(lastVehicle.gameObject);
// Here we are creating our new vehicle.
RCC.SpawnRCC(RCC_DemoVehicles.Instance.vehicles[selectedVehicleIndex], lastKnownPos, lastKnownRot, true, true, true);
#if BCG_ENTEREXIT
if (enterExitVehicleFound) {
lastEnterExitVehicle = null;
lastEnterExitVehicle = RCC_SceneManager.Instance.activePlayerVehicle.GetComponentInChildren<BCG_EnterExitVehicle>();
if (!lastEnterExitVehicle)
lastEnterExitVehicle = RCC_SceneManager.Instance.activePlayerVehicle.gameObject.AddComponent<BCG_EnterExitVehicle>();
if (BCG_EnterExitManager.Instance.activePlayer && lastEnterExitVehicle && lastEnterExitVehicle.driver == null) {
BCG_EnterExitManager.Instance.waitTime = 10f;
BCG_EnterExitManager.Instance.activePlayer.GetIn(lastEnterExitVehicle);
}
}
#endif
}
/// <summary>
/// An integer index value used for setting behavior mode.
/// </summary>
/// <param name="index"></param>
public void SetBehavior(int index) {
selectedBehaviorIndex = index;
}
/// <summary>
/// Here we are setting new selected behavior to corresponding one.
/// </summary>
public void InitBehavior() {
RCC.SetBehavior(selectedBehaviorIndex);
}
/// <summary>
/// Sets the mobile controller type.
/// </summary>
/// <param name="index"></param>
public void SetMobileController(int index) {
switch (index) {
case 0:
RCC.SetMobileController(RCC_Settings.MobileController.TouchScreen);
break;
case 1:
RCC.SetMobileController(RCC_Settings.MobileController.Gyro);
break;
case 2:
RCC.SetMobileController(RCC_Settings.MobileController.SteeringWheel);
break;
case 3:
RCC.SetMobileController(RCC_Settings.MobileController.Joystick);
break;
}
}
/// <summary>
/// Sets the quality.
/// </summary>
/// <param name="index">Index.</param>
public void SetQuality(int index) {
QualitySettings.SetQualityLevel(index);
}
/// <summary>
/// Simply restarting the current scene.
/// </summary>
public void RestartScene() {
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
/// <summary>
/// Simply quit application. Not working on Editor.
/// </summary>
public void Quit() {
Application.Quit();
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f8647f49632a2254fac2ad6d517cdef8
timeCreated: 1525133881
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// All demo materials.
/// </summary>
public class RCC_DemoMaterials : ScriptableObject {
#region singleton
private static RCC_DemoMaterials instance;
public static RCC_DemoMaterials Instance { get { if (instance == null) instance = Resources.Load("RCC Assets/RCC_DemoMaterials") as RCC_DemoMaterials; return instance; } }
#endregion
public Material[] demoMaterials;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e163df8e2f417a741bc43cd77db7442c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// All demo vehicles.
/// </summary>
public class RCC_DemoVehicles : ScriptableObject {
public RCC_CarControllerV3[] vehicles;
#region singleton
private static RCC_DemoVehicles instance;
public static RCC_DemoVehicles Instance { get { if (instance == null) instance = Resources.Load("RCC Assets/RCC_DemoVehicles") as RCC_DemoVehicles; return instance; } }
#endregion
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67c763223835deb4fba9bf832986512a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,279 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Detachable part of the vehicle.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Detachable Part")]
public class RCC_DetachablePart : MonoBehaviour {
public ConfigurableJoint Joint {
get {
if (_joint == null)
_joint = GetComponentInParent<ConfigurableJoint>();
return _joint;
}
set {
_joint = value;
}
}
private ConfigurableJoint _joint;
public Rigidbody Rigid {
get {
if (_rigid == null)
_rigid = GetComponentInParent<Rigidbody>();
return _rigid;
}
set {
_rigid = value;
}
}
private Rigidbody _rigid;
private RCC_Joint jointProperties; // Joint properties class.
public Transform COM; // Center of mass.
public Collider partCollider; // Collider.
public enum DetachablePartType { Hood, Trunk, Door, Bumper_F, Bumper_R }
public DetachablePartType partType = DetachablePartType.Hood;
public bool lockAtStart = true; // Lock all motions of Configurable Joint at start.
public float strength = 100f; // Strength of the part.
internal float orgStrength = 100f; // Original strength of the part. We will be using this original value while restoring the part.
public bool isBreakable = true; // Can it break at certain damage?
public bool broken = false; // Is this part broken currently?
public int loosePoint = 35; // Part will be broken at this point.
public int detachPoint = 0; // Part will be detached at this point.
public float deactiveAfterSeconds = 5f; // Part will be deactivated after the detachment.
public Vector3 addTorqueAfterLoose = Vector3.zero; // Adds angular velocity related to speed after the brake point reached.
private void Start() {
orgStrength = strength; // Getting original strength of the part. We will be using this original value while restoring the part.
// Getting collider.
if (!partCollider)
partCollider = GetComponentInChildren<Collider>();
if (partCollider)
partCollider.enabled = false;
// Setting center of mass if selected.
if (COM)
Rigid.centerOfMass = transform.InverseTransformPoint(COM.transform.position);
// Disable the script if configurable joint not found.
if (!Joint) {
Debug.LogWarning("Configurable Joint not found for " + gameObject.name + "!");
enabled = false;
return;
}
// Getting original properties of the joint. We will be using the original data for restoring the part while repairing.
GetJointProperties();
// Locks all motions of Configurable Joint at start.
if (lockAtStart)
StartCoroutine(LockJoint());
}
/// <summary>
/// Getting original properties of the joint. We will be using the original data for restoring the part while repairing.
/// </summary>
private void GetJointProperties() {
jointProperties = new RCC_Joint();
jointProperties.GetProperties(Joint);
}
/// <summary>
/// Locks the parts.
/// </summary>
private IEnumerator LockJoint() {
yield return new WaitForFixedUpdate();
RCC_Joint.LockPart(Joint);
}
private void Update() {
// If part is broken, return.
if (broken)
return;
// If part is weak and loosen, apply angular velocity related to vehicle speed.
if (addTorqueAfterLoose != Vector3.zero && strength <= loosePoint) {
float speed = transform.InverseTransformDirection(Rigid.velocity).z; // Local speed.
Rigid.AddRelativeTorque(new Vector3(addTorqueAfterLoose.x * speed, addTorqueAfterLoose.y * speed, addTorqueAfterLoose.z * speed)); // Applying local torque.
}
}
/// <summary>
/// On collision with impulse.
/// </summary>
/// <param name="impulse"></param>
public void OnCollision(float impulse) {
// If part is broken, return.
if (broken)
return;
// Decreasing strength of the part related to collision impulse.
strength -= impulse * 5f;
strength = Mathf.Clamp(strength, 0f, Mathf.Infinity);
// Check joint of the part based on strength.
CheckJoint();
}
/// <summary>
/// Checks joint of the part based on strength.
/// </summary>
private void CheckJoint() {
// If part is broken, return.
if (broken)
return;
// If strength is 0, unlock the parts and set their joint limits to none. Detach them from the vehicle. If strength is below detach point, only set joint limits to none.
if (isBreakable && strength <= detachPoint) {
if (Joint) {
if (partCollider)
partCollider.enabled = true;
broken = true;
Destroy(Joint);
transform.SetParent(null);
StartCoroutine(DisablePart(deactiveAfterSeconds));
}
} else if (strength <= loosePoint) {
if (partCollider)
partCollider.enabled = false;
if (Joint) {
Joint.angularXMotion = jointProperties.jointMotionAngularX;
Joint.angularYMotion = jointProperties.jointMotionAngularY;
Joint.angularZMotion = jointProperties.jointMotionAngularZ;
Joint.xMotion = jointProperties.jointMotionX;
Joint.yMotion = jointProperties.jointMotionY;
Joint.zMotion = jointProperties.jointMotionZ;
}
}
}
/// <summary>
/// Repairs, and restores the part.
/// </summary>
public void OnRepair() {
// Enabling gameobject first if it's disabled.
if (!gameObject.activeSelf)
gameObject.SetActive(true);
if (partCollider)
partCollider.enabled = false;
// If joint is removed and part is detached, adding new configurable joint component. Configurable Joints cannot be toggled on or off. Therefore, we need to destroy and create configurable joints.
if (Joint == null) {
// Setting properties of the configurable joint to original properties.
Joint = gameObject.AddComponent<ConfigurableJoint>();
jointProperties.SetProperties(Joint);
} else {
// Setting strength to original strength value. And make sure part is not broken anymore.
strength = orgStrength;
broken = false;
// Locking the part.
Joint.angularXMotion = ConfigurableJointMotion.Locked;
Joint.angularYMotion = ConfigurableJointMotion.Locked;
Joint.angularZMotion = ConfigurableJointMotion.Locked;
Joint.xMotion = ConfigurableJointMotion.Locked;
Joint.yMotion = ConfigurableJointMotion.Locked;
Joint.zMotion = ConfigurableJointMotion.Locked;
}
}
/// <summary>
/// Disables the part with delay.
/// </summary>
/// <param name="delay"></param>
/// <returns></returns>
private IEnumerator DisablePart(float delay) {
yield return new WaitForSeconds(delay);
gameObject.SetActive(false);
}
private void Reset() {
if(!string.IsNullOrEmpty(RCC_Settings.Instance.DetachablePartLayer))
gameObject.layer = LayerMask.NameToLayer(RCC_Settings.Instance.DetachablePartLayer);
if (!COM) {
COM = new GameObject("COM").transform;
COM.SetParent(transform);
COM.localPosition = Vector3.zero;
COM.localRotation = Quaternion.identity;
}
if (!Joint)
Joint = gameObject.AddComponent<ConfigurableJoint>();
Joint.connectedBody = GetComponentInParent<RCC_CarControllerV3>().gameObject.GetComponent<Rigidbody>();
if (!Rigid)
Rigid = gameObject.AddComponent<Rigidbody>();
Rigid.mass = 35f;
Rigid.interpolation = RigidbodyInterpolation.Interpolate;
Rigid.collisionDetectionMode = CollisionDetectionMode.Continuous;
if (!partCollider)
partCollider = GetComponentInChildren<Collider>();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a98b2e6e19475c45bec725d857f98d7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,96 @@
//----------------------------------------------
// 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>
/// Applies emission texture to the target renderer.
/// </summary>
[System.Serializable]
public class RCC_Emission {
public Renderer lightRenderer; // Renderer of the light.
public int materialIndex = 0; // Index of the material.
public bool noTexture = false; // Material has no texture.
public bool applyAlpha = false; // Apply alpha channel.
[Range(.1f, 10f)] public float multiplier = 1f; // Emission multiplier.
private int emissionColorID; // ID of the emission color.
private Material material;
private Color targetColor;
private bool initialized = false;
/// <summary>
/// Initializes the emission.
/// </summary>
public void Init() {
// If no renderer selected, return.
if (!lightRenderer) {
Debug.LogError("No renderer selected for emission! Selected a renderer for this light, or disable emission.");
return;
}
material = lightRenderer.materials[materialIndex]; // Getting correct material index.
material.EnableKeyword("_EMISSION"); // Enabling keyword of the material for emission.
emissionColorID = Shader.PropertyToID("_EmissionColor"); // Getting ID of the emission color.
// If material has no property for emission color, return.
if (!material.HasProperty(emissionColorID))
Debug.LogError("Material has no emission color id!");
initialized = true; // Emission initialized.
}
/// <summary>
/// Sets emissive strength of the material.
/// </summary>
/// <param name="sharedLight"></param>
public void Emission(Light sharedLight) {
// If not initialized, initialize and return.
if (!initialized) {
Init();
return;
}
// If light is not enabled, return with 0 intensity.
if (!sharedLight.enabled)
targetColor = Color.white * 0f;
// If intensity of the light is close to 0, return with 0 intensity.
if (Mathf.Approximately(sharedLight.intensity, 0f))
targetColor = Color.white * 0f;
// If no texture option is enabled, set target color with light color. Otherwise, set target color with Color.white.
if (!noTexture)
targetColor = Color.white * sharedLight.intensity * multiplier;
else
targetColor = sharedLight.color * sharedLight.intensity * multiplier;
// If apply alpha is enabled, set color of the material with alpha channel.
if (applyAlpha)
targetColor = new Color(targetColor.r, targetColor.g, targetColor.b, sharedLight.intensity * multiplier);
// And finally, set color of the material with correct ID.
if (material.GetColor(emissionColorID) != (targetColor))
material.SetColor(emissionColorID, targetColor);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41e0cbbb9f1f0a3498b51bfdcd8100f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,251 @@
//----------------------------------------------
// 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>
/// Exhaust based on Particle System. Based on vehicle controller's throttle.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Exhaust")]
public class RCC_Exhaust : RCC_Core {
public RCC_CarControllerV3 CarController {
get {
if (_carController == null)
_carController = GetComponentInParent<RCC_CarControllerV3>();
return _carController;
}
}
private RCC_CarControllerV3 _carController;
private ParticleSystem particle; // Smoke particles.
private ParticleSystem.EmissionModule emission; // Smoke emission.
public ParticleSystem flame; // Flame particles.
private ParticleSystem.EmissionModule subEmission; // Flame emission.
private Light flameLight; // Flame light.
private LensFlare lensFlare; // Lensflare of the flame light.
public float flareBrightness = 1f; // Flare brightness.
private float finalFlareBrightness; // Calculated flare brigtness.
public float flameTime = 0f; // Flame time.
private AudioSource flameSource; // Flame audio source.
public Color flameColor = Color.red; // Flame color.
public Color boostFlameColor = Color.blue; // Boost / Nos flame color.
public bool previewFlames = false;
public float minEmission = 5f; // Emission limits
public float maxEmission = 20f;
public float minSize = 1f; // Size limits.
public float maxSize = 4f;
public float minSpeed = .1f; // Speed limits.
public float maxSpeed = 1f;
private void Start() {
// If don't use any particles enabled, destroy it.
if (RCC_Settings.Instance.dontUseAnyParticleEffects) {
Destroy(gameObject);
return;
}
// Getting components.
particle = GetComponent<ParticleSystem>();
emission = particle.emission;
// If flame exists...
if (flame) {
// Getting emission of the flame, light, and creating audio source.
subEmission = flame.emission;
flameLight = flame.GetComponentInChildren<Light>();
flameSource = NewAudioSource(RCC_Settings.Instance.audioMixer, gameObject, "Exhaust Flame AudioSource", 10f, 25f, .5f, RCC_Settings.Instance.exhaustFlameClips[0], false, false, false);
// If flame light exists, set render mode of the light depending of the option in RCC Settings.
if (flameLight)
flameLight.renderMode = RCC_Settings.Instance.useOtherLightsAsVertexLights ? LightRenderMode.ForceVertex : LightRenderMode.ForcePixel;
}
// Getting lensflare.
lensFlare = GetComponentInChildren<LensFlare>();
if (flameLight) {
if (flameLight.flare != null)
flameLight.flare = null;
}
}
private void Update() {
// If no car controller found, or particle, return.
if (!CarController || !particle)
return;
Smoke();
Flame();
if (lensFlare)
LensFlare();
}
/// <summary>
/// Smoke particles.
/// </summary>
private void Smoke() {
// If engine is running, set speed, size, and emission rates of the smoke particles.
if (CarController.engineRunning) {
ParticleSystem.MainModule main = particle.main;
if (CarController.speed < 20) {
if (!emission.enabled)
emission.enabled = true;
if (CarController.throttleInput > .35f) {
emission.rateOverTime = maxEmission;
main.startSpeed = maxSpeed;
main.startSize = maxSize;
} else {
emission.rateOverTime = minEmission;
main.startSpeed = minSpeed;
main.startSize = minSize;
}
} else {
if (emission.enabled)
emission.enabled = false;
}
} else {
if (emission.enabled)
emission.enabled = false;
}
}
/// <summary>
/// Flame particles with light effects.
/// </summary>
private void Flame() {
// If engine is running, set color of the flame, create audio source.
if (CarController.engineRunning) {
ParticleSystem.MainModule main = flame.main;
if (CarController.throttleInput >= .25f)
flameTime = 0f;
if (((CarController.useExhaustFlame && CarController.engineRPM >= 5000 && CarController.engineRPM <= 5500 && CarController.throttleInput <= .25f && flameTime <= .5f) || CarController.boostInput >= .75f) || previewFlames) {
flameTime += Time.deltaTime;
subEmission.enabled = true;
if (flameLight)
flameLight.intensity = flameSource.pitch * 3f * Random.Range(.25f, 1f);
if (CarController.boostInput >= .75f && flame) {
main.startColor = boostFlameColor;
if (flameLight)
flameLight.color = main.startColor.color;
} else {
main.startColor = flameColor;
if (flameLight)
flameLight.color = main.startColor.color;
}
if (!flameSource.isPlaying) {
flameSource.clip = RCC_Settings.Instance.exhaustFlameClips[Random.Range(0, RCC_Settings.Instance.exhaustFlameClips.Length)];
flameSource.Play();
}
} else {
subEmission.enabled = false;
if (flameLight)
flameLight.intensity = 0f;
if (flameSource.isPlaying)
flameSource.Stop();
}
} else {
if (emission.enabled)
emission.enabled = false;
subEmission.enabled = false;
if (flameLight)
flameLight.intensity = 0f;
if (flameSource.isPlaying)
flameSource.Stop();
}
}
/// <summary>
/// Lensflare calculation.
/// </summary>
private void LensFlare() {
// If there is no camera, return.
if (!Camera.main)
return;
float distanceTocam = Vector3.Distance(transform.position, Camera.main.transform.position);
float angle = Vector3.Angle(transform.forward, Camera.main.transform.position - transform.position);
if (angle != 0)
finalFlareBrightness = flareBrightness * (4 / distanceTocam) * ((100f - (1.11f * angle)) / 100f) / 2f;
if (flameLight) {
lensFlare.brightness = finalFlareBrightness * flameLight.intensity;
lensFlare.color = flameLight.color;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 66b98cf643678c845b2a8ee2683501bb
timeCreated: 1458850774
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
//----------------------------------------------
// 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>
/// Animation attached to "Animation Pivot" of the Cinematic Camera is feeding FOV float value.
/// </summary>
public class RCC_FOVForCinematicCamera : MonoBehaviour {
private RCC_CinematicCamera cinematicCamera; // Cinematic camera.
public float FOV = 30f; // Target field of view.
private void Awake() {
// Getting cinematic camera.
cinematicCamera = GetComponentInParent<RCC_CinematicCamera>();
}
private void Update() {
// Setting field of view of the cinematic camera.
cinematicCamera.targetFOV = FOV;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: df78f1d5dd5160441ab435e4fcc6981b
timeCreated: 1479327557
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,125 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using UnityEngine.XR;
public class RCC_FeedVehicleExample : MonoBehaviour {
public RCC_CarControllerV3 targetVehicle;
public bool takePlayerVehicle = true;
public RCC_Inputs newInputs = new RCC_Inputs();
private bool overrideNow = false;
public Slider throttle;
public Slider brake;
public Slider steering;
public Slider handbrake;
public Slider nos;
private void Start()
{
EnableOverride();
}
#region Machine control (Input System)
public void OnThrottle(InputAction.CallbackContext ctx) // Forward/Reverse gear
{
float vec = ctx.ReadValue<float>();
if (vec > 0)
newInputs.throttleInput = 1;
else
{
newInputs.throttleInput = 0;
newInputs.brakeInput = -vec;
}
}
public void SteerInput(InputAction.CallbackContext ctx) // Steering Control
{
var steer = ctx.ReadValue<Vector2>();
newInputs.steerInput = steer.x;
}
public void HandBrake(InputAction.CallbackContext ctx)// Hand brake
{
var hand = ctx.ReadValue<float>();
if(hand > 0)
newInputs.handbrakeInput = 1;
else
newInputs.handbrakeInput = 0;
}
public void NOS(InputAction.CallbackContext ctx)// Nitrogen
{
var NOS = ctx.ReadValue<float>();
if (NOS > 0)
newInputs.boostInput = 1;
else
newInputs.boostInput = 0;
}
#endregion
private void Update() {
//newInputs.throttleInput = throttle.value;
//newInputs.brakeInput = brake.value;
//newInputs.steerInput = steering.value;
//newInputs.handbrakeInput = handbrake.value;
//newInputs.boostInput = nos.value;
// if (takePlayerVehicle)
// targetVehicle = RCC_SceneManager.Instance.activePlayerVehicle;
if (targetVehicle && overrideNow)
targetVehicle.OverrideInputs(newInputs);
}
public void EnableOverride() {
if (!targetVehicle)
return;
overrideNow = true;
if (targetVehicle)
targetVehicle.OverrideInputs(newInputs);
}
public void DisableOverride() {
if (!targetVehicle)
return;
overrideNow = false;
if (targetVehicle)
targetVehicle.DisableOverrideInputs();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce218027992acef4e9ea2f59a23aef63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,119 @@
//----------------------------------------------
// 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>
/// Fixed camera system for RCC Camera. It simply parents the RCC Camera, and calculates target position, rotation, FOV, etc...
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Camera/RCC Fixed Camera")]
public class RCC_FixedCamera : RCC_Singleton<RCC_FixedCamera> {
private Vector3 targetPosition; // Target position.
public float maxDistance = 50f; // Max distance.
private float distance; // Current distance.
public float minimumFOV = 20f; // FOV limits.
public float maximumFOV = 60f;
public bool canTrackNow = false; // Can track now?
private void LateUpdate() {
// If can't track now, return.
if (!canTrackNow)
return;
// If current camera is null, return.
if (!RCC_SceneManager.Instance.activePlayerCamera)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget == null)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle == null)
return;
// Getting camera target.
Transform target = RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle.transform;
// Getting speed of the vehicle and calculating the distance.
float speed = RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.Speed;
distance = Vector3.Distance(transform.position, target.position);
// Calculating and setting field of view of the camera.
RCC_SceneManager.Instance.activePlayerCamera.targetFieldOfView = Mathf.Lerp(distance > maxDistance / 10f ? maximumFOV : 70f, minimumFOV, (distance * 1.5f) / maxDistance);
// Setting target position.
targetPosition = target.transform.position;
targetPosition += target.transform.rotation * Vector3.forward * (speed * .05f);
// Moving camera to the correct position.
transform.Translate((-target.forward * speed) / 50f * Time.deltaTime);
// Always look at the target.
transform.LookAt(targetPosition);
// If distance exceeds max distance, change position.
if (distance > maxDistance)
ChangePosition();
}
/// <summary>
/// Changes position of the camera.
/// </summary>
public void ChangePosition() {
// If can't track now, return.
if (!canTrackNow)
return;
// If current camera is null, return.
if (!RCC_SceneManager.Instance.activePlayerCamera)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget == null)
return;
// If current camera is null, return.
if (RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle == null)
return;
// Getting camera target.
Transform target = RCC_SceneManager.Instance.activePlayerCamera.cameraTarget.playerVehicle.transform;
// Creating random angle.
float randomizedAngle = Random.Range(-15f, 15f);
RaycastHit hit;
// Raycasting. If hits, translate the camera to the hit point.
if (Physics.Raycast(target.position + Vector3.up * 3f, Quaternion.AngleAxis(randomizedAngle, target.up) * target.forward, out hit, maxDistance) && !hit.transform.IsChildOf(target) && !hit.collider.isTrigger) {
transform.position = hit.point + Vector3.up * Random.Range(.5f, 2.5f);
transform.LookAt(target.position);
transform.position += transform.forward * 5f;
} else {
transform.position = target.position + Vector3.up * Random.Range(.5f, 2.5f);
transform.rotation = target.rotation * Quaternion.AngleAxis(randomizedAngle, Vector3.up);
transform.position += transform.forward * (maxDistance * .9f);
transform.LookAt(target.position);
transform.position += transform.forward * 5f;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 329bfd12784c4c24f834463bc2995114
timeCreated: 1465321476
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Fuel station. When a vehicle enters the trigger, fuel tank will be filled up.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Misc/RCC Fuel Station")]
public class RCC_FuelStation : MonoBehaviour {
private RCC_CarControllerV3 targetVehicle; // Target vehicle.
public float refillSpeed = 1f; // Refill speed.
private void OnTriggerStay(Collider col) {
targetVehicle = col.gameObject.GetComponentInParent<RCC_CarControllerV3>();
// If target vehicle is null, return.
if (!targetVehicle)
return;
// Refill the tank with given speed * time.
if (targetVehicle)
targetVehicle.fuelTank += refillSpeed * Time.deltaTime;
}
private void OnTriggerExit(Collider col) {
// Setting target vehicle to null when vehicle exits the trigger.
if (col.gameObject.GetComponentInParent<RCC_CarControllerV3>())
targetVehicle = null;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4696f9b843762cb459e8e54ab3be809b
timeCreated: 1517180523
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,109 @@
//----------------------------------------------
// 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>
/// Gets total bound size of a gameobject.
/// </summary>
public class RCC_GetBounds {
/// <summary>
/// Gets the center bounds extent of object, including all child renderers,
/// but excluding particles and trails, for FOV zooming effect.
/// </summary>
/// <returns>The bounds center.</returns>
/// <param name="obj">Object.</param>
public static Vector3 GetBoundsCenter(Transform obj) {
var renderers = obj.GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds();
bool initBounds = false;
foreach (Renderer r in renderers) {
if (!((r is TrailRenderer) || (r is ParticleSystemRenderer))) {
if (!initBounds) {
initBounds = true;
bounds = r.bounds;
} else {
bounds.Encapsulate(r.bounds);
}
}
}
Vector3 center = bounds.center;
return center;
}
/// <summary>
/// Gets the maximum bounds extent of object, including all child renderers,
/// but excluding particles and trails, for FOV zooming effect.
/// </summary>
/// <returns>The bounds extent.</returns>
/// <param name="obj">Object.</param>
public static float MaxBoundsExtent(Transform obj) {
var renderers = obj.GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds();
bool initBounds = false;
foreach (Renderer r in renderers) {
if (!((r is TrailRenderer) || (r is ParticleSystemRenderer))) {
if (!initBounds) {
initBounds = true;
bounds = r.bounds;
} else {
bounds.Encapsulate(r.bounds);
}
}
}
float max = Mathf.Max(bounds.extents.x, bounds.extents.y, bounds.extents.z);
return max;
}
public static MeshFilter GetBiggestMesh(Transform obj) {
MeshFilter[] mfs = obj.GetComponentsInChildren<MeshFilter>();
MeshFilter biggestMesh = mfs[0];
for (int i = 0; i < mfs.Length; i++) {
if (mfs[i].mesh.bounds.size.magnitude > biggestMesh.mesh.bounds.size.magnitude)
biggestMesh = mfs[i];
}
return biggestMesh;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6bc67ce9fc2b13d43af6ee0ca169e3d2
timeCreated: 1471999313
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,66 @@
//----------------------------------------------
// 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>
/// Ground materials for variable ground physics.
/// </summary>
[System.Serializable]
public class RCC_GroundMaterials : ScriptableObject {
#region singleton
private static RCC_GroundMaterials instance;
public static RCC_GroundMaterials Instance { get { if (instance == null) instance = Resources.Load("RCC Assets/RCC_GroundMaterials") as RCC_GroundMaterials; return instance; } }
#endregion
[System.Serializable]
public class GroundMaterialFrictions {
public PhysicMaterial groundMaterial; // Physic material.
public float forwardStiffness = 1f; // Forward stiffness.
public float sidewaysStiffness = 1f; // Sideways stiffness.
public float slip = .25f; // Target slip limit.
public float damp = 1f; // Damp force.
[Range(0f, 1f)] public float volume = 1f; // Volume of the ground sound.
public GameObject groundParticles; // Ground particles.
public AudioClip groundSound; // Ground audio clip.
public RCC_Skidmarks skidmark; // Skidmarks.
public bool deflate = false; // Deflate the wheel?
}
public GroundMaterialFrictions[] frictions; // Ground materials.
/// <summary>
/// Terrain ground materials.
/// </summary>
[System.Serializable]
public class TerrainFrictions {
public PhysicMaterial groundMaterial;
[System.Serializable]
public class SplatmapIndexes {
public int index = 0;
}
public SplatmapIndexes[] splatmapIndexes;
}
public TerrainFrictions[] terrainFrictions; // Terrain ground materials.
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7eb1a463d58d67241ac93ce41125f622
timeCreated: 1457867857
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,103 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// RCC Camera will be parented to this gameobject when current camera mode is Hood Camera.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/Camera/RCC Hood Camera")]
public class RCC_HoodCamera : MonoBehaviour {
private void Awake() {
CheckJoint();
}
/// <summary>
/// Fixing shake bug of the rigid.
/// </summary>
public void FixShake() {
StartCoroutine(FixShakeDelayed());
}
IEnumerator FixShakeDelayed() {
// If no rigid found, return.
if (!GetComponent<Rigidbody>())
yield break;
yield return new WaitForFixedUpdate();
GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.None;
yield return new WaitForFixedUpdate();
GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
}
/// <summary>
/// Checking configurable joint.
/// </summary>
private void CheckJoint() {
// Getting configurable joint.
ConfigurableJoint joint = GetComponent<ConfigurableJoint>();
// If no joint found, return.
if (!joint)
return;
// If connected body of the joint is null, set it to car controller itself.
if (joint.connectedBody == null) {
RCC_CarControllerV3 carController = GetComponentInParent<RCC_CarControllerV3>();
if (carController) {
joint.connectedBody = carController.GetComponent<Rigidbody>();
} else {
Debug.LogError("Hood camera of the " + transform.root.name + " has configurable joint with no connected body! Disabling rigid and joint of the camera.");
Destroy(joint);
Rigidbody rigid = GetComponent<Rigidbody>();
if (rigid)
Destroy(rigid);
}
}
}
private void Reset() {
ConfigurableJoint joint = GetComponent<ConfigurableJoint>();
if (!joint)
return;
RCC_CarControllerV3 carController = GetComponentInParent<RCC_CarControllerV3>();
if (!carController)
return;
joint.connectedBody = carController.GetComponent<Rigidbody>();
joint.connectedMassScale = 0f;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: df49e4c9448a62f4b9f91d03ef06dfb7
timeCreated: 1461462052
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// Displays UI info.
/// </summary>
[AddComponentMenu("BoneCracker Games/Realistic Car Controller/UI/RCC UI Info Displayer")]
[RequireComponent(typeof(Text))]
public class RCC_InfoLabel : RCC_Singleton<RCC_InfoLabel> {
private Text text; // UI text.
private float timer = 1.5f; // Timeout to close the info panel.
private void Awake() {
// Getting text component and disabling it.
text = GetComponent<Text>();
text.enabled = false;
}
private void OnEnable() {
text.text = "";
timer = 1.5f;
}
private void Update() {
// If timer is below 1.5, text is enabled. Otherwise disable.
if (timer < 1.5f) {
if (!text.enabled)
text.enabled = true;
} else {
if (text.enabled)
text.enabled = false;
}
// Increasing timer.
timer += Time.deltaTime;
}
/// <summary>
/// Shows info.
/// </summary>
/// <param name="info"></param>
public void ShowInfo(string info) {
// If no text found, return.
if (!text)
return;
// Display info.
text.text = info;
timer = 0f;
}
private void OnDisable() {
text.text = "";
timer = 1.5f;
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 99b6935d46b22894f94812ad5643b4ad
timeCreated: 1510613559
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using UnityEngine;
using UnityEngine.Audio;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// Stored all general shared RCC settings here.
/// </summary>
[System.Serializable]
public class RCC_InitialSettings : ScriptableObject {
#region singleton
private static RCC_InitialSettings instance;
public static RCC_InitialSettings Instance { get { if (instance == null) instance = Resources.Load("RCC Assets/RCC_InitialSettings") as RCC_InitialSettings; return instance; } }
#endregion
// Wheel frictions.
[Header("Wheel Frictions Forward")]
public float forwardExtremumSlip = .375f;
public float forwardExtremumValue = 1f;
public float forwardAsymptoteSlip = .8f;
public float forwardAsymptoteValue = .5f;
public float forwardStiffness = 1.25f;
[Header("Wheel Frictions Sideways")]
public float sidewaysExtremumSlip = .275f;
public float sidewaysExtremumValue = 1f;
public float sidewaysAsymptoteSlip = .5f;
public float sidewaysAsymptoteValue = .75f;
public float sidewaysStiffness = 1.25f;
[Header("Wheel Suspensions")]
public float suspensionSpring = 45000f;
public float suspensionDamping = 2500f;
public float suspensionDistance = .2f;
public float forceAppPoint = .1f;
[Header("Rigidbody")]
public float mass = 1500;
public float drag = .01f;
public float angularDrag = .5f;
public RigidbodyInterpolation interpolation = RigidbodyInterpolation.Interpolate;
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 41bc78a3d748c2d4ebfa1e40b2f98f11
timeCreated: 1461545776
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6ef677dff66d4b4d9b047afbd948da0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,273 @@
//----------------------------------------------
// Realistic Car Controller
//
// Copyright © 2014 - 2023 BoneCracker Games
// https://www.bonecrackergames.com
// Buğra Özdoğanlar
//
//----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
/// <summary>
/// Main input class of the RCC. Used by RCC_CarControllerV3, RCC_Camera, RCC_MobileButtons.
/// </summary>
public class RCC_InputManager : RCC_Singleton<RCC_InputManager> {
public RCC_Inputs inputs = new RCC_Inputs();
private static RCC_InputActions inputActions;
public bool gyroUsed = false;
public bool logitechSteeringUsed = false;
public bool logitechHShifterUsed = false;
public int logitechGear = -2;
public delegate void onStartStopEngine();
public delegate void onLowBeamHeadlights();
public static event onLowBeamHeadlights OnLowBeamHeadlights;
public delegate void onHighBeamHeadlights();
public static event onHighBeamHeadlights OnHighBeamHeadlights;
public delegate void onChangeCamera();
public static event onChangeCamera OnChangeCamera;
public delegate void onIndicatorLeft();
public static event onIndicatorLeft OnIndicatorLeft;
public delegate void onIndicatorRight();
public static event onIndicatorRight OnIndicatorRight;
public delegate void onIndicatorHazard();
public static event onIndicatorHazard OnIndicatorHazard;
public delegate void onGearShiftUp();
public static event onGearShiftUp OnGearShiftUp;
public delegate void onGearShiftDown();
public static event onGearShiftDown OnGearShiftDown;
public delegate void onNGear(bool state);
public static event onNGear OnNGear;
public delegate void onSlowMotion(bool state);
public static event onSlowMotion OnSlowMotion;
public delegate void onRecord();
public static event onRecord OnRecord;
public delegate void onReplay();
public static event onReplay OnReplay;
public delegate void onLookBack(bool state);
public static event onLookBack OnLookBack;
public delegate void onTrailerDetach();
public static event onTrailerDetach OnTrailerDetach;
private void Awake() {
gameObject.hideFlags = HideFlags.HideInHierarchy;
// Creating inputs.
inputs = new RCC_Inputs();
}
private void Update() {
// Creating inputs.
if (inputs == null)
inputs = new RCC_Inputs();
// Receive inputs from the controller.
GetInputs();
}
/// <summary>
/// Gets all inputs and registers button events.
/// </summary>
/// <returns></returns>
public void GetInputs()
{
if (inputActions == null)
{
inputActions = new RCC_InputActions();
// inputActions.Enable();
inputActions.Vehicle.LowBeamLights.performed += LowBeamLights_performed;
inputActions.Vehicle.HighBeamLights.performed += HighBeamLights_performed;
inputActions.Camera.ChangeCamera.performed += ChangeCamera_performed;
inputActions.Vehicle.IndicatorLeft.performed += IndicatorLeft_performed;
inputActions.Vehicle.IndicatorRight.performed += IndicatorRight_performed;
inputActions.Vehicle.IndicatorHazard.performed += IndicatorHazard_performed;
inputActions.Vehicle.GearShiftUp.performed += GearShiftUp_performed;
inputActions.Vehicle.GearShiftDown.performed += GearShiftDown_performed;
inputActions.Vehicle.NGear.performed += NGear_performed;
inputActions.Vehicle.NGear.canceled += NGear_canceled;
inputActions.Optional.SlowMotion.performed += SlowMotion_performed;
inputActions.Optional.SlowMotion.canceled += SlowMotion_canceled;
inputActions.Optional.Record.performed += Record_performed;
inputActions.Optional.Replay.performed += Replay_performed;
inputActions.Camera.LookBack.performed += LookBack_performed;
inputActions.Camera.LookBack.canceled += LookBack_canceled;
inputActions.Vehicle.TrailerDetach.performed += TrailerDetach_performed;
}
if (!RCC_Settings.Instance.mobileControllerEnabled)
{
inputs.throttleInput = inputActions.Vehicle.Throttle.ReadValue<float>();
inputs.brakeInput = inputActions.Vehicle.Brake.ReadValue<float>();
inputs.steerInput = inputActions.Vehicle.Steering.ReadValue<float>();
inputs.handbrakeInput = inputActions.Vehicle.Handbrake.ReadValue<float>();
inputs.boostInput = inputActions.Vehicle.NOS.ReadValue<float>();
inputs.gearInput = logitechGear;
inputs.orbitX = inputActions.Camera.Orbit.ReadValue<Vector2>().x;
inputs.orbitY = inputActions.Camera.Orbit.ReadValue<Vector2>().y;
inputs.scroll = inputActions.Camera.Zoom.ReadValue<Vector2>();
}
else
{
inputs.throttleInput = RCC_MobileButtons.mobileInputs.throttleInput;
inputs.brakeInput = RCC_MobileButtons.mobileInputs.brakeInput;
inputs.steerInput = RCC_MobileButtons.mobileInputs.steerInput;
inputs.handbrakeInput = RCC_MobileButtons.mobileInputs.handbrakeInput;
inputs.boostInput = RCC_MobileButtons.mobileInputs.boostInput;
}
}
public void TrailerDetach_performed(InputAction.CallbackContext obj) {
if (OnTrailerDetach != null)
OnTrailerDetach();
}
private void LookBack_performed(InputAction.CallbackContext obj) {
if (OnLookBack != null)
OnLookBack(true);
}
private void LookBack_canceled(InputAction.CallbackContext obj) {
if (OnLookBack != null)
OnLookBack(false);
}
private static void Replay_performed(InputAction.CallbackContext obj) {
if (OnReplay != null)
OnReplay();
}
private static void Record_performed(InputAction.CallbackContext obj) {
if (OnRecord != null)
OnRecord();
}
private static void SlowMotion_performed(InputAction.CallbackContext obj) {
if (OnSlowMotion != null)
OnSlowMotion(true);
}
private static void SlowMotion_canceled(InputAction.CallbackContext obj) {
if (OnSlowMotion != null)
OnSlowMotion(false);
}
private static void NGear_performed(InputAction.CallbackContext obj) {
if (OnNGear != null)
OnNGear(true);
}
private static void NGear_canceled(InputAction.CallbackContext obj) {
if (OnNGear != null)
OnNGear(false);
}
private static void GearShiftDown_performed(InputAction.CallbackContext obj) {
if (OnGearShiftDown != null)
OnGearShiftDown();
}
private static void GearShiftUp_performed(InputAction.CallbackContext obj) {
if (OnGearShiftUp != null)
OnGearShiftUp();
}
private static void IndicatorHazard_performed(InputAction.CallbackContext obj) {
if (OnIndicatorHazard != null)
OnIndicatorHazard();
}
private static void IndicatorRight_performed(InputAction.CallbackContext obj) {
if (OnIndicatorRight != null)
OnIndicatorRight();
}
private static void IndicatorLeft_performed(InputAction.CallbackContext obj) {
if (OnIndicatorLeft != null)
OnIndicatorLeft();
}
private static void ChangeCamera_performed(InputAction.CallbackContext obj) {
if (OnChangeCamera != null)
OnChangeCamera();
}
private static void HighBeamLights_performed(InputAction.CallbackContext obj) {
if (OnHighBeamHeadlights != null)
OnHighBeamHeadlights();
}
private static void LowBeamLights_performed(InputAction.CallbackContext obj) {
if (OnLowBeamHeadlights != null)
OnLowBeamHeadlights();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61e25ef321f8f794d8993e30a99ddf00
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More