※ Start 는 IEnumerator 형태로 가능핟. 즉 코루틴으로 호출이 가능하다
void Start >> IEnumerator Start // 그냥 Start 인데 형태만 콜틴인 것일뿐이다. 유일하게
※ OnEnable ( ) 은 오브젝트가 활성화 되는순간 호출된다 ! ( OnDisable 도 있다. 비활성화되는 순간 )
※ gameObject.activeSelf 게임오브젝트가 현재 활성화 상태인지 아닌지, bool 타입을 반환한다.
※ Single Turn 세상에 딱 하나밖에 없는 오브젝트 ( unity singleturn 검색해보면 많다. )
※ Static 이 붙으면 어디서든 접근할수있는 크래스가 생긴는 것, 누구든 접근 가능하다. Vector3 , Quartenion 생각하자.
어디서든 링크없이도 연결가능하다. Static 으로 고정된 메모리주소가생긴것.일종의 전역변수
스태틱 함수내에서는 스태틱 변수, 지역변수 등 다른곳에 영향을 주지않는 것만 사용한다.
사용 이유 : Find 나 FindwithTag 등 비교보다 훨씬 빠르다. 왜? 그냥 바로 직접 접근하고, 링크같은거 필요없이 어딧든 접근이 가능하기때문
단점은 이렇게 쉽게접근이가능하다보니 의존성이 높아지게되고 너무 곳곳에 퍼져있다.
※ 클래스 내의, this 는 자기자신(클래스, 컴퍼넌스)을 가리킨다.
※ Regedit - CURRENT_USER - software - 찾아가서 DefaultCompany 가서 해당 프로젝트 폴더 찾아가면,
Playerpref 에 가보면, 내가 저장한 값이 보인다.
※ Time.unscaledDeltaTime : TimeScale 의 영향을 받지않는 DeltaTime
콘솔창
Debug.Log 세 종류, Log / LogWarning / LogError ( 하양 / 노랑 / 빨강 )
Clear on Play : Play 했을 때, 기존의 콘솔을 비워주고 시작한다.
Error Pause : 에러가 나타나면, 멈춘다. 필수
Clear on Play / Error Pause 는 꼭 키도록 하자, 끌 이유가없는 것.
Collapse 같은 이유로 충돌 나는것들을 하나로 뭉쳐서 보여줌, 굳이 뭉칠 이유가없다.
여러번찍힐게 한번만 찍혀서 혼동을 불러올수가 있다.
Clear 해서 없어지는 오류는 가짜 오류다.
※ 유닡 오류잡기는 항상 가장 콘솔가장 위에있는 오류부터 잡아가야한다.
Pooling ( 미리 만들어놓고, 껏다 키고하지 실시간 생성파괴를안한다! )
Memory Pool ( 메모리 풀 ) : 메모리가 조각나눈 이유는 넣고 뺏고를 반복하기 때문이다.미리 구성된메모리를 필요할때
사용후 돌려보내는 방식 , 미리 만들어놓고 필요할때마다 꺼내쓰는 것을 생각하자
Instantiate 와 Destroy 를 사용하지않게될것이다. 다 미리 만들어놓고 가져다 사용하게 될것이다.
우리 눈에 보이고 안보일뿐
기존 메모리풀의 크기 이상의 요청이 드어와을땐 어떻게 하는가 ? 1. 무시 2. 확장 3. 재활용
이 밑의 케이스는 현재 무시 이다.
확장은 주로 Dictionary 혹은 List 를 사용하는것이 대부분이다.
ex) EnemyManager Start 부분을 수전한것
GameObject[] enemyPool = null; ※ 배열로 메모리풀을 관리할 것이다.
int poolSize = 10; ※ 풀의 크기
void Start()
{
enemyPool = new GameObject[poolSize]; ※ 배열의 크기를 정해주고
for( int i = 0; i < 10; i++)
{
enemyPool[i] = Instantiate(enemy) as GameObject; ※ 미리 모든 배열에 오브젝트들을 배치
enemyPool[i].name = "Enemy" + i; ※ 이름도 정해주고
enemyPool[i].SetActive(false); ※ 액티브 상태는 False 로 해놓는다.
}
}
ex2) EnemyManager 생성 부분 변경
void Update () {
deltaSpawnTime += Time.deltaTime;
if(deltaSpawnTime >= spawnTime)
{
// ++cnt; ※ 이제 메모리풀을 사용하므로, 굳이 숫자를 세서 맵상 공룡수를 컨트롤할 필요가없다.
deltaSpawnTime = 0.0f;
for(int i = 0; i < poolSize; i++) { ※ 풀사이즈만큼의 반복문 시작
GameObject newEnemy = enemyPool[i]; ※ newEnemy 에 배열에있는걸 꺼내담고
if (newEnemy.activeSelf) ※ 꺼내온 녀석이 이미 활성화됬다면 다음으로 넘어간다.
{ 활성화가 되어있다는 것은, 이미 맵상에 존재한다는것
continue;
}
newEnemy.SetActive(true); ※ 비활성화인 녀석을 찾았으므로 이녀석을 활성화 시켜주고,
// GameObject newEnemy = Instantiate(enemy) as GameObject; ※ 이코드는 필요없다.이제영원히
float x = Random.Range(-20, 20);
float z = Random.Range(-20, 20);
newEnemy.transform.position = new Vector3(x, 2, z); ※ 활성화된 녀석의 위치를 정해준다.
break; ※ 활성화 하나 시켰으므로 for 문을 탈출한다.
}
} ※ 11번째 요청이 들어온 경우, 이 케이스에서는, 아무일도 일어나지않게된다.
}
Get / Set 메소드
animation.isPlaying 처럼 변수처럼 겉보기엔 보이지만 내부에선 그렇지 않은 것이다.
public타입 이름{
get{
}
set{
}
}
ex )
public int bestScore ※ Get set 을 위한 선언
{
get ※ get 은 이럴때 Vector3 vec = Vector3.zero 이것처럼 읽어올때 사용 되는 것
{
return _bestScore;
}
}
public int myScore
{
get
{
return _myScore;
}
set ※ set 은 get 과 반대로 어떤 값을 세팅할때 이다.
{
_myScore = value; ※ value 는 C# 에서 미리정해준 것을 넘겨받아오는 값이다.
if( _myScore > _bestScore)
{
_bestScore = _myScore;
}
}
}
※ 예시를 들어서 보자
ScoreManager.Instance().myScore += 5; 이건 Set 을 한것이고,
int best = ScoreManager.Instance().bestScore 이건 Get을 한거다.
Data Save
PlayerPrefs : Stores and accesses player preferences between game sessions.
저장하는 3가지 SetInt SetFloat SetText 3가지고 불러오는 3가지 GetInt GetFloat GetText
인자 Set ( "변수명" , Value ) // Get ( " 변수명 " , Defalut 값 )
Time.timeScale = 0.0f
Update와 코루틴은 그래도 돌아간다. Fixed Update 는 안된다. 시간이 멈췄기 때문이다. 만약 Update 도 멈춘다면 한번 정지되면 영원히 풀수 없게될것이다. ( 코루틴에서, 시간을 기다리는 것이라면 코루틴도 멈춰있을 것이다. )
UI 도 시간의 영향을 받지 않는다.
시간이 흐르지 않는다는 것이므로 물리엔진도 작동을 안하고 ( 중력도 없고 ) OnTrigger OnCollision 모두 적용이 안된다.
'Programing > Game Programing' 카테고리의 다른 글
| C# 유니티 기반 VR 컨텐츠 개발 13일차 (0) | 2016.08.02 |
|---|---|
| XOR 연산, XOR 암호화 (1) | 2016.08.01 |
| 2D 런닝게임 만들다가 깨달은것들... (0) | 2016.07.30 |
| C# 유니티 기반 VR 컨텐츠 개발 11일창 (0) | 2016.07.29 |
| C# 유니티 기반 VR 컨텐츠 개발 10일차 (0) | 2016.07.27 |