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(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(); } public void OnVertical(InputAction.CallbackContext context) { _vertical = context.ReadValue(); } public void OnHorizontal(InputAction.CallbackContext context) { _horizontal = context.ReadValue(); } public void OnToggleHover(InputAction.CallbackContext context) { if (context.performed) { _hover = !_hover; } } public void OnTurn(InputAction.CallbackContext context) { _turn = context.ReadValue(); } 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; } } } }