Post

1인칭 캐릭터 구현

이전의 유니티 기본 문서와 다르게 구현함

Unity Version : 2022.3.16f1 LTS

캐릭터 움직임 구현

Edit → Project Manager → Input Manager → Axes에 있는 Horizontal, Vertical을 활용

Untitled

Horizontal이 A, D키 Vertical이 W, S키임

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// CharacterMove.cs

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

public class NewBehaviourScript : MonoBehaviour
{

    public Transform cameraTransform;
    public CharacterController characterController;

    public float moveSpeed = 10f;
    public float jumpSpeed = 10f;
    public float runSpeed = 2f;

    public float gravity = -20f;

    float yVelocity = 0;

    void Start()
    {
        
    }
    void Update()
    {
        float input_h = Input.GetAxis("Horizontal"); // A, D키 입력
        float input_v = Input.GetAxis("Vertical"); // W, S키 입력

        Vector3 moveDirection = new Vector3(input_h, 0, input_v);
        moveDirection = cameraTransform.TransformDirection(moveDirection);
        
        moveDirection *= moveSpeed;
        if (Input.GetKey(KeyCode.LeftShift)) // 좌 쉬프트 = 달리기
        {
            moveDirection *= runSpeed;
        }
   
        if (characterController.isGrounded) // 캐릭터가 땅에 붙어있을 때
        {
            yVelocity = 0;
            if (Input.GetKeyDown(KeyCode.Space)) // 스페이스바 누르면 점프
            {
                yVelocity = jumpSpeed;
            }

        }

        yVelocity += (gravity * Time.deltaTime);

        moveDirection.y = yVelocity;

        characterController.Move(moveDirection * Time.deltaTime);

    }
}

WASD로 이동, Shift로 달리기, Space로 점프 구현함

카메라 움직임 구현

Edit → Project Manager → Input Manager → Axes에 있는 Mouse X, Mouse Y 활용

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// CameraMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMove : MonoBehaviour
{
    public float sensitivity = 200f;
    float rotationX;
    float rotationY;

    void Start()
    {
        
    }

    
    void Update()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        rotationX += mouseX * sensitivity * Time.deltaTime;
        rotationY += mouseY * sensitivity * Time.deltaTime;

        rotationX = rotationX > 35f ? 35f : rotationX;
        rotationX = rotationX < -30f ? -30f : rotationX;

        rotationY = rotationY > 35f ? 35f : rotationY;
        rotationY = rotationY < -30f ? -30f : rotationY;

        transform.eulerAngles = new Vector3(-rotationY, rotationX, 0);
    }
}

카메라 회전에 관한 추가 그림

Untitled

카메라가 아니라 캐릭터가 돌아감

이유 : 카메라를 캐릭터에 붙여놓고, 캐릭터를 돌리니까 카메라를 돌리는 것처럼 보였던 것 뿐임

해결 방안 : cameraMove.cs을 카메라에 붙이고, 캐릭터의 CharacterMove.cs를 일부 수정함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// CharacterMove.cs

using UnityEngine;

public class CharacterMove : MonoBehaviour
{

    ...
    void Update()
    {
        CharacterMoving(); // WASD 이동 부분을 따로 함수로 뺌
        CharacterRotationX(); // 마우스 좌우로 돌리면 캐릭터가 직접 돌게
    }
		
    void CharacterMoving()
    {
        float input_h = Input.GetAxis("Horizontal"); // A, D키 입력
        float input_v = Input.GetAxis("Vertical"); // W, S키 입력

        Vector3 moveDirection = new Vector3(input_h, 0, input_v);
        moveDirection = cameraTransform.TransformDirection(moveDirection);

        moveDirection *= moveSpeed;
        if (Input.GetKey(KeyCode.LeftShift)) // 좌 쉬프트 = 달리기
        {
            moveDirection *= runSpeed;
        }

        if (characterController.isGrounded) // 캐릭터가 땅에 붙어있을 때
        {
            yVelocity = 0;
            if (Input.GetKeyDown(KeyCode.Space)) // 스페이스바 누르면 점프
            {
                yVelocity = jumpSpeed;
            }

        }

        yVelocity += (gravity * Time.deltaTime);

        moveDirection.y = yVelocity;

        characterController.Move(moveDirection * Time.deltaTime);
    }

    void CharacterRotationX()
    {
        float mouseX = Input.GetAxis("Mouse X");

        rotationX += mouseX * sensitivity * Time.deltaTime;

        this.transform.eulerAngles = new Vector3(0, rotationX, 0);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// CameraMove.cs

public class CameraMove : MonoBehaviour
{
    float sensitivity;
    float rotationY;

    GameObject parentCharacter;

    private void Awake()
    {
        // 부모 객체 (캐릭터) 가져오기
        parentCharacter = this.transform.parent.gameObject;
        // 캐릭터의 sensitivity를 그대로 가져옴
        sensitivity = parentCharacter.GetComponent<CharacterMove>().sensitivity;
    }
		...
    void Update()
    {
        CameraRotationY(); // 마우스 위 아래로 돌리면 카메라만 움직이게
    }

    void CameraRotationY()
    {
        float mouseY = Input.GetAxis("Mouse Y");

        rotationY += mouseY * sensitivity * Time.deltaTime;
		
				// 부모 객체의 회전 각도를 가져다 사용
        Vector3 parentAngle = parentCharacter.transform.eulerAngles;

        // 카메라를 위, 아래로 회전시킬 때 제한을 설정
        rotationY = rotationY > 35f ? 35f : rotationY;
        rotationY = rotationY < -30f ? -30f : rotationY;

        transform.eulerAngles = new Vector3(-rotationY, parentAngle.y, 0);
    }
}

Untitled

이제 마우스를 아래로 내린다고 해서 캐릭터 자체가 숙이지 않음!

참고자료

[Unity3D 개발] 키보드 방향키로 플레이어 움직임과, 1인칭 카메라 시점이동 구현하기

C# 삼항연산자(Ternary Operator)로 간결한 코딩을!

[Unity] GetAxis - 마우스 입력 제어

[Unity] 유니티 게임 오브젝트를 찾는 방법 - GameObject

[Unity] 유니티 다른 오브젝트 컴포넌트, 스크립트 변수 접근하기

[Unity] 트랜스폼(Transform) 회전(Rotation)

This post is licensed under CC BY 4.0 by the author.