BITFALL/Assets/BITKit/Unity/Scripts/Vehicle/Vehicle.cs

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;
}
}
}