BITFALL/Assets/Artists/Scripts/Vehicle/WorldHelicopter.cs

173 lines
4.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using BITFALL.Player.Movement;
using Lightbug.Utilities;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BITKit.Vehicles
{
public class WorldHelicopter : MonoBehaviour
{
[SerializeField] private float upForce = 1024f;
[SerializeField] private float forwardForce = 1024f;
[SerializeField] private float shakeForce = 4096f;
[SerializeField] private float torqueResetDelta = 4096f;
[SerializeField] private float torqueForce = 4096f;
[SerializeField] private float inertia = 0.5f;
[SerializeField] private Transform spin;
[SerializeField] private new Rigidbody rigidbody;
[SerializeField] private new Collider collider;
[SerializeField] private Transform model;
[SerializeReference,SubclassSelector] private IPlayerFixedPlace fixedPlace;
private Vector2 _movement;
private float _vertical;
private float _horizontal;
private float _turn;
private float _AscendAndDescend;
private bool _hover;
private bool _reset;
private Transform Transform;
private Vector3 _initialPosition;
private readonly ValidHandle _resetHandle=new();
private void Start()
{
foreach (var x in GetComponentsInChildren<Collider>(true))
{
Physics.IgnoreCollision(x, collider);
}
_initialPosition = model.localPosition;
Transform = transform;
var newRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(Transform.forward, Vector3.up));
rigidbody.MoveRotation(newRotation);
fixedPlace.OnPlayerEntered += x => _resetHandle.RemoveElement(111);
fixedPlace.OnPlayerExited += x => _resetHandle.AddElement(111);
}
private void FixedUpdate()
{
if (rigidbody.isKinematic) return;
var offsetX = Mathf.PerlinNoise(Time.time, 0) - 0.5f;
var offsetY = Mathf.PerlinNoise(0, Time.time) - 0.5f;
_resetHandle.SetElements(123,_reset);
rigidbody.useGravity = !_hover;
_movement = Vector2.Lerp(_movement, new Vector2(_horizontal, _vertical), inertia * Time.fixedDeltaTime);
var up = rigidbody.transform.up;
var moveForce = up * (_AscendAndDescend * upForce * Time.fixedDeltaTime);
var newRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(Transform.forward, Vector3.up));
if (_resetHandle)
{
rigidbody.AddTorque(MathV.CalculateTorque(Transform,newRotation) * (torqueResetDelta * Time.fixedDeltaTime),
ForceMode.VelocityChange);
}
else
{
Vector3 direction = default;
direction += Vector3.ProjectOnPlane(up, Vector3.up) * (forwardForce * Time.fixedDeltaTime);
direction += Vector3.ProjectOnPlane(Vector3.up, Transform.right) * (forwardForce * Time.fixedDeltaTime);
moveForce += Vector3.ProjectOnPlane(direction, Vector3.up);
rigidbody.AddForce(moveForce, ForceMode.VelocityChange);
Vector3 torque = default;
torque += Transform.up * (_turn * torqueForce * Time.fixedDeltaTime);
torque += Transform.forward * (-_movement.x * torqueForce * Time.fixedDeltaTime);
torque += rigidbody.transform.right * (_movement.y * Time.fixedDeltaTime);
//torque += Vector3.MoveTowards(rigidbody.angularVelocity, Vector3.zero, Time.fixedDeltaTime);
rigidbody.AddTorque(torque,ForceMode.VelocityChange);
// rigidbody.AddTorque(CalculateTorque(newRotation) * Time.fixedDeltaTime,
// ForceMode.VelocityChange);
}
spin.Rotate(Vector3.forward, 1024 * Time.deltaTime, Space.Self);
if (Physics.Raycast(Transform.position, Vector3.down, out var hit, 1f, LayerMask.GetMask("Default")))
{
if (_hover)
rigidbody.AddForce(Vector3.up * (upForce * Time.fixedDeltaTime), ForceMode.VelocityChange);
}
else
{
model.localPosition =_initialPosition + new Vector3(offsetX, offsetY, 0) * (shakeForce * Time.fixedDeltaTime);
}
}
public void OnAscendAction(InputAction.CallbackContext context)
{
_AscendAndDescend = context.ReadValue<float>();
}
public void OnVertical(InputAction.CallbackContext context)
{
_vertical = context.ReadValue<float>();
}
public void OnHorizontal(InputAction.CallbackContext context)
{
_horizontal = context.ReadValue<float>();
}
public void OnToggleHover(InputAction.CallbackContext context)
{
if (context.performed)
{
_hover = !_hover;
}
}
public void OnTurn(InputAction.CallbackContext context)
{
_turn = context.ReadValue<float>();
}
private void OnDrawGizmos()
{
var forward = Vector3.ProjectOnPlane(transform.forward, Vector3.up);
var position = transform.position;
Gizmos.DrawLine(position, position + forward);
}
public void OnReset(InputAction.CallbackContext context)
{
if (context.performed)
{
_reset = true;
}
else if (context.canceled)
{
_reset = false;
}
}
}
}