# 클릭한 위치로 캐릭터 이동하는 기능 구현
- InputManager 클래스 코드 추가 및 수정
기존 KeyAction 뿐 아니라 MouseAction 델리게이트 이벤트를 생성해서
이를 활용하면 된다
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputManager
{
public event Action KeyAction = null;
public event Action<Define.MouseEvent> MouseAction = null;
bool _mousePressed = false;
public void OnUpdate()
{
if (KeyAction != null && Input.anyKey)
KeyAction.Invoke();
if (MouseAction != null)
{
if (Input.GetMouseButton(0))
{
MouseAction.Invoke(Define.MouseEvent.Press);
_mousePressed = true;
}
else
{
if (_mousePressed == true)
MouseAction.Invoke(Define.MouseEvent.Click);
_mousePressed = false;
}
}
}
}
- PlayerController 클래스 코드 추가 및 수정
InputManager의 MouseAction과 바인드 할 함수를 추가하면 된다
그리고 PlayerController Update에서 마우스로 지속적으로 이동을 하는 코드를 작성하면 된다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _positionSpeed = 10.0f;
[SerializeField]
private float _rotationSpeed = 10.0f;
bool _mouseMoveToDest = false;
Vector3 _mouseMoveDestPos;
void Start()
{
Managers.Input.KeyAction -= OnKeyboard;
Managers.Input.KeyAction += OnKeyboard;
Managers.Input.MouseAction -= OnMouseClicked;
Managers.Input.MouseAction += OnMouseClicked;
}
void Update()
{
if (_mouseMoveToDest == true)
{
Vector3 dir = _mouseMoveDestPos - transform.position;
dir.y = 0.0f;
if(dir.magnitude < 0.0001f)
{
_mouseMoveToDest = false;
}
else
{
transform.position += dir.normalized * _positionSpeed * Time.deltaTime;
transform.LookAt(_mouseMoveDestPos);
}
}
}
void OnKeyboard()
{
...
_mouseMoveToDest = false;
...
}
void OnMouseClicked(Define.MouseEvent evt)
{
if (evt != Define.MouseEvent.Click)
return;
Debug.Log("OnMouseClicked");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100.0f, LayerMask.GetMask("Wall")))
{
_mouseMoveDestPos = hit.point;
_mouseMoveToDest = true;
}
}
}
# 오류 발생 1
플레이어의 속도가 있다보니 계속 목적지를 지나쳐서
다시 해당 위치로 가려고 부들부들 떨리며 이동하는 문제가 있다
따라서 거리(== 시 * 속)를 통제하는 코드를 추가해야 한다
void Update()
{
if (_mouseMoveToDest == true)
{
Vector3 dir = _mouseMoveDestPos - transform.position;
dir.y = 0.0f;
if(dir.magnitude < 0.0001f)
{
_mouseMoveToDest = false;
}
else
{
float moveDist = Mathf.Clamp(_positionSpeed * Time.deltaTime, 0, dir.magnitude); // 거리 통제
transform.position += dir.normalized * moveDist;
transform.LookAt(_mouseMoveDestPos);
}
}
}
# 오류 발생 2
LookAt을 사용하는 경우
회전을 천천히 진행하는 것이 아니라
바로 딱 회전을 진행하는 문제가 있다
그렇기에 이를 해결하기 위해서는 Slerp를 활용하면 된다
void Update()
{
if (_mouseMoveToDest == true)
{
Vector3 dir = _mouseMoveDestPos - transform.position;
dir.y = 0.0f;
if(dir.magnitude < 0.0001f)
{
_mouseMoveToDest = false;
}
else
{
float moveDist = Mathf.Clamp(_positionSpeed * Time.deltaTime, 0, dir.magnitude);
transform.position += dir.normalized * moveDist;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime); // Slerp 활용
}
}
}'게임 엔진 - 유니티 > [루키스] 유니티' 카테고리의 다른 글
| [유니티 Note] 섹션 7-1 (0) | 2025.07.05 |
|---|---|
| [유니티 Note] 섹션 6-3 (0) | 2025.07.02 |
| [유니티 Note] 섹션 6-1 (0) | 2025.07.02 |
| [유니티 Note] 섹션 5-6 (0) | 2025.07.02 |
| [유니티 Note] 섹션 5-5 (0) | 2025.07.02 |