❓ Profiler란? 성능 분석을 위한 도구이다. 프로그램의 시간 복잡도 및 공간 상태(Memory), 함수 호출 주기와 빈도를 알아낼 수 있다 즉, Profiler를 이용하여 어떤 이유로 프로그램의 성능에 악영향을 미쳤는지 확인할 수 있다 Profiler는 Frame의 변화를 알아볼 수 있으며, 스크립트를 실행하거나 렌더링 작업을 수행하는데 걸리는 시간 등을 볼 수 있다 종류, 작업별로 시간을 모두 분석할 수 있으며 가장 시간이 많이 소요되는 작업부터 순서대로 정렬해서 보여준다 ❓성능 분석을 왜 해야하냐? 최적화가 잘 이루어지지 않은 게임을 하면 쉽게 말해 이른바 "렉"이 심하게 걸린다 성능 분석을 통해 게임의 최적화를 도울 수 있다 ❓ Profiler를 사용하는 방법 상단 [Window] - [An..
ref란? 참조에 의한 매개 변수 전달, 값이 할당된 변수를 사용해야 한다 void Swap(int x, int y) { int temp = y; int y = x; int x = temp; } void main() { int x = 3; int y = 4; Swap(x,y); print(x,y); //결과 x : 3, y : 4 } Swap메서드를 통해 x,y값이 바꾸길 바랬지만 바뀌지 않는다 ref키워드를 매개 변수 앞에 붙여주기만 하면 된다 void Swap(ref int x, ref int y) { int temp = y; int y = x; int x = temp; } void main() { int x = 3; int y = 4; Swap(ref x, ref y); print(x, y); //..
var 키워드란? var 키워드의 기능은 자료형을 자동으로 저장하는 것이다 var 키워드는 지역변수로 사용되어야 하며, 선언과 동시에 초기화 작업을 해야한다 var 100; print("Type : "+ var.GetType()); // 결과 Type : int32 var은 컴파일러가 변수를 생성할 때, 값을 보고 타입을 추론해서 stack 영역에 지정하고 값을 삽입한다 ex) var = 5; 이면 5라는 값을 통해 Type이 int라고 추론함 따라서, int형일 경우 4byte를 stack에 할당받게된다 var a = 5; //4byte var b = 6.6f;//8byte 따라서, int형인 a에 double형인 b의 값으로 덮어쓰려고 하면, a는 4byte의 영역을 할당받았기에 8byte의 영역을 ..
IEnumerator Start() { while (true) { yield return new WaitUntil(() => IsOnJump()); yield return StartCoroutine(JumpTo()); } } private bool IsOnJump() { if (agent.isOnOffMeshLink) { OffMeshLinkData linkData = agent.currentOffMeshLinkData; //OffMeshLinkType Manula = 0, Drop = 1, Jump = 2 if (linkData.linkType == OffMeshLinkType.LinkTypeJumpAcross || linkData.linkType == OffMeshLinkType.LinkTypeDro..
❓ Off Mesh Link란 사다리, 암벽과 같이 수직으로 올라가거나 내려오는 길 절벽 사이를 뛰어서 넘어가거나 낭떠러지 아래로 떨어지는 길과 같이 Mesh가 끊어져 있는 곳을 이동할 수 있께 설정하는 것이다 📖 자동으로 Off Mesh Link 설정하는 방법 Navigation View에서 Object 탭을 선택하고 Genertate OffMeshLinks를 체크한다 그 후 Bake탭에 가서 Drop Height와 Jump Distance 값을 설정한 후 Bake를 눌러 데이터를 저장해주면 된다 📌자동 Off Mesh Link 장단점 더보기 장점 : 게임월드에 배치된 많은 오브젝트의 Off Mesh Link를 한꺼번에 설정 할 수 있다 단점 : 낙하 높이와 점프거리를 하나만 설정할 수 있어 다양한 지..
위 모델의 Animation State는 Default Layer의 Idle State입니다. 걷는 애니메이션과 오브젝트를 들고 있는 애니메이션을 혼합(Mix)해서 사용하고 싶습니다. 애니메이션 State를 혼합할 때 사용하는 것이 Animation Layer입니다. Avatar Mask를 하나 생성하고 이름을 그에 맞게 변경해줍니다. 특정 오브젝트를 잡고 있는 애니메이션의 상태에서 하체의 움직임은 필요없고 상체의 움직임만 변경되길 원하므로 하체는 클릭하여 제외시켜주면 됩니다. Animator창으로 가서 Layer버튼을 누르고 + 버튼을 눌러 새로운 Layer을 만들어준 뒤 이름을 적절하게 변경해줍니다. Weight 현재 레이어와 아래 레이어의 애니메이션 비중, 1에 가까울수록 현재 레이어의 가까운 모션..
💡Custom Editor Custom Editor란 Unity에서 Editor를 커스터마이징 한다는 뜻이다 커스터마이징을 통해 개발자들은 유니티 에디터 자체에 특정 기능을 추가할 수 있다 예를 들면, 인스펙터창에 특정 버튼을 누르면 특정 에셋들이 Load 된다거나, 자동으로 맵을 생성해준다거나 등등 잘 활용만 한다면 개발하는데 엄청난 편의성을 느낄 수 있다 💡유니티 에디터 커스터마이징을 하기 위해서는 몇가지 개념들을 알아두어야 한다 먼저, 유니티 에디터 코드가 동작하는 레벨에 대해 알 필요가 있다 우리가 흔히 사용하는 C# 스크립트들은 모든 레벨에서 사용이 가능하다 즉, 빌드 된 환경에서도 동작하고, 유니티 에디터 환경에서도 잘 동작한다는 뜻이다 하지만, 에디터 코드는 에디터 환경에서만 동작하고 빌드 ..
💡namespace namespace는 클래스들의 묶음이다 namespace를 쓰는 이유는 프로젝트의 규모가 커질수록 각종 이름들의 충돌 발생 가능성을 막아주기 위함이다 namespace 네임스페이스-이름 { class A{} class B{} ... } 💡namespace 사용방법 네임스페이스를 사용하는 방법은 2가지 있다 전체 네임스페이스를 다 적는 방식 using 지시문을 사용하는 방식 UnityEngine.Debug.Log("네임스페이스 호출"); 위와 같이 UnityEngine라는 namespace을 선언해준다음 사용하거나 using UnityEngine; public class Namespaces : MonoBehaviour { void Start() { Debug.Log("네임스페이스 호출"..
ScriptableObject란 ScriptableObject는 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너입니다. ScriptableObject를 쓰는 이유는 다음과 같습니다. 기존 클래스는 내부 변수 하나 당 4Byte가 듭니다(변수에 따라 다름) . 총 4개의 변수가 사용된다 가정할 때, 4X4 = 16Byte가 메모리에 사용되게 됩니다. 만약 좀비라는 몬스터 프리팹이 1000마리를 일반클래스의 변수로 구현했다면 16 X 1000 = 16000Byte(16KB)가 메모리에 사용되게 됩니다. 16KB는 큰 값은 아니지만, 추후 변수가 추가됨에 따라 점점 메모리 소모량이 많아질 것입니다. 하지만, 스크립터블 오브젝트를 사용하면 좀비를 몇 백마리 사용하든 메모리..
폭탄이 폭발했을 때 주변 오브젝트들과 상호작용할 때 사용하면 유용하다 Collider[] colliders = Physics.OverlapShere(폭발위치, 반지름); foreach(Collider col in colliders)을 이용하여 조리하면 된다 물론, 주변 오브젝트에 콜라이더가 달려있어야한다
콜라이더 끄는 방법은 쉽다 BoxCollider를 예시로 들묜 GetComponent().enable = true; //켜기 GetComponent().enable = false; //끄기 enable로 끄고 킬 수 있다!
ViewportToWorldPoint & WorldToViewportPoint 활용법 오브젝트가 화면(보여지고 있는 화면)에서 벗어나게 하지 않게 하고 싶을 때 사용하면 된다 이렇게 Cube오브젝트는 화면밖으로 나가지 않는다전 시간에도 말했다시피 ViewPort는 비율이므로 0~1사이 값으로 컨트롤한다Cube의 World Transform Position을 ViewPort 좌표계의 값으로 변환한다 그러면 ViewPort좌표계에 0~1비율 사이에 존재하게 되는데 이때 x좌표가 0 or 1을 벗어나려고 하면 최대치를 0과 1로 하여 화면에 고정시킨다 그다음으로 ViewPort좌표계의 위치를 다시 3차원의 좌표계 World 좌표계로 변환해준다 그거를 transform에 대입한다 ScreenToWorldPoin..
ScreenPointToRay에 대해 알아보자 우리는 모니터를 통해 3차원 게임을 바라본다 모니터는 2차원 (쉽게 설명하면 가로, 세로로만 이루어진)으로 되어 있는데 어떻게 2차원 모니터의 한 지점을 눌렀을 때 게임 환경인 3차원에서의 Point지점으로 갈 수 있을까? 일단 원리는 이러하다 카메라로부터 플레이어가 클릭한 위치로 Ray(광선)을 쏜다 현재 카메라에 보이는 화면을 관통해 뻗어나가는 광선은 지정한 길이에 도달하거나 오브젝트에 부딪히면 멈춘다 오브젝트에 부딪혀 멈추게 되면 오브젝트의 정보를 얻는다 내용이 이해가 가지 않으면 그냥 이렇게 생각하자 Mouse를 클릭한 곳에 뭔가의 Interaction을 취하고 싶으면 ScreenPointToRay이 녀석을 이용하면 된다~! (해석하면 카메라로부터의 ..
애니메이션 특정 클립에 Event 추가하기 원하는 프레임에 원하는 Events를 추가할 수 있습니다. 이때 주의할 점은 Function이름입니다. 함수 이름을 OnAttackCollsion으로 지었고, OnAttackCollsion을 실행시키고 싶다면 Event Function의 이름도 똑같이 해주어야 합니다. Animator컴포넌트와 실행시키고 싶은 Event Function이 담겨져 있는 스크립트 컴포넌트는 같은 곳에 있어야합니다.
뭔가 특수한 상황에서 카메라를 흔들고 싶은 연출이 필요할 때가 있지 않음? 그럴때를 위한 방법을 가져왔음! 먼저 싱글톤 패턴을 이용하여 다른 코드에서 손쉽게 접근할 수 있도록 해줘! 그리고 OnShakeCamera가 호출될 때마다 카메라가 흔들리게 할거야! 첫 번째 방법은 Camera의 Position자체를 움직이는거고! 두 번째 방법은 Camera의 Rotation을 바꿔주는거임! 나 같은 경우에는 칼같은 무기에 상대 Enemy가 닿으면 카메라가 흔들리게끔 설정했음! CameraShake.Instance아래 코드는 무시하셈~
Create new BlendTree in State를 눌러 블렌드트리를 만들자 플레이어가 왼쪽키를 눌렀을 때 왼쪽으로 향하는 듯한 애니메이션을 실행시키고 싶을 때 Blend Tree를 사용하여 애니메이션을 컨트롤한다 변수 Float로 Horizontal, Vertical 2개를 받는다 그리고 5개의 상태에 맞게 각각 Parameter값을 조정한다 코드를 생성해준다
연속적인 애니메이션에는 무엇이 있을까? 연속 공격, 연속 점프 등 있다 Animator창을 열어 Create Sub-State Machine을 선택하자 연속적으로 표현하고 싶은 애니메이션을 추가한다 Parameter는 Attack이라는 이름으로 Trigger를 하나 만들어준다 위에 두 사진이 핵심이다 잘봐야한다 먼저 Attack1 -> Attack2로 갈 때 Exit Time이 0.79로 설정되어 있는걸 볼 수 있다 Attack1 -> Base Layer로 갈 땐 Exit Time이 0.9로 설정되어 있다 Exit Time같은 경우 Has Exit Time이 체크되어야만 활성화되는 녀석이다 이 녀석이 0.9라는 뜻은 애니메이션이 90%로 실행되었다는 뜻이다 즉, 90%로 실행되기 전에는 Attack Tr..
먼저 Door 오브젝트와 빈오브젝트인 Pivot오브젝트를 생성해준다.Pivot오브젝트는 문의 Pivot에 놓는다. Pivot설정할 때 V누르고 하면 피봇 설정하기 매우 편하다.Door 오브젝트에 One Grab Rotate Transfomer컴포넌트와 Rigidbody를 만들어준다.각도를 설정해줘야 하는데, Constaints를 열어 설정해주면 된다(Pivot 오브젝트 Rotation을 돌리며 확인)이때 One Grab Rotate Transformer는 Grabbable의 One Grab Transformer에 할당해줘야 한다 + 추가돌리고자 하는 객체에는 One Grab Rotate Transformer와 Rigidbody함께!잡고 싶은 핸들에는 콜라이더만!그리고 자식 오브젝트 하나 만들고 거기에 ..
ML-Agents를 사용하는 방법에는 2가지가 있다 첫 번째, ML-Agents에서 제공하는 mlagents-learn 기능을 이용해 학습을 수행, 이 경우 강화학습 알고리즘을 직접 구현하지 않아도 되고 간단한 명령어만으로 학습을 수행할 수 있다, 단점으로는 학습과 관련된 파라미터만 변경이 가능하고, 알고리즘에 대한 변경은 제한적 두 번째, ML-Agents의 Python-API를 사용하여 직접 구성한 파이썬 코드를 통해 에이전트를 학습하는 것, 알고리즘에 대한 변경이 자유롭지만 직접 구현해야 한다는 점에서 난이도가 높다 # ML-Agents에서 제공하는 강화학습 알고리즘 Proximity Policy Optimization (PPO) Soft Actor Critic (SAC) Curiostiy base..