Unity 예제 - 1인칭 시점 캐릭터 컨트롤러

이 기사는 독자의 이해를 돕기 위해 이전 Unity 쿼드러플 의 데모를 위한 것입니다.


그 효과는 방향을 위해 마우스로, 이동을 위해 키보드로 조작할 수 있는 작업을 달성하는 것입니다.

효과 영상은 다음과 같습니다.

1687597097844


다음과 같이 가르칩니다.

1. 간단한 장면 만들기

  1. 새 장면을 만들고 평면을 바닥으로 배치하고 크기를 사용자 지정합니다.
  2. 평면에 매달릴 새 재료 만들기
  3. 주로 테스트 중에 참조할 수 있도록 바닥에 몇 개의 큐브를 놓습니다.

2. 주인공 개체 만들기

  1. 캐릭터를 나타내는 캡슐 만들기
  2. 캡슐의 자식으로 큐브를 만들고 캡슐의 "면"에 큐브를 놓습니다. 교수형 재료
  3. 장면 목록에서 카메라를 드래그하여 카메라를 캡슐의 하위 개체로 만듭니다.
  4. 카메라 위치를 0으로 되돌린 후 카메라 위치를 캐릭터의 얼굴로 미세 조정합니다.

 3. 제어 스크립트 작성 - 모바일 부분

  1.  스크립트 FPSCharacter 생성 및 캡슐에 마운트
  2. 스크립트 내용을 작성합니다. 스크립트의 내용이 핵심이며, 다음은 단계별로 소개합니다.

 캐릭터의 컨트롤은 캐릭터 이동과 카메라 회전 두 부분으로 나뉩니다.

캐릭터 이동 측면에서 플레이어는 화살표 키를 눌러 앞, 뒤, 왼쪽 및 오른쪽으로 이동할 수 있습니다. 문제는 플레이어가 위쪽 화살표 키를 눌렀을 때 어느 방향에 해당하는지, 플레이어가 오른쪽 화살표 키를 눌렀을 때 어느 방향에 해당하는지이다.

일반적으로 플레이어 자체에는 순방향 벡터 transform.forward 및 오른쪽 벡터 transform.right가 있습니다. 오른쪽 방향 벡터는 오른쪽 방향으로의 움직임에 직접적으로 대응하며, 정면 벡터는 고개를 들었다가 내리는 상황이 있기 때문에 더 번거롭다. 플레이어가 하늘을 올려다보며 앞으로 직진하면 결국 하늘로 날아가게 된다.

해결 방법은 전면 벡터가 수평을 유지하도록 전면 벡터의 y축 구성 요소를 제거하기 위해 전면 벡터를 약간 수정하는 것입니다. 전체 코드는 글 말미에 있으며, 움직임을 계산하는 코드 부분은 다음과 같습니다.

 void Move()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        Vector3 fwd = transform.forward;
        Vector3 f = new Vector3(fwd.x, 0, fwd.z).normalized;
        Vector3 r = transform.right;
        Vector3 move = f * z + r * x;
        transform.position += move * speed * Time.deltaTime;
    }

4. 제어 스크립트 작성 - 회전 부분

다음은 회전 렌즈 부분입니다. 카메라는 이미 캐릭터에 걸려 있기 때문에 캐릭터를 직접 회전시키면 그에 따라 렌즈도 회전하게 됩니다. 회전 키 코드는 다음과 같습니다.

 void MouseLook()
    {
        float mx = Input.GetAxis("Mouse X");
        float my = -Input.GetAxis("Mouse Y");
        Quaternion qx = Quaternion.Euler(0, mx, 0);
        Quaternion qy = Quaternion.Euler(my, 0, 0);
        transform.rotation = qx * transform.rotation;
        transform.rotation = transform.rotation*qy;
    }

