저번 시간에 영역을 만들었으니 이번 시간에는
영역을 선택하고 아군영역이면 해당 영역으로 이동하는 기능을 만들어보자.
01 - 플레이어 컨트롤러와 플레이어 캐릭터 코드의 관계
플레이어 캐릭터가 직접 명령을 받고 즉시 기능을 수행하는 방법도 있지만
사용자에게 입력을 받는 클래스와 수행하는 클래스로 나누면 추후 작업하기 편하고
여러 개의 플레이어블 캐릭터가 있으면 관리하기도 편하기에 플레이어 컨트롤러 클래스는 필요하다!
02 - 준비하기: TestPlayer 스크립트, PlayerController 스크립트
우선 Create Empty를 생성하고 이름을 Player Controller 지정해
플레이어 컨트롤러 오브젝트를 만들고 PlayerController.cs 스크립트를 추가하자
Player는 에셋 폴더에 Prefab에 있는 Player를 하이어라키에 넣고 플레이어 스크립트를 넣자
(이때 Tag값도 수정해두자)
02 - 1. Player.cs
public class TestPlayer : MonoBehaviour
{
[System.NonSerialized] public bool isMove = false;
private float walkSpeed = 50f;
[System.NonSerialized] public Vector3 targetPos; // 이동할 위치
// Update is called once per frame
void Update()
{
if (isMove)
{
Move();
}
}
public void MovePosition(Vector3 position)
{
this.targetPos = position;
isMove = true;
}
private void Move()
{
transform.position = Vector3.MoveTowards(transform.position, targetPos, walkSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, targetPos) < 0.01f)
{
isMove = false;
}
}
}
- 플레이어 캐릭터 코드는 이동할 위치 정보를 받는다.
- MovePostion() : targetPos를 position 값으로 변경하고 isMove를 true로 변경함.
- Move() : Update 함수에 호출되며 isMove가 true일때만 targetPos로 이동
이동이 완료되면 isMove 값을 false로 전환.
02 - 2. PlayerController.cs
public class PlayerController : MonoBehaviour
{
[SerializeField] private TestPlayer player;
[SerializeField] private AreaManager areaManager;
// 필요한 정보
private Ray ray;
private RaycastHit hit;
private Area selectArea; // 선택한 영역
private bool isFriend = false; // 선택한 영역이 아군 영역?
// Update is called once per frame
void Update()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
InfoUpdate();
MouseClick();
}
private void InfoUpdate()
{
if (Physics.Raycast(ray, out hit))
{
selectArea = hit.collider.GetComponent<Area>();
if (selectArea != null)
{
isFriend = CheckArea(selectArea);
}
else
{
isFriend = false;
}
}
}
// 마우스로 클릭
private void MouseClick()
{
if (Input.GetMouseButtonDown(0) && selectArea != null)
{
if (isFriend)
{
DirectPlayer_Move(selectArea);
}
else
{
Debug.Log($"이곳은 적군의 영역입니다!\n선택한 좌표: {selectArea.areaIndex}");
}
}
}
// 태그 값으로 영역 확인
private bool CheckArea(Area selectArea)
{
return selectArea.CompareTag("Area_Friend");
}
// 캐릭터에게 이동 명령
private void DirectPlayer_Move(Area selectArea)
{
Vector3 areaPos = areaManager.GetAreaPosition(selectArea);
Debug.Log($"선택한 좌표로 이동!: {selectArea.areaIndex}");
player.MovePosition(new Vector3(areaPos.x, player.transform.position.y, areaPos.z));
}
}
이 스크립트의 역할을 간단히 이해하자면 마우스가 좌클릭하면 선택한 부분에 있는
영역 정보를 가져와서 아군 영역이면 해당 위치로 이동하라고 명령을 내린다.
명령을 내리는 부분에서 선택한 Area가 3D 게임상에서 위치한 곳이 어디에 있는지를
AreaManager에게 요청하는 내용이 있다!
02 - 3. AreaManager.cs 에서 GetAreaPostion( ) 메서드 추가
public Vector3 GetAreaPosition(Area area)
{
return area.transform.position;
}
AreaManger.cs 에 해당 메서드를 추가하자!
3. Unity 에서 값 조정
저번에 만들었던 영역 오브젝트들을 Tag 값들을 설정해주자!
아군 영역은 Area_Friend, 적군 영역은 Area_Enemy로 Tag를 추가해서 값을 지정하면 된다!
4. 테스트 결과
이런 식으로 플레이어 캐릭터가 선택한 영역에 움직이고 적군 영역이면 움직이지 않으면 끝!
'Unity > Unity 게임 개발' 카테고리의 다른 글
[Unity] 3D 턴제 게임 만들기 01 - 진형(영역) 만들기 (0) | 2025.02.25 |
---|---|
[Unity] 3D 턴제 게임 만들기 00 - 프로토타입 게임 개발 준비 (0) | 2025.02.25 |