Making an RPG in Unity #1

오동환·2023년 2월 17일
0

Making an RPG in Unity

목록 보기
1/7
post-thumbnail

1. Gamma, Linier Color Space

(Edit -> Project Settings -> Player -> Other Settings -> Rendering -> Color Space)
감

↑Gamma

↑Linier

Linier가 강한 빛 아래서 색 표현을 훨씬 풍부하게 할 수 있다.

감마(Gamma) and 선형(Linear) Color Space 에 대해

2. Nav Mesh Agent

: 자동으로 Player가 Path Finding할 수 있게 해주는 Component

Steering : 조종 Properties (이동 속도, 회전 속도, 마찰 등)

필요 Components : Capsule Collider (Player 기본 Collider), RigidBody (isKinematic에 체크)

3. Navigation

(Window -> AI -> Navigartion)

Bake : Static상태인 Object들을 계산하여 NavMesh를 보여줌

↑모든 Ojbect가 Static

↑Bridge의 Object 상태 : Walkable

↑Bridge를 Not Walkable로 변경 후 Bake

↑Bridge가 Static이 아닐 때 (Not Walkable과의 차이가 있음)

Bake는 Static상태의 Object를 계산한다.

1) Obejct를 Navigation Mesh에 추가하기

  1. Object에 Static 체크
  2. Nav Mesh Obstacle Component를 추가 한 후 Carve 체크 (Runtime으로 계산된 Nav Mesh를 볼 수 있음)
  3. Collider Component는 없어도 됨

2) Agent를 위한 Navigation Bake 설정하기

Agent Radius : NavMesh 위에서 움직일 대상의 반지름
Step Height : Agent가 가벼운 계단 정도로 여기고 올라갈 수 있는 높이

내비게이션 시스템 (1) - NavMesh

4. Scripts

클릭된 곳의 정보 받기

1) Input

  • GetMouseButton : 마우스가 눌릴 동안 true 반환
  • GetMouseButtonDown : 마우스를 누르면 true 1회 반환
  • GetMouseButtonUp : 마우스를 떼면 true 1회 반환

  • 0 : 마우스 왼쪽 키
  • 1 : 마우스 오른쪽 키
  • 2 : 마우스 휠 키

키보드, 마우스 조작 정리

2) Ray

  • Ray : 직선의 시작점과 방향을 가지고 있는 단순한 구조체
  • RayCastHit : 개체와 Ray의 충돌에 대한 결과를 저장하는 구조체

3) Physics

  • RayCast(Ray ray, out RayCastHit hitInfo, float maxDistance, int layerMask)
    : Ray를 layerMask에 maxDistance까지 쏴서 충돌 정보를 hitInfo에 저장한다.

4) 코드 및 결과

void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = cam.ScreenPointToRay(Input.mousePosition); 
            RaycastHit hit;
            
            if (Physics.Raycast(ray, out hit, 100, movementMask))
            {
                Debug.Log("We hit " + hit.collider.name + " " + hit.point);  
            }
        }
    }

↑CampFire Object를 클릭했지만 Ground가 인식된다.

Physics.Raycast 완벽 가이드

클릭된 곳으로 플레이어 이동시키기

1) RequireComponent
: 요구되는 Component가 해당 Object에 없을 경우 자동으로 Component를 추가해준다.

2) NavMeshAgent

  • SetDestination(Vector 3) : 해당 위치로 최단 거리를 통해 agent를 이동

3) 코드

using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]
public class PlayerMotor : MonoBehaviour
{
    NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>(); // Get component from current object
    }

    public void MoveToPoint(Vector3 point)
    {
        agent.SetDestination(point);
    }
}

컴포넌트 : NavMeshAgent 와 프로퍼티/함수 모음

플레이어를 따라다니는 Camera 만들기

1) Update

  • Update() : 물리 효과가 적용되지 않은 오브젝트의 움직임이나 단순한 타이머, 키 입력을 받을 때 사용됩니다.

  • FixedUpdate() : 물리 효과가 적용된(Rigidbody) 오브젝트를 조정할 때 사용됩니다. (Update는 불규칙한 호출임으로 물리엔진 충돌검사 등이 제대로 안될 수 있음)

  • LateUpdate() : 모든 Update 함수가 호출된 후, 마지막으로 호출됩니다. 주로 오브젝트를 따라가게 설정한 카메라는 LateUpdate 를 사용합니다. (카메라가 따라가는 오브젝트가 Update함수 안에서 움직일 경우가 있기 때문)

Update() , FixedUpdate() , LateUpdate() 의 차이점

2) Mathf

  • Mathf.Clamp(float value, float min, float max);
    : value를 min값과 max값 사이를 벗어나지 않게 함

3) Tarnsform

  • Transform.LookAt(Vector3 worldPosition)
    : worldPosition을 바라봄

  • Transform.RotateAround(Vector3 point, Vector3 axis, float angle)
    : angle 정도로 point를 axis 를 따라 회전함

4) 코드

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform target;
    public Vector3 offset;
    public float pitch = 2f;

    public float currentZoom = 10f;
    public float zoomSpeed = 4f;
    public float minZoom = 5f;
    public float maxZoom = 15f;

    public float yawSpeed = 100f;
    private float currentYaw = 0;

    private void Update()
    {
        currentZoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
        currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);

        // A, D, Left arrow, Rigth arrow Keys
        currentYaw -= Input.GetAxis("Horizontal") * yawSpeed * Time.deltaTime;
    }

    private void LateUpdate()
    {
        transform.position = target.position - offset * currentZoom;

        // Hence target's position is equal to the character's feet, add character's tall.
        transform.LookAt(target.position + Vector3.up * pitch);

        transform.RotateAround(target.position, Vector3.up, currentYaw);
    }
}

5. 완성

6. Take-Home Message

사실 복습을 해야하는가도 고민했고 복습을 한다면 어느 시기에 어떻게 해야하는가도 고민했다. 해보니 확실히 많은 장점들이 있다.

1. Liniar / Gamma Color Space와 같은 튜토리얼 강의에서 설명해 주지 않고 넘어가는 부분을 챙길 수 있다.

2. 배운 것들을 글로 적으려면 나름의 정리가 필요하다. 정리를 하고 나면 머릿 속이 편안해진다.

3. 글을 연재하는 것처럼 다음의 공부를 위한 동기 부여가 된다.

Object를 생성하기 전 Empty를 먼저 생성해서 Parent해주는 것이 좋다

다음과 같이 설정하면 Player Motion같이 움직임을 맡는 스크립트를 Player에 Add하면, Children은 모두 함께 움직인다.

  • Player
    • HitBox
    • GFX
    • KillBox
    • HitBox
profile
게임 개발 공부하고 있어요

0개의 댓글