using System; using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(Health))] public class Player : MonoBehaviour { public InputAction movement; public InputAction mousePosition; public InputAction fireAction; public Camera mainCamera; public float speed = 10; public float fireRate; public GameObject projectileGo; public Transform projectileSpawn; public Transform barrelTransform; private Transform _transform; private Vector3 _position; private float _lastFireTime; private bool _wantFire; private Action _aimingFunction; private void Start() { _transform = transform; var h = GetComponent(); h.OnDeath += ProcessDeath; } private void OnEnable() { movement.Enable(); mousePosition.Enable(); _aimingFunction = MouseAim; // TODO: Aim stick fireAction.Enable(); fireAction.started += StartFire; fireAction.canceled += EndFire; } private void OnDisable() { movement.Disable(); mousePosition.Disable(); } private void StartFire(InputAction.CallbackContext cbContext) { _wantFire = true; } private void EndFire(InputAction.CallbackContext cbContext) { _wantFire = false; } private void MouseAim() { var mousePos = mousePosition.ReadValue(); var mouseWorld = mainCamera.ScreenToWorldPoint(mousePos); mouseWorld.z = _transform.position.z; var direction = mouseWorld - _transform.position; direction.Normalize(); var cross = Vector3.Cross(Vector3.up, direction); var dot = Vector3.Dot(Vector3.up, direction); var angle = Mathf.Acos(dot) * Mathf.Rad2Deg; if (cross.z < 0) { angle *= -1; } barrelTransform.eulerAngles = Vector3.forward * angle; } private void JoystickAim() { // TOOD: } private void Update() { var direction = movement.ReadValue(); direction.Normalize(); _transform.up = direction; direction *= speed * Time.deltaTime; _position.x = direction.x; _position.y = direction.y; _position.z = 0; _transform.position += _position; _aimingFunction(); if (_wantFire && _lastFireTime + (1 / fireRate) < Time.time) { _lastFireTime = Time.time; Instantiate(projectileGo, projectileSpawn.position, projectileSpawn.rotation); } } private void ProcessDeath() { // TODO: effects, gameover screen, etc. Destroy(gameObject); } }