190 lines
5.9 KiB
C#
190 lines
5.9 KiB
C#
using Photon.Pun;
|
|
using UnityEngine;
|
|
|
|
public class AoERayHitLocationSnapshotController : MonoBehaviour
|
|
{
|
|
public Transform aoeRayHitLocationSnapshot;
|
|
public LayerMask movementMask;
|
|
|
|
[Header("Gamepad Settings")]
|
|
[SerializeField] private float defaultTargetDistance = 5f;
|
|
[SerializeField] private float minDistance = 2f;
|
|
[SerializeField] private float maxDistance = 10f;
|
|
[SerializeField] private float distanceAdjustSpeed = 5f;
|
|
[SerializeField] private float gamepadDeadzone = 0.2f;
|
|
|
|
protected PhotonView photonView;
|
|
protected Ray ray;
|
|
protected RaycastHit hit;
|
|
protected Vector3 targetPoint = Vector3.zero;
|
|
protected bool isCasting;
|
|
protected bool isUsingGamepad;
|
|
protected float currentTargetDistance;
|
|
protected Vector3 lastValidAimDirection;
|
|
|
|
protected virtual void Awake()
|
|
{
|
|
photonView = GetComponentInParent<PhotonView>();
|
|
aoeRayHitLocationSnapshot.parent = null;
|
|
currentTargetDistance = defaultTargetDistance;
|
|
lastValidAimDirection = transform.forward;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
protected virtual void Update()
|
|
{
|
|
if (Camera.main == null) return;
|
|
if (isCasting) return;
|
|
|
|
DetectInputMethod();
|
|
|
|
if (isUsingGamepad)
|
|
{
|
|
HandleGamepadAiming();
|
|
}
|
|
else
|
|
{
|
|
HandleMouseAiming();
|
|
}
|
|
}
|
|
|
|
private void DetectInputMethod()
|
|
{
|
|
Vector2 gamepadLook = new Vector2(
|
|
Input.GetAxisRaw(GameConstants.Input.AimHorizontalAxis),
|
|
Input.GetAxisRaw(GameConstants.Input.AimVerticalAxis)
|
|
);
|
|
|
|
float rightTrigger = Input.GetAxisRaw("RightTrigger");
|
|
float leftTrigger = Input.GetAxisRaw("LeftTrigger");
|
|
bool triggerInput = Mathf.Abs(rightTrigger) > gamepadDeadzone || Mathf.Abs(leftTrigger) > gamepadDeadzone;
|
|
|
|
if (gamepadLook.magnitude > gamepadDeadzone || triggerInput)
|
|
{
|
|
isUsingGamepad = true;
|
|
}
|
|
else if (Input.GetAxisRaw("Mouse X") != 0 || Input.GetAxisRaw("Mouse Y") != 0)
|
|
{
|
|
isUsingGamepad = false;
|
|
}
|
|
}
|
|
|
|
private void HandleGamepadAiming()
|
|
{
|
|
// Get aim direction from right stick
|
|
Vector2 aimInput = new Vector2(
|
|
Input.GetAxisRaw(GameConstants.Input.AimHorizontalAxis),
|
|
Input.GetAxisRaw(GameConstants.Input.AimVerticalAxis)
|
|
);
|
|
|
|
// Update target distance based on both triggers
|
|
float rightTrigger = Input.GetAxisRaw("RightTrigger");
|
|
float leftTrigger = Input.GetAxisRaw("LeftTrigger");
|
|
|
|
// Right trigger increases distance, left trigger decreases
|
|
float distanceChange = (rightTrigger - leftTrigger) * distanceAdjustSpeed * Time.deltaTime;
|
|
currentTargetDistance += distanceChange;
|
|
currentTargetDistance = Mathf.Clamp(currentTargetDistance, minDistance, maxDistance);
|
|
|
|
// Calculate target position
|
|
Vector3 aimDirection;
|
|
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();
|
|
|
|
aimDirection = (cameraForward * aimInput.y + cameraRight * aimInput.x).normalized;
|
|
lastValidAimDirection = aimDirection;
|
|
}
|
|
else
|
|
{
|
|
aimDirection = lastValidAimDirection;
|
|
}
|
|
|
|
// Calculate target position with ground detection
|
|
Vector3 targetPosition = transform.position + aimDirection * currentTargetDistance;
|
|
ray = new Ray(targetPosition + Vector3.up * 10f, Vector3.down);
|
|
|
|
if (Physics.Raycast(ray, out hit, 20f, movementMask))
|
|
{
|
|
aoeRayHitLocationSnapshot.position = hit.point;
|
|
}
|
|
else
|
|
{
|
|
// Fallback if no ground is hit
|
|
targetPosition.y = transform.position.y;
|
|
aoeRayHitLocationSnapshot.position = targetPosition;
|
|
}
|
|
}
|
|
private void HandleMouseAiming()
|
|
{
|
|
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
|
|
if (Physics.Raycast(ray, out hit, 100f, movementMask))
|
|
{
|
|
aoeRayHitLocationSnapshot.position = hit.point;
|
|
}
|
|
}
|
|
|
|
private void UpdateIsCastingState(bool isCasting)
|
|
{
|
|
this.isCasting = isCasting;
|
|
|
|
if (isCasting)
|
|
{
|
|
if (isUsingGamepad)
|
|
{
|
|
// Store the current AOE position for the cast
|
|
Vector3 currentPos = aoeRayHitLocationSnapshot.position;
|
|
currentPos.y = transform.position.y;
|
|
targetPoint = currentPos;
|
|
}
|
|
else
|
|
{
|
|
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
if (Physics.Raycast(ray, out hit, 100f, movementMask))
|
|
{
|
|
targetPoint = hit.point;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
if (!Application.isPlaying) return;
|
|
|
|
// Draw the current target distance
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawWireSphere(transform.position, currentTargetDistance);
|
|
|
|
// Draw the min/max range
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawWireSphere(transform.position, minDistance);
|
|
Gizmos.DrawWireSphere(transform.position, maxDistance);
|
|
}
|
|
} |