Unity 5로 'Unity 3D로 배우는 실전 게임 개발'에 나오는 탱크게임 예제 따라하기.

게임은 용량이 좀 부담스러워 업로드를 미뤄 두다.

탱크 WS키로 전후진, AD키로 회전, QE키로 포탑 회전 처리.
키보드 좌 ctrl/마우스 좌 버튼 클릭시 포탄 발사.
카메라가 탱크 뒤를 따라가게 처리.
장애물 설치하고 Collider 탭의 'is Trigger' 체크한 뒤 function OnTriggerEnter(c:Collider)로 포탄이 장애물 충돌시 AudioSource.PlayClipAtPoint() 함수로 폭파 소리 출력하고 Destroy() 함수로 장애물과 포탄 제거시키기.
Tag에 Wall 추가하고 장애물에 Wall Tag 설정. if(c.gameObject.tag == "Wall"){ 폭파처리 } 로 포탄과 충돌한 것이 장애물일 경우만 폭파처리하기.
장애물 폭파시, 포탄 발사시 파티클로 폭파 효과와 포연 효과 추가하기.
폭파 효과에 넣는 'SmokeMat' Material의 경우 Texture엔 'smoke.png'를, Shader 엔Particles/Additive(soft)를 적용.

주인공 탱크 복제하여 적 탱크 만들고 적 탱크의 BulletSpawnPoint의 이름 변경, 빨간색으로 매핑.
transform.lookAt(목표transform)으로 주인공쪽을 향하게 처리.
Physics.Raycast(<기준점>,<방향>,<hitinfo>,<거리>)를 이용해 주인공 탱크가 자신의 근처에 접근하면 포탄을 발사하게 처리.
Raycast의 경우 글로벌 좌표계를 이용하므로 방향을
var fwd = Vector3.forward; //로컬 좌표 식이 아닌
var fwd = transform.TransformDirection(Vector3.forward); //글로벌 좌표로 바꿔줘야 제대로 작동한다.

Debug.Log()로 콘솔창에 메시지 보이기, Debug.DrawRay()로 에디터 상에 선을 표시하게 해 거리 시각화 하기.
Raycast에 걸린 물체가 주인공인지 태크로 확인하게 하여 포탄 발사하게 하기.
따발총처럼 연발하는 사격속도 제한 걸기.
RotateAround(<중심점>,<회전축>,<회전각도/sec>); 함수로 적 탱크 자동으로 원을 그리며 이동하게 처리.
function OnGUI(){ GUI.Label(Rect(x,y,width,height), "표시내용"+<점수>); } 함수로 화면에 점수 표시하기.
적과 아군탱크 각각 5발씩 맞을 경우 적 탱크의 경우 파괴, 아군 탱크의 경우 패배 화면으로 이동시키기.
승리시 화면과 패배시 화면 만들고 화면에서 아무키나 클릭시 메인 게임화면으로 이동시키게 처리.

15/8/25 화

유니티 5 자바스크립트 코딩 팁:

#pragma strict : 선언하지 않는 변수의 사용을 금지시키기.

이동: 오브젝트.transform.Translate(방향 * 속도)
회전: 오브젝트.transform.Rotate(방향 * 속도)
크기: localScale = Vector3(x, y, z)
힘 가하기: 오브젝트.GetComponent.<Rigidbody>().AddForce(방향 * 힘)
목표물 주시: transform.LookAt(Transform)

일정시간 대기하기:
yield WaitForSeconds(<대기할 시간(초)>): 지정 시간 동안 CPU를 다른 프로세스에 양보하기. 지정 시간이 지나면 그 이후 문장 처리
ex) yield WaitForSeconds(0.5); //0.5초 대기

프리팹 생성: Instantiate(<프리팹>,<생성 위치>,<생성 각도>);

Input.GetAxis("Horizontal") 좌우 이동키 눌렀을 때 이동방향
Input.GetAxis("Vertical") 상하 이동키 눌렀을 때 이동방향
Input.GetKeyDown() 특정 키를 눌렀는지 여부
Input.GetButtonDown() 특정 키를 눌렀는지 여부
Input.GetMouseButtonDown() 마우스 버튼을 눌렀는지 여부
Input.GetTouch() 스마트폰의 화면을 터치 했는지 여부
ex)
var hor: float = Input.GetAxis("Horizontal"); //좌우 (a, d)
var ver: float = Input.GetAxis("Vertical"); //상하 (w, s)

