본문 바로가기

레트로의 유니티 게임프로그래밍 에센스

유니티 탑다운 슈터 게임 좀비서바이버 개발일지 3일차

오브젝트의 확장성 문제

어떤 오브젝트의 스크립트에 값을 가진 필드들이 나열되어 있다고 가정합니다.

이 값들은 컴포넌트에 종속 되어있습니다.

 

예를들어 어떤 게임에서 플레이어가 사용하는 무기가 1. 카메라, 2. 단검, 3. 장검 이 있다고 가정해 보겠습니다.

프로젝트가 완성된 후 유지보수가 이루어지는 과정에서 무기의 종류가 더 다양해질 수가 있습니다.

 

또한 무기가 플레이어 손에 들려있는것만 존재하리라는 보장도 없습니다.

씬에 같은 오브젝트가 여러개 존재할 수도 있는 것이지요.

씬에 있는 오브젝트는 프리펩을 복사한 형태가 있겠지요.

 

이러다 보면 같은 오브젝트의 복사본 형태이지만, 값이 다른 오브젝트가 존재할 여지가 생깁니다.

 

그리고, 런타임 중에 값이 수정되는 경우가 있을 때, 예를 들면 모드를 변경하여 데이터가 수정되는 경우

장검에 폭주모드를 발동하면 공격력, 공격속도에 변화가 생길 수 있겠지요.

 

또, 외형은 같지만 성능이 강화된 버전의 검이 존재할 수도 있습니다.

이럴 때는 프리팹이 여러개 필요해 집니다. 검, 검+, 검++ 등등..

 

이럴때는 캡슐화를 구현해서 데이터를 은닉할 필요가 있습니다.

그리고, 다형성을 구현하게 되면

검의 껍데기와 검의 값을 분리시키는 것이 가능하게 됩니다.

값에 해당하는 데이터 스크립트를 따로 운용하면서, 껍데기만 갈아 끼우는 것입니다.

 

여기서 값에 해당하는 쪽을 스크립터블 오브젝트라고 합니다.

 

 

using UnityEngine;

public class KatanaData
{
    public AudioClip swingClip;
    public AudioClip putInClip;

    public float attackDelay = 10f;
    public float attackDamage = 100f;
}

 

 

이런식으로 아무것도 상속받지 않은 클래스에 데이터만 몰아넣은 후

클래스 선언 위에 Attribute를 추가 하는 형태입니다.

그리고 클래스가 ScriptableObject 라는 클래스를 상속하도록 합니다.

using UnityEngine;

[CreateAssetMenu(menuName = "Scriptable/KatanaData", fileName = "KatanaData")]
public class KatanaData : ScriptableObject
{
    public AudioClip swingClip;
    public AudioClip putInClip;

    public float attackDelay = 10f;
    public float attackDamage = 100f;
}

Attribute는 클래스나 메서드, 변수 데이터에 대한 추가 정보를 제공하는  C# 문법입니다.

대괄호로 특성 이름을 묶어주고, 값을 추가 전달합니다.

위의 예제에서는 menuName과 fileName을 추가 전달 했지요.

익숙한 모습에서 유추할 수 있듯이 menuName은 파일 경로이고 fileName은 파일 이름입니다.

Project 창에서 + 버튼을 누르면 ScriptableObject 라는게 항목이 보이게 됩니다.

 

ScriptableObject를 생성하고 경로명과 파일명을 위에 기재 했던것과 동일하게 맞춰주면 사용준비가 끝납니다.

에셋이 생성된 모습입니다.

Gun 스크립트 완성하기

OnEnable()

총의 상태를 완전히 초기화 하는 매서드

탄창의 양을 초기화 하고, 발사 준비 상태로 만든다.

마지막으로 총을 쏜 시점을 초기화 한다. ( 총을 쏜적은 없지만 초기 상태이기 때문이다. )

 

코루틴

유니티의 코루틴은 멀티스레드 기능을 사용하는 것과 같은 동작을 구현할 수 있게 해주는 기능입니다.

함수가 동작되는 과정을 떠올려 본다면 어떤 메서드가 실행될 때, 제어권이 그쪽으로 넘어오게 됨으로, 해당 동작이 실행되는 동안 다른 동작은 멈추게 됩니다.

 

코루틴을 사용하면 코루틴이 실행되는 동안 다른 작업이 동시에 실행 되는것 처럼 만들 수 있습니다.

일종의 병렬 구조를 만드는 것입니다.

(사실 실제 병렬 구조로 동작하는 것이 아니라 하나의 스레드가 찔끔찔끔 번갈아 가면서 실행 하는것입니다만 단일 스레드로도 프로그래머가 의도한대로 동작할 수 있게 하는 훌륭한 기능입니다.)

 

유니티의 메서드는 IEnumerator 타입을 반환해야 하며, 처리가 일시 대기할 곳에 yield 키워드를 명시해야 합니다.

IEnumerator 은 열거자 형태이며, 현재 값을 출력하는 것과 MoveNext 를 사용해서 다음 값을 출력하는 것으로 이루어져 있습니다.

 

코루틴을 사용해서 ShotEffect 매서드를 완성했습니다.