98 lines
3.1 KiB
C#
98 lines
3.1 KiB
C#
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.AI;
|
||
|
|
using UnityEngine.InputSystem;
|
||
|
|
|
||
|
|
public class ClickToMoveInputSystem : MonoBehaviour
|
||
|
|
{
|
||
|
|
[Header("References")]
|
||
|
|
public Camera cam;
|
||
|
|
public LayerMask movementLayers; // ground
|
||
|
|
public LayerMask selectionLayers; // enemies, NPCs, interactables
|
||
|
|
|
||
|
|
void Awake()
|
||
|
|
{
|
||
|
|
if (cam == null) cam = Camera.main;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hook this to PointerPos action (Value Vector2)
|
||
|
|
Vector2 pointerScreenPos;
|
||
|
|
public void OnPointerPos(InputAction.CallbackContext ctx)
|
||
|
|
{
|
||
|
|
pointerScreenPos = ctx.ReadValue<Vector2>();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hook this to LeftClick action (Button)
|
||
|
|
public void OnLeftClick(InputAction.CallbackContext ctx)
|
||
|
|
{
|
||
|
|
if (!ctx.performed) return;
|
||
|
|
if (cam == null) return;
|
||
|
|
|
||
|
|
Ray ray = cam.ScreenPointToRay(pointerScreenPos);
|
||
|
|
if (Physics.Raycast(ray, out RaycastHit hit, 500f, selectionLayers))
|
||
|
|
{
|
||
|
|
// Try to find a Character on the hit object or its parents
|
||
|
|
var character = hit.collider.GetComponentInParent<Character>();
|
||
|
|
if (character != null)
|
||
|
|
{
|
||
|
|
if (Player.Current != null) Player.Current.SetTarget(character);
|
||
|
|
var selectable = hit.collider.GetComponentInParent<ISelectable>();
|
||
|
|
selectable?.OnSelected();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Generic interactable
|
||
|
|
var interactable = hit.collider.GetComponentInParent<Interactable>();
|
||
|
|
interactable?.OnSelect();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Nothing selected, clear target
|
||
|
|
if (Player.Current != null) Player.Current.SetTarget(null);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hook this to RightClick action (Button)
|
||
|
|
public void OnRightClick(InputAction.CallbackContext ctx)
|
||
|
|
{
|
||
|
|
if (!ctx.performed) return;
|
||
|
|
if (cam == null) return;
|
||
|
|
if (Player.Current == null) return;
|
||
|
|
|
||
|
|
Ray ray = cam.ScreenPointToRay(pointerScreenPos);
|
||
|
|
if (Physics.Raycast(ray, out RaycastHit hit, 500f, movementLayers))
|
||
|
|
{
|
||
|
|
// Move player's movement controller or NavMeshAgent
|
||
|
|
var movement = Player.Current.MovementController;
|
||
|
|
if (movement != null)
|
||
|
|
{
|
||
|
|
movement.MoveTo(hit.point);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// fallback: try to find NavMeshAgent on player root
|
||
|
|
var agent = Player.Current.GetComponent<UnityEngine.AI.NavMeshAgent>();
|
||
|
|
if (agent != null) agent.SetDestination(hit.point);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Optional fallback if PointerPos not wired
|
||
|
|
void Update()
|
||
|
|
{
|
||
|
|
if (cam == null) return;
|
||
|
|
if (Mouse.current == null) return;
|
||
|
|
|
||
|
|
pointerScreenPos = Mouse.current.position.ReadValue();
|
||
|
|
|
||
|
|
if (Mouse.current.leftButton.wasPressedThisFrame)
|
||
|
|
{
|
||
|
|
// simulate InputAction callback context by calling handler directly
|
||
|
|
OnLeftClick(new InputAction.CallbackContext());
|
||
|
|
}
|
||
|
|
|
||
|
|
if (Mouse.current.rightButton.wasPressedThisFrame)
|
||
|
|
{
|
||
|
|
OnRightClick(new InputAction.CallbackContext());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|