충돌판정:
OnCollisionEnter(Collision) 충돌 후 반사 등의 수학적 계산 수행
OnTriggerEnter(Collider) 충돌 후 반사 등의 수학적 계산 수행 안함.

목표물 탐색(Raycast):
가장 가까운 물체 탐색: Physics.Raycast(<기준점>,<방향>,<hitinfo>,<거리>)
전체탐색: Physics.RaycastAll(<기준점>,<방향>,<hitinfo[]>,<거리>)
지정한 범위 탐색: Physics.Linecast(<시작점>,<끝점>,<hitinfo>)
탐색결과는 RaycastHit Class로 구해짐. 정보 중 중요한 것:
distance: 탐지한 물체까지의 거리
collider: 탐지한 물체의 충돌체
rigidbody: 탐지한 물체의 리지드 바디
transform: 탐지한 물체의 위치 정보

<충돌체>.transform.parent 충돌체의 부모 오브젝트
<충돌체>.transform.root 충돌체의 최상위 오브젝트

물체 제거하기:
Destroy(<충돌체>.gameOobject);

소리 내기:
AudioSource.PlayClipAtPoint(낼 소리, 위치);
ex) AudioSource.PlayClipAtPoint(explosionSnd, transform.position); //폭파 사운드 출력

메시지 보내 다른 오브젝트 함수 실행하기:
Object.SendMessage(<"실행할 함수명">, [<파라미터 리스트>], [<옵션>]); - 파라미터 리스트와 옵션은 생략 가능.
ex) col.SendMessage("SetAsteroid", SendMessageOptions.DontRequireReceiver);
//충돌체의 SetAsteroid 함수 실행시키기. SendMessageOptions.DontRequireReceiver은 함수 실행 후 반환 값이 필요치 않을 때 처리 결과 반환 받지 않도록 함으로써 시스템 지연 방지.

범위 확인 처리:
Mathf.Clamp(<조사할 값>,<최소값>,<최대값>) 조사 값이 최소 값과 최대 값 사이이면 원래 값이 구해지고 벗어날 경우 각각 최소, 최대값을 얻는다.
ex) transform.position.x = Mathf.Clamp(transform.position.x, -29, 29); 이것은
if(transform.position.x < -29) transform.position.x = -29;
if(transform.position.x > 29) transform.position.x = 29; 와 같은 내용.

로컬 좌표를 글로벌 좌표로 바꾸기:
transform.TransformDirection(Vector3)
ex) var fwd = Vector3.forward; //로컬 좌표
var fwd = transform.TransformDirection(Vector3.forward); //글로벌 좌표
자신 중심, 월드 좌표 중심:
Space.Self 자신을 기준으로 한 로컬좌표
Space.World 게임뷰를 기준으로 한 월드좌표
ex) transform.Rotate(Vector3(amtRotX,amtRotY,amtRotZ),Space.Self); //자신 중심 회전
transform.Translate(Vector3(-amtX, amtY, 0),Space.World); //게임뷰 중심 이동

원을 그리며 이동하기:
RotateAround(<중심점>,<회전축>,<회전각도/sec>);
ex) transform.RotateAround(Vector3.zero, Vector3.up, amtRot);

화면에 표시하기:
function OnGUI(){ GUI.Label(Rect(x,y,width,height), "표시내용"+<점수>); }
ex) function OnGUI(){
//Rect(x, y, 넓이, 높이)
GUI.Label(Rect(10,10,120,20), "명중: "+hit);
GUI.Label(Rect(10,30,120,20), "피격: "+hited);
}

Debug 출력:
Debug.Log(<디버그 정보>); 콘솔창에 문자열 출력
print(<디버그 정보>); 콘솔창에 문자열 출력
Debug.DrawRay(<위치>,<길이>,<컬러>); 화면에 직선 표시
Debug.DrawLine(<시작점>,<끝점>,<컬러>); 화면에 직선 표시

속도 = 거리 / 시간
거리 = 속도 * 시간
매 프레임 이동 거리 = 속도(m/s) * Time.deltaTime

난수 만들기:
r = Random.Range(작은수, 큰수); 작은 수 <= r < 큰 수 사이의 임의의 수 생성