using System; using System.Collections; using System.Collections.Generic; using System.Security.Permissions; using UnityEngine; using BITKit.Entities; using BITKit.Events; using UnityEngine.InputSystem; namespace BITKit.Vehicles { public enum WheelType { None, Motor, Steel, } [System.Serializable] public class AxisInfo { public WheelCollider[] wheels; public Transform[] wheelModels; public WheelType wheelType; } public sealed class Vehicle : EntityBehavior { [Header(Constant.Header.Settings)] public float maxMotorTorque = 64; [SerializeField] private float maxSteeringAngle = 45; [SerializeField] private float brakeTorque; [SerializeField] private Optional optionalVertical; [SerializeField] private Optional optionalHorizontal; [SerializeField] private Optional optionalUpRight; [Header(Constant.Header.Components)] [SerializeField] private new Rigidbody rigidbody; [SerializeField] private GameObject[] objects; [SerializeField] private GameObject[] destroyedObjects; [SerializeField] private Transform driveAnchor; [Header(Constant.Header.Gameobjects)] [SerializeField] private List axisInfos = new(); [SerializeField] private Transform steeringWheel; [Header(Constant.Header.Events)] [SerializeField] private UnityEvent onHighSpeed; [SerializeField] private UnityEvent OnEntryHighSpeed; [SerializeField] private UnityEvent OnExitHighSpeed; [Header(Constant.Header.InternalVariables)] private float vertical; private float horizontal; private bool isBraking; private readonly ValidHandle highSpeedHandle = new(); private IUnityEntity _unityEntity; [Inject(true)] private IHealth _health; public override void OnAwake() { base.OnAwake(); if (_health is not null) _health.OnSetAlive += OnSetAlive; } private void OnSetAlive(bool obj) { foreach (var x in objects) { x.SetActive(obj); } foreach (var x in destroyedObjects) { x.SetActive(!obj); } } public override void OnStart() { highSpeedHandle.AddListener(x => { if (x) { OnEntryHighSpeed.Invoke(); } else { OnExitHighSpeed.Invoke(); } onHighSpeed.Invoke(x); }); highSpeedHandle.Invoke(); } public override void OnUpdate(float deltaTime) { var torque = maxMotorTorque *(optionalVertical.Allow ? optionalVertical.Value : vertical); var steel =maxSteeringAngle * (optionalHorizontal.Allow ? optionalHorizontal.Value : horizontal); axisInfos.ForEach(x => { switch (x.wheelType) { case WheelType.Motor: if (isBraking) { x.wheels.ForEach(wheelCollider => { wheelCollider.brakeTorque = brakeTorque; }); } else { x.wheels.ForEach(wheelCollider => { wheelCollider.motorTorque = torque; }); x.wheels.ForEach(wheelCollider => { wheelCollider.brakeTorque = 0; }); } break; case WheelType.Steel: var steelAngle = horizontal * 45; x.wheelModels.ForEach(trans => { trans.localEulerAngles = new Vector3(torque * Time.deltaTime, steelAngle, 0); }); if (steeringWheel) steeringWheel.localEulerAngles = new Vector3(0, 0, steelAngle); x.wheels.ForEach(wheelCollider => { wheelCollider.steerAngle = steel; }); break; } }); if (optionalUpRight.Allow) { rigidbody.AddRelativeTorque(rigidbody.transform.eulerAngles.z * optionalUpRight.Value * transform.forward, ForceMode.VelocityChange); } highSpeedHandle.SetElements(this, rigidbody.velocity.magnitude > 4); } public void OnVertical(InputAction.CallbackContext context) { vertical = context.ReadValue(); } public void OnHorizontal(InputAction.CallbackContext context) { horizontal = context.ReadValue(); } public void OnBrake(InputAction.CallbackContext context) { isBraking = context.performed; } } }