마우스로 객체를 이동하고 회전시키는 아이디어는 간단하지 않지만 쿼터니언을 영리하게 사용하고 나면 코드가 예상외로 짧아집니다. 먼저 "마우스 X"와 "마우스 Y"는 각각 마우스의 수평 이동과 수직 이동에 해당하는 두 개의 특수 입력 축입니다(마우스 위치가 아니라 마우스 위치의 변화).

마우스의 수평 이동은 렌즈의 수평 회전, 즉 y축을 따른 회전에 해당하고, 마우스의 수직 이동은 렌즈의 피치 회전에 해당합니다. 따라서 마우스의 수평 및 수직 이동을 오일러 각도로 간주하고 쿼터니언으로 변환하여 각각 qx 및 qy라고 하는 두 개의 "작은 회전"을 얻을 수 있습니다.

그런 다음 쿼터니언 곱셈을 사용하여 캐릭터의 현재 방향에 작은 회전을 적용하면 문제가 해결됩니다. 어려운 점은 카메라의 회전이 실제로 세계 좌표계의 y축을 중심으로 한 회전인 반면, 카메라의 피치 회전은 로컬 좌표계의 x축을 중심으로 한 회전이라는 것입니다.

마지막으로 고개를 숙이거나 들어올릴 때 90도 이상 뒤를 볼 수 없기 때문에 피치 각도를 제한해야 하므로 MouseLook() 함수 끝에 다음과 같은 로직을 추가해야 합니다.

 float angle = transform.eulerAngles.x;
        if (angle > 180) { angle -= 360; }
        if (angle <- 180) { angle+= 360; }
        if(angle>80)
        {
            Debug.Log("A" + transform.eulerAngles.x);
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if (angle <-80)
        {
            Debug.Log("A" + transform.eulerAngles.x);
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }

5. 마우스 포인터 숨기기 및 잠그기

테스트 중에는 마우스 포인터가 게임 경험에 영향을 미치며 게임 창 외부 영역을 클릭하면 게임 창의 포커스가 사라집니다. 해결책은 마우스 포인터를 숨기고 마우스 포인터를 화면 중앙에 고정하는 것입니다. 코드는 다음과 같습니다.

void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }

Unity 컴파일러에서는 Esc 키를 누르기만 하면 마우스 포인터가 표시되지만 실제 게임 개발자에서는 적절한 시점에 마우스 포인터를 표시하고 잠금을 해제하는 것을 잊지 마십시오. Ruyuanshinzhong은 Alt 키를 눌러 잠금을 취소하는 것입니다.

여섯, 완전한 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FPSCharachter : MonoBehaviour
{
    public float speed = 5f;
    void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }
    void Update()
    {
        Move();
        MouseLook();
    }
   void Move()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
        Vector3 fwd = transform.forward;
        Vector3 f = new Vector3(fwd.x, 0, fwd.z).normalized;
        Vector3 r = transform.right;
        Vector3 move = f * z + r * x;
        transform.position += move * speed * Time.deltaTime;
    }
    void MouseLook()
    {
        float mx = Input.GetAxis("Mouse X");
        float my = -Input.GetAxis("Mouse Y");
        Quaternion qx = Quaternion.Euler(0, mx, 0);
        Quaternion qy = Quaternion.Euler(my, 0, 0);
        transform.rotation = qx * transform.rotation;
        transform.rotation = transform.rotation * qy;
        float angle = transform.eulerAngles.x;
        if (angle > 180) { angle -= 360; }
        if (angle <- 180) { angle+= 360; }
        if(angle>80)
        {
            Debug.Log("A" + transform.eulerAngles.x);
            transform.eulerAngles = new Vector3(80, transform.eulerAngles.y, 0);
        }
        if (angle <-80)
        {
            Debug.Log("A" + transform.eulerAngles.x);
            transform.eulerAngles = new Vector3(-80, transform.eulerAngles.y, 0);
        }
    }
}

추천

출처blog.csdn.net/m0_63024355/article/details/131363750