반응형

유니티 인강 31

Part 3-13-9. 미니 RPG : 몬스터 자동 생성, 完

미니 RPG 몬스터 자동 리스폰 서버 측에서 한다. 몬스터가 죽으면 몬스터의 전체적인 숫자를 맞춰주기 위해 랜덤한 위치에서 스폰을 한다. 이렇게 서버측에서 스폰을 한 후 클라이언트에게 알려준다. 📜 GameManager public Action OnSpawnEvent; public GameObject Spawn(Define.WorldObject type, string path, Transform parent = null) { GameObject go = Managers.Resource.Instantiate(path, parent); switch(type) { case Define.WorldObject.Monster: _monsters.Add(go); if (OnSpawnEvent != null) OnSp..

Part 3-13-8. 미니 RPG : 레벨업

미니 RPG 레벨업 ✈ 스탯 데이터 📄StatData.json { "stats": [ { "level": "1", "maxHp": "200", "attack": "20", "totalExp": "0" }, { "level": "2", "maxHp": "250", "attack": "25", "totalExp": "10" }, { "level": "3", "maxHp": "300", "attack": "30", "totalExp": "20" } ] } 각 레벨에서의 기본 스탯 📜Stat [Serializable] public class Stat { public int level; public int maxHp; public int attack; public int totalExp; } json파일의 내용과..

Part 3-13-7. 미니 RPG : Destory

미니 RPG Destroy 오브젝트가 Destroy 될 때 오브젝트가 메모리 해제되면 유니티의 Object의 == 연산자 오버로딩으로 인하여 해제된 객체를 == null 비교 연산할 땐 그 객체를 참조하는 참조 변수들은 댕글링 포인터가 되는 것이 아닌 “null”이 되도록 처리된다. 따라서 해제된 오브젝트의 컴포넌트를 참조하는 것들을 잘 확인해야 한다. 크러쉬가 날테니까! 오브젝트가 해제되면 당연히 그 오브젝트의 컴포넌트들에도 참조할 수 없다. 형변환 연산 비용 줄이는 대안 📜GameManager 에서 오브젝트들을 스폰하고 디스폰하는 작업을 할 것이다. 근데 어떤 오브젝트를 스폰해야하는지를 알아야 한다. 그러면 📜BaseController 타입으로 업캐스팅해서 받는 방법도 있을테고(근데 이러면 상속이 아..

Part 3-13-6. 미니 RPG : 몬스터 AI

미니 RPG 몬스터 AI 📜BaseController 👉 플레이어와 몬스터의 공통적인 속성과 기능 모음 1. 📜PlayerController 2. 📜MonsterController 📜MonsterController와 📜PlayerController의 공통적인 함수 및 멤버들은 📜BaseController로 옮겨주었다. 몬스터 애니메이션 컨트롤러의 애니메이션 클립의 이름들도 플레이어 애니메이션 컨트롤러와 동일하게. 📜MonsterController 몬스터 오브젝트에 붙여준다. 📜PlayerController 와 상당수 비슷하다. 여기에 없는건 📜BaseController로부터 상속 받는다. using System.Collections; using System.Collections.Generic; using..

Part 3-13-5. 미니 RPG : 체력 게이지

미니 RPG 체력 게이지 UI 만들기 체력 게이지는 몬스터와 플레이어 위에 따라다녀야함. 그러니 원근법 적용이 되야 한다. 3D 오브젝트처럼! 따라서 캔버스 렌더러 모드를 World Space로 바꿔준다. UI_HPBar : 캔버스 👉 RenderMode는 WorldSpace. 이땐 이 캔버스를 찍을 카메라도 할당해주어야 하는데, RenderMode, Camera 둘 다 코드로 로드해줄 것이다. HPBar : 슬라이더 이제 캔버스는 게임 월드 기준 좌표를 가지므로 캔버스와 슬라이더의 위치와 크기를 잘 맞춰주고 최종적으로 UI_HPBar 캔버스를 프리팹으로 만들어준다. 게임이 시작되면 몬스터와 플레이어의 산하 자식으로 Instantiate 시켜주어 몬스터와 플레이어를 따라다니게 할 것이다. 공격시 체력 깎..

Part 3-13-3. 미니 RPG : 타겟 락온

미니 RPG 📜Define public enum MouseEvent { Press, PointerDown, // 마우스 뗀 상태에서 처음 눌렀을 때 PointerUp, // 마우스 누르고 있던 상태에서 처음 뗏을 때 Click, } Press : 누르는 동안 PointerDown : 안 누르고 있던 상태에서 처음으로 눌렀을 때 PointerUp : 0.2초 이상 꾹 누르고 있던 상태에서 처음으로 뗏을 때 (꽤 누르고 있다가 뗐을 때) Click : 0.2초 이하로 누르고 있던 상태에서 처음으로 뗏을 때 (말 그대로 클릭 수준. 찰나만 누르고 뗐을 떄) 📜InputManager public class InputManager { public Action KeyAction = null; public Actio..

Part 3-13-2. 미니 RPG : 스탯 설정, 마우스 커서 변경

미니 RPG 스탯 📜Stat 👉 스탯을 가지는 모든 것들이 공통적으로 가지는 속성들 📜PlayerStat 👉 Stat을 상속 받음. 플레이어의 스탯 (플레이어 오브젝트에 붙는다.) 📜MonsterStat 👉 Stat을 상속 받음. 몬스터의 스탯 (몬스터 오브젝트에 붙는다) 📜Stat using System.Collections; using System.Collections.Generic; using UnityEngine; public class Stat : MonoBehaviour { // 멤버 변수 [SerializeField] protected int _level; [SerializeField] protected int _hp; [SerializeField] protected int _maxHp; [..

Part 3-13-1. 미니 RPG : 환경 설정, 이동

미니 RPG 게임을 만들 때 빈 프로젝트에서 처음부터 쌓아나가는 식으로 만들지 말고 여태까지 해온 온갖 매니저들 등등 이런 나만의 프레임 워크를 미리 구축해놓고 이를 활용해 만들어 나가기를 추천한다고 하셨다. 풀링 매니저, UI 매니저 등등 이런건 어떤 게임을 만들든 다 필요하다. Light 연산 RealTime 실시간으로 빛을 연산하겠다는 의미 이로 인해 성능 부하가 어마어마 하다. 그리고 움직이는 오브젝트라면 그 오브젝트의 빛 연산을 미리 Baked 할 수 없다. 어떻게 움직일 줄 알고 하겠는가? 🤯 Baked 이미 계산 완료 후 에셋으로 저장해놓은 라이트맵을 이용해서 게임 실행 중에 라이트 연산을 하지 않고 이를 덮어 쓴다. 라이트맵은 빛을 받으면 어떤 색으로 보일지 그림자는 어떻게 할지 등등 미리..

Part 3-12-1. Data : Json을 이용한 Data Manager

Data Data Manager 게임 내의 모든 수치, 데이터들을 관리하는 Manager 하드 코딩으로 수치를 세팅하고 바꾸는 것은 관리차원에서도 문제가 되고 더 큰 문제는 하드코딩된 수치는 exe 실행파일에 묶여 들어가기 때문이다. 나중에 수치를 변경해야할 업데이트 사항이 생긴다면 수정해서 만든 새로운 exe를 배포를 아예 다시 해야하는 일이 발생하는 것이다. 👉 따라서 모든 수치와 연관된 모든 데이터들을 모아둔 것을 따로 별도의 파일로 만든다. 일반적으로 json이나 XML파일로 만든다. 게임을 실행했을 때 웹 통신을 이용하여 데이터 파일 내용을 살짝 수정하기만 하면 되기 때문에 게임을 실행할 때 그 바뀐 데이터 파일을 로드해서 실행하게 되므로 게임 실행 파일을 수정하고 새배포 해야하는 그런 일은 하..

Part 3-11-1. Corutine : 코루틴 최적화, 커스텀

Corutine 코루틴은 하나의 프로세스를 여러 루틴들이 시간을 나눠서 사용하는 방식으로 스레드와는 다르다. 스레드는 동시에 여러 프로세스가 여러 작업을 병렬적으로 진행하는 것. 즉 코루틴은 직렬처리이며 병렬처리처럼 보이게끔 해주는 함수이다. 유니티는 병렬적으로 함수들을 동시에 여러가지 실행하지 못한다. 한번에 함수를 하나하나 실행시켜주는 것이다. 코루틴 원리 class Test { public int id = 0; } class CoroutineTest : IEnumerable { public IEnumerator GetEnumerator() // 인터페이스 구현 { yield return new Test() { id = 1 }; // Test 객체 리턴 후 다시 돌아 와서 밑에 실행 yield ret..

Part 3-10-1. Object Pooling : Pool Manager

Object Pool 오브젝트 풀을 왜 사용해야할까? 리소스 폴더에 있는 것을 Instantiate 하는 일련의 과정은 어마어마하게 느리며, SSD와 CPU는 여전히 물리적으로 거리가 떨어져 있기 때문이다. 👉 따라서 런타임 도중의 생성이 빈번하게 일어날 오브젝트에 대해서만 게임 시작 전에 미리 가져와서 로드해놓고 그를 재활용. 미리 로드해놓은 것을 켜주고 꺼주고 하는 식으로 관리하며 풀링을 진행한다. 풀링을 할 오브젝트, 풀링을 안 할 오브젝트를 구분해야 한다. 👉 이 구분을 풀링을 할 오브젝트들에만 📜Poolable 컴포넌트(스크립트)를 붙여 구분한다. 📜PoolManager 오브젝트 풀링 관리 📜Manager로 부터 사용 📜ResourceManager 를 보조 하는 역할. 📜Poolable 풀링 할..

Part 3-9-1. Sound : Sound Manager, 3D 사운드

Sound Sound Manager 1. MP3 Player, 소리 발생 근원지 👉 Audio Source 컴포넌트 2. MP3 음원, 어떤 소리를 재생할지, 음반 👉 Audio Clip 3. 관객, 듣는 사람, 귀 👉 Audio Listner 컴포넌트 Audio Listner 컴포넌트는 Main Camera에 기본적으로 달려있는 컴포넌트이다. 한 Scene 안에 하나만 있으면 된다. 소리를 발생시킬 오브젝트들에게 Audio Source 컴포넌트를 붙여준다. 이 컴포넌트의 Audio Clip 에 원하는 음원을 할당하면 된다. Volume : 소리 크기 Pitch : 재생 속도 (느리고 빠르게) 사운드 매니저를 사용하는 이유 AudioClip audioClip1; AudioClip audioClip2; A..

Part 3-8-1. Scene : Scene Manager

Scene 구조도 여태까지는 📜PlayerController에 Manager로부터 GameManager 스러운 일들을 실행시켰는데, 플레이어도 씬에 동적으로 생성되는 존재라면 📜PlayerController에 Manager를 호출하는 것은 바람직하지 않을 것이다. 생각해보면 이는 당연한 것이다. 🤔 따라서 게임 실행 내내 살아있는 선봉대 역할을 할 존재를 만들고 그에게 Manager를 호출하는 일을 맡겨야 한다. 이 선봉대 역할을 📜Scene에서 하는 것이다. 씬들. 각각 씬들만의 함수 📜BaseScene 📜GameScene 📜LoginScene 여러 씬들 한꺼번에 관리 👉 📜SceneManager 빈 오브젝트 @Scene 만들어서 그 곳에 Scene 종류가 되는 스크립트(📜GameScene 혹은 📜Lo..

Part 3-7-5. UI : 인벤토리 실습

UI 인벤토리(고정UI) 📜UI_Inven_Item UI_Inven 캔버스 UI 프리팹의 아이템 하나하나를 이루는 그 아이템에 붙는다. public class UI_Inven_Item : UI_Base { enum GameObjects // 구성 UI 오브젝트가 2개 뿐이라 그냥 GameObjects 한 곳에 묶음 { ItemIcon, ItemNameText, } string _name; void Start() { Init(); } public override void Init() { Bind(typeof(GameObjects)); // ItemIcon, ItemNameText 오브젝트 바인딩하여 상속받은 Dictionary _objects에 저장. Get((int)GameObjects.ItemNameT..

Part 3-7-4. UI : UI Manager, Blocker

UI UI 자동화를 위한 클래스 구조 📜Managers 👉 📜UIManager 를 싱글톤으로 관리 UIManager _ui = new UIManager(); public static UIManager UI { get { return Instance._ui; } } 📜PlayerController 👉 📜UIManager의 UI 캔버스 프리팹 생성해주는 ShowPopupUI(팝업 UI 경우) 함수를 호출시켜 UI 띄우기 void Start() { Managers.Input.MouseAction -= OnMouseClicked; Managers.Input.MouseAction += OnMouseClicked; // 임시로 생성 테스트를 진행한다 👻 Managers.UI.ShowPopupUI(); } 📜UIMa..

Part 3-7-3. UI : UI 자동화

UI UI 자동화 UI 자동화를 위한 클래스 구조 UI 구조 📜UI_Base 👉 모든 UI 의 조상, 모든 UI 캔버스들이 가지고 있는 공통적인 부분들. 📜UI_Scene 👉 씬 UI 의 조상, 팝업처럼 차례대로 뜨는게 아니라 원래 자리잡고 있는 고정적인 UI 캔버스들의 공통적인 부분들. 📜UI_PopUp 👉 팝업 UI 의 조상, 팝업 UI 캔버스들의 공통적인 부분들. (📜UI_Button) UI Canvas 의 종류를 고정적인 형태의 1️⃣Scene, 스택으로 관리되는 팝업 형태의 2️⃣PopUp 로 구분할 것. 바인딩, 이벤트 관련 함수 📜Util 📜UI_EventHandler 📜Define Bind : 이름으로 UI 오브젝트 찾아와 자동 할당 📜UI_Button UI_Button이라는 이름의 Can..

Part 3-7-2. UI : Button Event, IsPointerOverGameObject()

UI 팝업창 Managers.Resource.Instantiate("UI/PopUp_Canvas"); // 팝업 UI 캔버스 프리팹 생성. 이전에 📜ResourceManager 참고 게임에는 수 많은 팝업 UI 가 사용될 수 있다. 그러려면 각각의 팝업 UI 들이 독립적인 캔버스가 있어야 하고 이를 프리팹으로 만들어두어 그때 그때 생성하는 방식으로 사용해야 한다. 캔버스들은 서로 캔버스의 sort order 에 의하여 먼저 그려지고 가장 위에 그려지고 이런 순위가 결정된다. UI 입력 이벤트만 처리 using UnityEngine.EventSystems; //.. if (EventSystem.current.IsPointerOverGameObject()) return; IsPointerOverGameObj..

Part 3-7-1. UI : 기초, Rect Transform (앵커)

UI UI 기초 1. 캔버스는 도화지다 이미지, 텍스트 같은 UI 요소들은 반드시 캔버스의 자식으로 있어야지만 보이게 된다. 2. UI는 Rect Transform 으로 좌표를 관리한다. 3. UI는 씬에서 볼 때 3D가 아닌 2D로 보는게 더 편하다. T 단축키를 이용하여 Rect Transform 크기를 관리할 수 있다. 해당 기능 하나로 회전 이동 스케일 관리 다 할 수 있다. 회전 같은 경우는 모서리에 커서 갖다대면 가능 스케일도 그냥 크기 늘리듯이 키우면 되는데 shift를 누르면 비율을 유지한체 스케일 조정을 할 수 있다. 4. 중앙의 파란 점은 Pivot이다. 👉 중심 좌표 이 피봇을 중심으로 회전을 한다. 5. 바람개비 같은 것은 Anchor이다. 👉 원점 좌표 위치 찢어질 수도 있다. 6..

Part 3-6-3. 애니메이션 : KeyFrame, Event

Animation(애니메이션) Animation KeyFrame, 위치 - Window - Animation 모델에 종속된 애니메이션이 아니라 게임에 의존적인 애니메이션 직접 만들기. Animation 윈도우에서 애니메이션 클립을 만드려면 반드시 애니메이션을 적용할 오브젝트를 선택한 상태여야 활성화된다. 일종의 애니메이션 클립을 생성하는 과정이다. 애니메이션 컨트롤러의 상태 머신에 추가하고 이를 Animator 컴포넌트에 할당해주면 재생할 수 있다. 첫 번째 줄 👉 시간(프레임) 두 번째 줄 👉 애니메이션 이벤트 (다음 포스트)) 세 번째 줄 👉 프레임마다 키를 추가할 수 있음 Key : 해당 프레임에서 어떤 속성이 변할 경우 체크되는게 바로 키이다. 두 가지의 속성값만 변화시켜 입력하면, 즉 두 Key..

반응형