154 lines
5.0 KiB
C#
154 lines
5.0 KiB
C#
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<float> optionalVertical;
|
|
[SerializeField] private Optional<float> optionalHorizontal;
|
|
[SerializeField] private Optional<float> 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<AxisInfo> 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<float>();
|
|
}
|
|
|
|
public void OnHorizontal(InputAction.CallbackContext context)
|
|
{
|
|
horizontal = context.ReadValue<float>();
|
|
}
|
|
|
|
public void OnBrake(InputAction.CallbackContext context)
|
|
{
|
|
isBraking = context.performed;
|
|
}
|
|
}
|
|
} |