profile image

L o a d i n g . . .

article thumbnail image
Published 2020. 9. 1. 20:50
반응형

Component 패턴

게임 엔진 공부 시 "원리"를 이해하는 것이 중요하다.

디자인 패턴 -> 코드 작성 방법론

설계를 신경 안 쓰고 기능 구현 코드를 update에 전부 다 때려넣으면 언젠가는 다 벌을 받는다. (!!)
=> Component Pattern

모든 코드를 '부품화'해서 관리를 하는 것이 핵심이다.

AnimationComponent _anim = new AnimationComponent();
SkillComponent _skill = new SkillComponent();
PhysicsComponent _physics = new PhysicesComponent();

// 사용 시...
_anim.Update(deltaTick);
_skill.Update(deltaTick);
_physics.Update(deltaTick);

 

컴포넌트로 이용될 C# 파일과 일반 C# 파일을 구분해서 생각하자.

유니티 경고 로그 - MonoBehaviour를 상속받은 클래스는 new 연산자 동적 할당이 불가능함에 주의한다.

MonoBehaviour를 상속받아야 컴포넌트로 붙일 수 있다.

Scene에 배치하는 게임 오브젝트는 꼭 실체가 있는 사물일 필요가 없다.

 

 

Singleton 패턴

C# 스크립트 내에서는 특정 GameObject의 특정 컴포넌트를 손쉽게 가져올 수 있다.

단, GameObject.Find()는 현재 Scene 전체를 돌면서 이름으로 해당 오브젝트를 찾는 함수이기 때문에 부하가 심하다. 자주 사용해서는 안 됨에 주의한다!

=> Singleton Pattern

 

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

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

    // Start is called before the first frame update
    void Start()
    {
        // 초기화
        // 각각의 @Managers가 선언되었다고 해도 이렇게 찾아서 사용한다면 원본의 Managers가 instance에 저장될 것임
        GameObject go = GameObject.Find("@Managers");
        instance = go.GetComponent<Managers>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

단, 이 경우 @Managers라는 GameObject가 Scene에 존재하지 않는다면 코드가 동작되지 않을 것이다.

 

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

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

    // Start is called before the first frame update
    void Start()
    {
        Init();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    static void Init()
    {
        if(instance == null)
        {
            // 초기화
            // 각각의 @Managers가 선언되었다고 해도 이렇게 찾아서 사용한다면 원본의 Managers가 instance에 저장될 것임
            GameObject go = GameObject.Find("@Managers");

            // Scene에 GameObject인 @Managers가 없다면 새로 추가함
            if (go == null)
            {
                go = new GameObject { name = "@Managers" };
                go.AddComponent<Managers>();
            }
            // 새로운 Scene이 로드될 때 삭제되지 않게끔
            DontDestroyOnLoad(go);
            instance = go.GetComponent<Managers>();
        }
    }
}
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    // Start is called before the first frame update
    void Start()
    {
        Init();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    static void Init()
    {
        if(s_instance == null)
        {
            // 초기화
            // 각각의 Managers가 선언되었다고 해도 이렇게 찾아서 사용한다면 원본(@Managers)의 Managers가 instance에 저장될 것임
            GameObject go = GameObject.Find("@Managers");

            // Scene에 GameObject인 @Managers가 없다면 새로 추가함
            if (go == null)
            {
                go = new GameObject { name = "@Managers" };
                go.AddComponent<Managers>();
            }
            // 새로운 Scene이 로드될 때 삭제되지 않게끔
            DontDestroyOnLoad(go);
            s_instance = go.GetComponent<Managers>();
        }
    }
}

 

 

Player

transform.gameObject로 바로 해당 GameObject를 가져올 수 있다. 유용하다!

Input.GetKey(KeyCode.?)

반응형
복사했습니다!