본문 바로가기
개발자가 되어보자..공부공부/개발 일지

C# 유니티 공부 25 - 디펜스 게임. (Snapping, 적 무한순환이동, 자동 적 생성, 자동 오브젝트 회전, 자동 공격)

by 묭묭이와소담이 2022. 12. 27.
반응형

* 필드 생성

★ 스냅핑(Snapping)

1) 정점 스내핑

- v를 누른 상태에서는 점을 맞출 수 있음. (Vertex)

- Shift+v로 정점 스내핑 기능을 On/Off 할 수 있음.

 

2) 단위 스내핑(Unit Snapping)

- Setting에 정의된 단위 거리만큼 게임 오브젝트를 배치할 수 있음.

(규칙적인 필드 맵 구현에 효과적.)

 

3) 면 스내핑 (Surface Snapping)

- ctrl + shift 를 누르고 오브젝트를 이동 시키면, 면을 맞출 수 있음.

 

 

★블랜더에서 매쉬를 가져왔을 때,  메터리얼 수정이 안되는 경우.

- 묶음으로 있을때는 수정이 안됨. Location에서 External Material(legacy)로 적용해줘야 가능.
- Important, if you can't change materials, set "location" to Use External Material (legacy) in the material window.

 

 


 

 

* 무한으로 순환하는 적 이동 구현.

- 자식오브젝트를 배열화.

★ 자식오브젝트를 얻어내는 함수들

(기본적으로 자식의 Transform을 얻고 싶을 때 사용하나, 다른 Component도 얻을 수 있다.)

1) 이름으로 자식 Objcet 찾기

transform.FindChild("이름")

otherGameObject.transform.FindChild("이름")  ---------- 외부 게임 오브젝트

2) 번호 순으로 자식 오브젝트 찾기

transform.GetChild(번호);

otherGameobject.transform.GetChild(번호); ---------- 외부 게임 오브젝트

3) 자식 오브젝트의 갯수를 알기

transform.childCount

 

 

* 스테이지 마다 규칙적으로 생성되는 적 구현.

- waveIndex로 스테이지 및, 새로운 적 생성 구현.

- 새로운 적이 나올 때마다, waveIndex 숫자에 따라 적의 수가 증가.

- 한 스테이지에 여러 적이 나올 때, 시간차이를 두기 위하여 코루틴 함수 사용.

 


 

* 아군 타워 적 감지 후 포탑 회전.

- OnDrawGizomsselected() 함수 이용.

오브젝트를 선택할 때, 기즈모에서 영역표시가 나타나게 됨. (Scene뷰에서만 확인 가능.)

Gizmo 함수는 매 프레임마다 호출.

영역의 범위를 ragne로 public 변수로 생성하여 사용.

 

1) 기즈모 범위 안에 있는 오브젝트 중,

FindeGameObjectsWithTag 함수를 이용해 태그가 enemy인 오브젝트를 배열에 저장.

public string enemyTag = "Enemy" 로 태그변수를 먼저 선언해주었음.

 

2) Mathf 함수 중 Infinity 사용.

Infinity는 무한대로 RayCast 함수를 사용할 때, 주로 사용한다.

float ShortestDisatance 변수를 무한대로 설정한다. (가장 짧은 거리)

GameObjcet nearestEnemy는 null로 설정. (가장 가까운 적)

 

3) foreach 문으로 1번단계에서 생성된 배열에서  {}를 반복하여 실행되게 함.

{}는 우선 float distanceToEnemy 변수에 감지된 적의 위치와 Turret간의 거리를 저장.

distancetoEnemy 가 ShortestDistance보다 작다면, 

ShortestDisance에 distancetoEnemy 값을 저장. (ShortestDistance는 무한대로 설정해놨기 때문에, 값이 저장될 수 밖에 없음)

nearestEnemy 변수에는 감지된 Enemy를 저장.

 

4) nearestEnemy에 값이 저장되어 null이 아니고, ShortestDistance가 Turret의 range보다 작다면?

target변수에 neartestEnemy를 저장.

 

5) 위 조건을 만족하지 못했다면 target은 null 값 반환.

 

6) Update문으로 이동하여 target이 null이라면 return으로 Update문에서 빠져나옴.

 

7) target이 있다면, target을 향해 터렛이 회전.

- 타겟과 터렛과의 벡터차이값을 dir변수에 저장.

- Quaternion.LookRotation(벡터좌표값)으로 해당 회전벡터값을 lookloation 변수에 저장.

  (타겟 벡터 방향을 바라보는 회전 상태를 구하는 과정.)

- 다시 한번 rotation 벡터 변수에 Quaternion.Lerp(초기회전값, 목표회전값, 속도).eulerAngles로 하여 저장.

★ eulerAngles는 오일러앵글을 의미하며.. x,y,z 세가지 축에 대한 값으로 반환값을 가진다.

eulerAngle.x / eulerAngle.y / eulerAngle.z 로 각 축을 기준으로 회전시킬 수 있다. 

- 최종적으로 Euler(x,y,z)를 Quaternion으로 변환시켜 목표 회전 변수에 대입해준다.

 

 

 

8) 터렛의 공격 딜레이 조건에 만족한다면, 포탄 발사 함수(Shoot()) 실행.

 

 


 

* 아군 타워 적 공격. 

- 적을 공격하는 포탄 생성 함수는 Turret 스크립트에서 작성.

- 포탄이 적의 위치로 이동하여 발생되는 공격 로직은 Bullet 스크립트에서 작성.

- 파티클 이펙트 사용.

- 오브젝트간 거리를 체크하는 함수

1) Vector3.Distance (float type 반환)

- 정확한 거리를 계산해 반환하지만, sqrMagnitude보다는 속도가 느림.

 

2) Vector3. magnitude (Vector3 type 반환)

- Distance와 성능과 기능은 동일.

x,y,z축 사이의 정확한 거리를 계산해 Vector3 타입으로 반환한다.

 

3) Vector3.sqrMagnitude

- 제곱 값을 루트 계산 없이 그대로 반환.

정확한 거리는 측정할 수 없고, 두 벡터 사이에서 크기 비교를 할 때 사용하기 적합하다.

 

 


 

* 유튜트 Brackeys 영상 참고함.

 

 

 

반응형

댓글