GameObject[] array = new GameObject[5];
arrya[2].name = "Test;
- 위의 문제는 무엇인가?
- 값형식의 배열인데 밑은 참조형식의 배열이기에 오브젝트 자체가 널이기에 ‘NullReferenceException’이 발생한다.
- array[0] = new Object;를 해야한다.
public class A
{
void DoWork() {}
}
public class B
{
A instA = new A();
instA.DoWork();
}
- 위의 문제는 무엇인가?
- DoWork()의 접근지정자는 지정을 안했기에 ‘private’로 자동지정 되기에 다른 클래스에서 사용할 수 없다.
Debug.Log("Hello");
GameObject[] array = new GameObject[5];
arrya[2].name = "Test;
Debug.Log("~");
private OnCollisionEnter(Collision collision)
{
Destroy(this, 3);
}
GetComponent<Animator> -> Update
- 위에처럼 안쓰는 이유
- 매번 검색되기 때문이다.
- 타입 체킹이 계속 되기 때문이다. 이건 2교시 녹음 듣자
OnTriggerEnter
private OnTriggerEnter(Collider other)
{
if(other.CompareTag("Player"))
{
Debug.Log("Hello");
}
}
높이맵으로 지형을 생성하는 방법
- 지형 표현할 텍스처 준비(Terrain)
- 텍스처 픽셀 하나당 정점 하나를 생성한다.
- 픽셀의 좌표를 정점의 X, Z 좌표로 매핑한다.
- 픽셀의 색상을 Y 좌표로 설정한다.
- 생성된 픽셀을 연결해서 지형을 생성한다.
지형 - 심리스 방식
- 심리스 : 현재 존재하는 맵과 인접한 모든 맵을 한번에 로딩한다.
- ‘오픈월드’를 의미한다. (해외에서 부르는 방식이 심리스다)
- 플레이어의 이동에 따라 플레이어가 이동할 확률이 높은 맵을 미리 로딩, 이동 확률이 작은 곳은 삭제한다.
Awake, Start
- Awake : 게임 오브젝트의 생성이 완료되고 초기화를 수행할 때 호출된다.
- Start : 첫번째 Update 수행 직전에 호출된다.
- 호출 순서 : Awake → Start
마우스 피킹
- 마우스 포인터의 스크린 좌표를 카메라를 이용해 역으로 투영
- 카메라 위치에서 near plane의 마우스 위치로 나가는 레이 구성,
- 해당 레이에 닿는 오브젝트를 선택한다.
특정 기능을 수행하기 위해 정수를 비교하는 방법과 문자열을 비교하는 방법이 있다고 했을때, 어느것을 선택하는 것이 좋은것인가?
- 정수
- 이유는? : 문자열은 결국 숫자의 집합이므로 매 자리마다 비교 수행해야 하기 떄문이다.
Resources 폴더
- 동적 로딩하는 폴더다
- 문제점 : 에셋 관리의 난이도가 증가한다.
- 메모리 관리가 복잡해진다.
- 빌드 및 게임 실행 시간이 길어진다.
태그 비교시 == 대신에 CompareTag 함수의 사용 이유?
- == 문자열을 비교하기 위해 힙에 임시공간을 생성한다.
- 따라서, 힙에 공간을 만든다는것은 힙을 제거해야하기 때문에 ‘가비지 컬렉션’이 발생한다.
- CompartTag는 컴파일러에서 적은 수의 CIL을 생성하도록 설계되어 속도가 빠르다.
- C#은 인터프리터인데, 인터프리터는 코드를 기계어로 바로 바꾸지않는다.
- visual C# → CIL(Assemblier) → exe
- visual C++ → exe(기계어)
- 즉 ,COmpareTag 함수를 사용하는 이유는 CIL이 적을수록 실행 시간이 단축되기때문에 더 빨라서 사용하는 것이다.
메모리 풀
- 객체 생성 / 샂게하기 위해 힙에 메모리를 할당 / 삭제하는 것은 많은 시간을 필요로 하며,
- 메모리 단편화 발생 가능성을 높이기 때문에, 하나의 큰 버퍼를 할당한 후 내부적으로 따로 관리해서 사용하는 것이 성능 향상에 도움이 된다.
Terrain
- raw 파일 : 음영값만 저장되어있는 파일
- ‘포토피아’라는 홈페이지에서 raw파일 가져와 맵을 보거나(12 - 34 클릭) 음영차(34 - 12)를 확인할 수 있다.
- 높이 맵
- 검정색 부터 (0, 0, 0) 흰색(1, 1, 1) 사이에서 고저자를 높이로 표현하여 이미지로 저장할 수 있다.
- 가장 순수한 흰색이 가장 높은 고도다.
- 가장 순수한 검정색이 가장 낮은 고도다.(일단 0으로 고정)
- 장점 : 매우 적은 메모리로 매우 넓은 지형 표현이 가능하다
- 단점 : 지형 구조가 단조롭다.
- 동굴이나 절벽 같은 급경사는 표현할 수 없다.
- 직각처럼 보여도 직각이 아니다. ⇒ 정점 2개중 하나가 기울어지며 올라간것이지 반듯하게 세워진 것이 아니기 때문이다.
- MeshGrid를 정점을 표현한 시각자료이고, Image는 픽셀로 표현한 Raw 파일이다.
- 한 정점은 Image에서 한 픽셀을 맡고 있다.
- 한 픽셀의 값을 0.5로 바꾼다면, 한 정점의 ‘높이’가 0.5로 바뀐다. / 그 다음 픽ㅔㄹ을 1로 바꾼다면 그 다음 정점의 높이도 1로 바뀐다.
- 이것을 올때 수직선이란 정점이 겹치는 형태이기 때문에 ‘높이 맵’에서는 사용할 수 없다. ⇒ 높이맵은 정점이 겹치지 않고 경사가 생기며 서서히 올라가는것이 보이기 때문이다.
LOD
- 씬에서 Player라는 이름을 가진 오브젝트를 찾아 target 변수에 저장하는 코드 작성
- GameObject target = GameObject.Find(”Player”);
- 씬에서 Player라는 태그를 가진 오브젝트를 찾아 target 변수에 저장하는 코드 작성
- GameObject target = GameObject.FindWithTag(”Player”);
- 씬에서 Character 타입을 가진 컴포넌트를 찾아 target 변수에 저장하는 코드 작성
- Character target = GmaObject.FindObjectOfType<Character>();
- 씬에서 컴포넌트를 찾는다면 FindObjectOfType를 사용한다.
- 2교시 녹음 듣자
- 씬에서 Character 타입을 가진 컴포넌트를 모두 찾아 target 변수에 저장하는 코드 작성
- Character target = GmaObject.FindObjectㄴOfType<Character>();
- Terrain을 관리하는 인스펙터? 이름?
- 동적으로 에셋을 가져오는 폴더 이름
- “Forest”라는 스프라이트를 런타임에 불러와 image라는 변수에 저장하는 코드를 작성 , 단 스프라이트는 Resources 폴더 안에 존재한다고 가정한다. (2D 에서는 스프라이트, 3D에서는 텍스처)
- Sprite image = Resources.Load<Sprite>(”Forest”);
- 프로그램에서 감지되고 탐지되어 처리하는 사건
- 프로그램이 비동기적인 동작이나 사건에 반응해서 동작을 변경하는 프로그래밍 패러다임?
- ‘이벤트 드리븐 프로그래밍’ 또는 ‘이벤트 기반’
- 에러가 출력되는 창 이름
- Click 로그를 남기세용~!!
빌트 인 셰이더
- 기본적으로 사용되는 셰이더
- 셰이더 코드로 작업한다.
SRP (Scriptable Rendering PipeLine)
- URP(Universial / 빌트인도 가져다 쓸 수 있어서 이것을 사용한다.) / HDRP (지원되는 에셋이 많이 없다 / 사양도 높다. / URP에서 옵션 몇개만 바꾸면 HDRP로 업그ㅔ이드 가능하다.)
Character Controller
Git
- 리포지토리 : 저장소
- 여곳에 보낸 파일들을 git의 형식대로 저자한다.(.meta 파일도 같이 보내야한다.)
- 대표적으로 SVN 또는 Git을 협업용 파일 저장소로 사용한다.
- SVN : client → Commit → Repo(저장소) → Pull → Client
- 무조건 중앙(원격저장소)으로 데이터가 간다.
- 이전 버전으로 돌릴 수 없다.
- Git : Client → commit → Local Repo(본인의 저장소) → Push → Repo
- 본인의 저장소의 버전을 이전버전으로 돌릴 수 있다.
- 무기면 무기, 다른 기능들을따로 프로젝트에 묶어서 올릴 수 있다.