using Photon.Pun; using UnityEngine; public class ProjectileSpawnLocationController : MonoBehaviour { [SerializeField] protected Transform lookAt; [SerializeField] private float gamepadDeadzone = 0.2f; protected PhotonView photonView; protected PlayerMovement playerMovement; Plane plane = new Plane(Vector3.up, 0); Ray ray; protected Vector3 targetPoint = Vector3.zero; bool isCasting; Vector3 castLookatSnapshot; bool isUsingGamepad; Vector3 lastValidAimDirection; protected virtual void Awake() { photonView = GetComponentInParent(); playerMovement = GetComponentInParent(); lastValidAimDirection = transform.forward; // Initialize with a default forward direction } private void OnEnable() { if (CastBarHandler.Instance != null) { CastBarHandler.Instance.OnCastingStateChanged.AddListener(UpdateIsCastingState); } } private void OnDisable() { if (CastBarHandler.Instance != null) { CastBarHandler.Instance.OnCastingStateChanged.RemoveListener(UpdateIsCastingState); } } protected virtual void Start() { if (!photonView.IsMine) { this.enabled = false; return; } } protected virtual void Update() { if (Camera.main == null) return; if (isCasting) { lookAt.forward = castLookatSnapshot; return; } DetectInputMethod(); if (isUsingGamepad) { HandleGamepadAiming(); } else { HandleMouseAiming(); } // Always ensure we have a valid forward direction if (lookAt.forward == Vector3.zero) { lookAt.forward = lastValidAimDirection; } } private void DetectInputMethod() { Vector2 gamepadLook = new Vector2( Input.GetAxisRaw(GameConstants.Input.AimHorizontalAxis), Input.GetAxisRaw(GameConstants.Input.AimVerticalAxis) ); if (gamepadLook.magnitude > gamepadDeadzone) { isUsingGamepad = true; } else if (Input.GetAxisRaw("Mouse X") != 0 || Input.GetAxisRaw("Mouse Y") != 0) { isUsingGamepad = false; } } private void HandleGamepadAiming() { Vector2 aimInput = new Vector2( Input.GetAxisRaw(GameConstants.Input.AimHorizontalAxis), Input.GetAxisRaw(GameConstants.Input.AimVerticalAxis) ); if (aimInput.magnitude > gamepadDeadzone) { Vector3 cameraForward = Camera.main.transform.forward; Vector3 cameraRight = Camera.main.transform.right; // Ensure we're working in the horizontal plane cameraForward.y = 0f; cameraRight.y = 0f; cameraForward.Normalize(); cameraRight.Normalize(); Vector3 aimDirection = (cameraForward * aimInput.y + cameraRight * aimInput.x).normalized; if (aimDirection != Vector3.zero) { lastValidAimDirection = aimDirection; lookAt.forward = aimDirection; } } else { // Use the last valid aim direction when no current input lookAt.forward = lastValidAimDirection; } } private void HandleMouseAiming() { ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (plane.Raycast(ray, out float distance)) { targetPoint = ray.GetPoint(distance); targetPoint.y = this.transform.position.y; Vector3 direction = (targetPoint - lookAt.position).normalized; if (direction != Vector3.zero) { lastValidAimDirection = direction; lookAt.forward = direction; } } } public Vector3 GetLookat() { return lookAt.forward != Vector3.zero ? lookAt.forward : lastValidAimDirection; } private void UpdateIsCastingState(bool isCasting) { this.isCasting = isCasting; if (isCasting) { if (isUsingGamepad) { Vector2 aimInput = new Vector2( Input.GetAxisRaw(GameConstants.Input.AimHorizontalAxis), Input.GetAxisRaw(GameConstants.Input.AimVerticalAxis) ); if (aimInput.magnitude > gamepadDeadzone) { Vector3 cameraForward = Camera.main.transform.forward; Vector3 cameraRight = Camera.main.transform.right; cameraForward.y = 0f; cameraRight.y = 0f; cameraForward.Normalize(); cameraRight.Normalize(); castLookatSnapshot = (cameraForward * aimInput.y + cameraRight * aimInput.x).normalized; } else { castLookatSnapshot = lastValidAimDirection; } } else { ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (plane.Raycast(ray, out float distance)) { targetPoint = ray.GetPoint(distance); targetPoint.y = this.transform.position.y; castLookatSnapshot = (targetPoint - lookAt.position).normalized; } } // Ensure we never have a zero vector for casting if (castLookatSnapshot == Vector3.zero) { castLookatSnapshot = lastValidAimDirection; } } } }