본문 바로가기
Unity

[Unity] 유니티 기초 / 에디터 기초, 단축키, Component 패턴, 매니저, Singleton 패턴, 디버깅

by imagineer_jinny 2023. 1. 19.

본 포스팅은 인프런 - Rookiss님의 <[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진>을 토대로 작성하였습니다. 

 

강의 보러가기: https://www.inflearn.com/course/mmorpg-%EC%9C%A0%EB%8B%88%ED%8B%B0/dashboard



환경 설정

 

* 단축키 *

 

- Object 만들기 : ctrl + shift + n

- Object 이름 바꾸기: F2

- Play : ctrl + p (play 끌때도 같음)

- 현재 저장: ctrl + s

- 다른 이름 혹은 다른 경로에 저장 : ctrl + shift+ s , File -> SaveAs

 

<화면 조절>

오른쪽 마우스+ W,A,S,D : 상하좌우움직이기

오른쪽 마우스 + Q, E : 위 아래

오른쪽 마우스만 가지고도 움직이고

오른쪽 마우스 + alt : zoom in, zoom out 

왼쪽 마우스 + alt : 주시하던 대상 기준으로 화면을 돌릴 수 있음

마우스 휠 : 확대, 축소

오른쪽 마우스 + 휠 : 숫자가 보이는데 가상 카메라가 이동할 속도

 

<오브젝트>

오브젝트 선택 + Q,W,E,R

W: Move. 네모 영역 누르고 움직이면 두개의 축 고정된채로 움직임

E: 회전

R: Scale

 

변화 취소 : Ctrl + z

 

 

여기서 마우스로 움직였던 것은 실제 카메라 아님. 사용자 편의 위해서 보는 것

만약 내가 보고 있는대로 카메라가 바로 보면 좋겠다 느끼면

Main Camera 클릭 + ctrl+shift+F

 

 

 

에디터 입문

클라이언트 개발은 영화를 찍는 것과 비슷하다

 

- Scene: 촬영장

- Game: 영화

- Project:

Asset - 배우, 소품, 음악 등 

- Inspector: Scene에 있는 Object들의 상세 설명

 

 

Play

영화와 게임 사이 미묘한 차이가 있긴 함

영화는 최종적으로 녹화한 화면을 보여주는 반면, 게임은 촬영은 하지만 캠코더로 실시간으로 보여주는 느낌이 강함

근본적 차이? 게임은 카메라맨이 플레이어 자신이기 때문에

그럼 촬영은 어떻게 하나?

Play 버튼을 누르면 된다

 

주의할 것: 촬영 종료되면 모든 것이 날라간다. 

 

 

Component 패턴

 

코드를 부품화해서 관리하는 것

 

왜 필요한가?

로직이 많아질 때 한 곳에 계속 추가하게 되면 나중에 수정, 가독성 용이하지 않게 됨

안 좋은 예 / 좋은 예

이것들을 예쁘게 관리할 수 있는 방법 중 하나가 Component 패턴

ex. 애니메이션 관련 된 것은 Animation Component

 

언리얼의 경우 Component와 상속을 반반 섞어서 사용하는 개념이라면, 유니티는 모든 것을 Component 패턴에 올인

 

- Game Object에 Mesh 입히기

1. Add Component -> Mesh Filter -> Cube

2. 이미 Cube인 Object에서 복붙

Cube -> Mesh Renderer -> Copy Componet -> Paste Componet As New

 

 

매니저 만들기

 

컴포넌트 용도의 C# 파일과 일반 C# 파일을 구분해서 사용하자!

 

MonoBehaviour란?

-상속 구조 파악

MonoBehaviour -> Behaviour -> Component -> Object

 

Object: Base class for everything attached to GameObjects.

C# 만든다고 해서 무조건 컴포넌트로 게임 오브젝트에 갖다 붙일 수 있는 것은 아니고, 

반드시 클래스 선언 옆에 MonoBehaviour를 붙여서 상속을 받아 줘야 파일을 컴포넌트로 인식해서 유니티 툴에서 붙일 수 있다.

 

매니저 같은 경우 컴포넌트 용도는 아니고 일반적인 클래스로 쓰고 싶으면 MonoBehaviour를 지워주면 된다.

 

그런데 Start, Update 함수는 저절로 호출되는게 아니라 부품으로 들어가 있을 때만 컴포넌트로 인식해서 유니티가 Start, Update 함수를 찾아주는거지 임의의 클래스로 만들어줄 경우 자동으로 찾아주지 않음

 

-> 씬에 빈 게임오브젝트 만들어서 Managers : MonoBehaviour로 다시 변경 후 스크립트 붙여준다. 

 

 

Singleton 패턴

 

Manager를 만들어줬는데, 어떻게 불러올까?

 GameObject go=GameObject.Find("@Managers");

 

정확히는 GameObject 자체를 가져오고 싶은게 아니라 GameObject 안에 들어있는 Manager 스크립트를 가져오고 싶다.

GameObject go=GameObject.Find("@Managers");
Managers mg=go.GetComponent<Managers>();

 

디버깅으로 매니저를 잘 가져오는지 확인해보자!

Breaking Point 찍고 Unity에 연결 누르기

 

이 상태에서 유니티 Play 버튼 누르면 Breaking Point에 걸린 것을 알 수 있음

 

 

- 게임 오브젝트를 이름으로 찾는 것은 권장하지 않음

만약 하나만 있는 클래스면 싱글톤 패턴을 사용할 수 있다.

 

특정 클래스의 인스턴스가 한 개만 있길 원할 때 싱글톤 패턴을 사용함

싱글톤을 구현할 때는 static을 이용해 전역으로 사용함

 

Managers.cs

static Managers Instance; //유일성이 보장된다
public static Managers GetInstance() { return Instance; } //유일한 매니저를 갖고 온다
void Start()
{
    GameObject go = GameObject.Find("@Managers");
    Instance = go.GetComponent<Managers>();
}

 

 

이렇게 하면 Scene에 @Managers가 없을 때 크래시가 날 수 있음

그래서 스크립트 상에서 만약 @Managers가 없을 때 만들어주는 기능을 넣어주는 것이 좋음

static Managers Instance; //유일성이 보장된다
//public static Managers GetInstance() { return Instance; } //유일한 매니저를 갖고 온다
public static Managers GetInstance() { Init(); return Instance; }

void Start()
{
    Init();
}

static void Init()
{
    if(Instance==null)
    {
        GameObject go = GameObject.Find("@Managers");
        if(go==null)
        {
            go = new GameObject { name = "@Managers" };
            go.AddComponent<Managers>();
        }
        DontDestroyOnLoad(go); //마음대로 삭제되지 않게 처리
        Instance = go.GetComponent<Managers>();
    }
}

 

결과

 

 

수정할 점

 

Player.cs

 void Start()
{
    Managers mg = Managers.GetInstance();
}

 

이렇게 함수 형태로 호출하는 것 보다 Instance, 즉 Property를 사용하는 것이 좋음

 

Managers.cs

static Managers s_instance;
public static Managers Instance { get { Init();  return s_instance; } }

Player.cs

Managers mg = Managers.Instance;

댓글