유니티3D_7

Download Report

Transcript 유니티3D_7

모바일
게
임
제작
한국IT전문학교
박재성
Flying Owl
7
장
모바일
게
임
제작
7.1 게임의 개요
- 올빼미가 나뭇가지를 밟고 점프해서 위로 높이 날아가는 2D 게임
- PC/웹용 게임에서는 키보드로 올빼미가 이동. 모바일에서는 좌우로 기울여서 (가속센서) 이
동
7.3 게임의 리소스
7.4 게임의 흐름도
7.5 카메라와 Light 설정
- 2D 형태로 제작. 카메라의 원근이 필요없다.Projection 속성을 Orthographic으로 지정.
- Directional Light 추가
7.6 Object 만들기
- 1) 배경하늘 만들기
plane을 설치하고, 이름은 sky로 변경. sky비트맵 설정
- 2) 올빼미 만들기
plane을 설치하고, 이름은 owl로 변경.비트맵을 owl1으로 매핑
7.6 Object 만들기
- 3) 나뭇가지 만들기
plane을 설치하고, 이름은 Branch로 변경. branch비트맵 설정
- 4) 선물 만들기
plane을 설치하고, 이름은 Gift로 변경.비트맵을 gift1으로 매핑
- 5) 참새 만들기
Plane을 설치하고, 이름은 Bird로 변경. 비트맵을 bird_107X92X6으로 매핑
- 6) 점수 오브젝트 만들기
하이어아키에서 Create > GUI Text 선택해서 GUI Text 추가. 이름을 txtScore로 설
정.
7.7 Object에 Collider 추가
- Owl, Bird는 Sphere Collider 추가
- Branch, Gift는 Box Collider추가
- Owl에는 Rigidbody도 추가. Is Trigger 는 ON, Use Gravity는 해제
7.8 Object에 Tag 달기
- Gift에는 태그를 지정하지 않는다. 코드로 동적 지정.
- Branch, Bird는 태그 지정
7.9 프리팹 만들기
- Prefab 폴더를 만들고 Branch, Gift, Bird, txtScore를 프리팹으로 만든다.
- 하이어아키의 Gift, Bird, txtScore는 삭제.
7.10 게임 화면 디자인
7.10 게임 화면 디자인
- Spawn Point 만들기
빈 오브젝트를 만들어서 spPoint로 작명한 후 Position을 (0, 12, 03)으로 설정
- Main Camera의 하위 개체 설정
배경화면과 spPoint를 Main Camera의 하위 개체로 설정. 카메라와 같이 이동하도록 함.
7.11 게임 화면 스크롤
using UnityEngine;
using System.Collections;
public class CsSky : MonoBehaviour {
float speed = 0.03f;
void Update ()
{
//오프셋이용.
float ofsX = speed * Time.time;
transform.renderer.material.mainTextureOffset = new Vector2(ofsX, 0);
}
} // end of class
7.11 게임 화면 스크롤
- Spawn Point 만들기
빈 오브젝트를 만들어서 spPoint로 작명한 후 Position을 (0, 12, 03)으로 설정
- Main Camera의 하위 개체 설정
배경화면과 spPoint를 Main Camera의 하위 개체로 설정. 카메라와 같이 이동하도록 함.
7.12 화면을 벗어난 나뭇가지 제거
using UnityEngine;
using System.Collections;
public class CsBranch : MonoBehaviour {
void Update () {
// 월드 좌표를 스크린 좌표로 변환
Vector3 view = Camera.main.WorldToScreenPoint(transform.position);
if (view.y < -50) { //화면 아래로 내려가면 제거
Destroy(gameObject);
}
}
} // end of class
7.13 Gift 스크립트 작성
void DisplayScore () {
// Gift의 Tag를 점수로 변환
int n = int.Parse(transform.tag.Substring(4, 1)) * 500;
// 점수 표시용 GUIText 만들기
Transform obj = Instantiate(txtScore) as Transform;
obj.guiText.text = "<size=22><color=green>+" + n + "</color></size>";
// World 좌표를 Viewport 좌표로 변환
var pos = Camera.main.WorldToViewportPoint(transform.position);
obj.position = pos;
// Gift 제거
Destroy(gameObject);
}
7.14 참새의 이동
public class CsBird : MonoBehaviour {
public Transform txtScore;
int frmCnt = 6;
int frmPerSec;
float frmDelay;
int frmNum = 0;
// 프리팹
// 전체 프레임 수
// 1초에 표시할 프레임 수
// 프레임 표시 간격
// 현재 표시할 프레임 번호
int speed;
bool isDrop = false;
// 추락중인가?
void Start () {
speed = Random.Range(3, 7);
frmPerSec = Random.Range(10, 18);
frmDelay = 1.0f / frmPerSec;
}
// 이동 속도
7.14 참새의 이동
void Update () {
float amtMove = speed * Time.smoothDeltaTime;
if (!isDrop) {
AnimateBird();
transform.Translate(Vector3.right * amtMove);
} else {
// 아래로 이동
transform.Translate(Vector3.down * amtMove, Space.World);
}
// 화면을 벗어난 오브젝트 제거
Vector3 view = Camera.main.WorldToScreenPoint(transform.position);
if (view.y < -50 || view.x > Screen.width + 50) {
Destroy(gameObject);
}
}
7.14 참새의 이동
void DropBird () {
isDrop = true;
// 참새 회전
transform.eulerAngles = new Vector3(0, 0, 180);
// 감점 표시
Transform obj = Instantiate(txtScore) as Transform;
obj.guiText.text = "<color=red><size=22>-1000</size></color>";
// World 좌표를 Viewport 좌표로 변환
var pos = Camera.main.WorldToViewportPoint(transform.position);
obj.position = pos;
}
- txtScore변수에 txtScore 프리팹 연결
7.15 득점 및 감점 표시
void Start () {
StartCoroutine("DisplayScore");
}
void Update () {
Vector3 pos = transform.position;
pos.y += 0.001f;
transform.position = pos;
}
IEnumerator DisplayScore() {
yield return new WaitForSeconds(0.5f);
for (float a = 1; a >= 0; a -= 0.05f) {
transform.guiText.material.color = new Vector4(1, 1, 1, a);
yield return new WaitForFixedUpdate();
}
Destroy(gameObject);
}
7.16 올빼미의 이동
public class CsOwl : MonoBehaviour {
public GUISkin skin;
// GUI Skin
public Transform branch;
public Transform gift;
public Transform bird;
// 프리팹
public AudioClip sndJump;
public AudioClip sndGift;
public AudioClip sndBird;
public AudioClip sndStage;
public AudioClip sndOver;
// 효과음 및 배경음악
7.16 올빼미의 이동
Transform spPoint;
Transform newBranch;
// Spawn Point
// 새로만들 나뭇가지
int speedSide = 10;
int speedJump = 16;
int gravity = 25;
// 좌우 이동 속도
// 점프 속도
// 추락 속도
Vector3 moveDir = Vector3.zero;
int giftCnt = 0;
float score = 0;
float maxY = 0;
bool isDead = false;
// 올빼미의 이동 방향
// 획득한 선물 수
// 득점
// 올빼미의 최대 높이
7.17 게임 초기화
void Start () {
// 모바일 단말기 설정
Screen.orientation = ScreenOrientation.LandscapeRight;
Screen.sleepTimeout = SleepTimeout.NeverSleep;
spPoint = GameObject.Find("spPoint").transform;
// 나뭇가지 만들기
newBranch = Instantiate(branch, spPoint.position, spPoint.rotation) as
sform;
Screen.showCursor = false;
// 커서 감추기
}
void Update () {
if (isDead) return;
JumpOwl();
MoveOwl();
MoveCamera();
MakeGift();
}
// 올빼미 점프
// 올빼미 이동
// 카메라 이동
// 선물과 새 만들기
7.18 게임 루프
void Update () {
if (isDead) return;
JumpOwl();
MoveOwl();
MoveCamera();
MakeGift();
}
// 올빼미 점프
// 올빼미 이동
// 카메라 이동
// 선물과 새 만들기
7.19 올빼미의 점프
void JumpOwl () {
RaycastHit hit;
// 올빼미 아래에 나뭇가지가 있는지 조사
if (Physics.Raycast(transform.position, Vector3.down, out hit, 0.9f)) {
if (hit.transform.tag == "BRANCH") {
moveDir.y = speedJump;
AudioSource.PlayClipAtPoint(sndJump, transform.position);
}
}
}
7.20 올빼미의 좌우 이동
void MoveOwl () {
// 올빼미 위치를 Screen 좌표로 변환
Vector3 view = Camera.main.WorldToScreenPoint(transform.position);
if (view.y < -50) {
isDead = true;
return;
}
// 화면 아래를 벗어나면
// 게임 오버
moveDir.x = 0;
// 올빼미의 좌우 이동 방향
7.20 올빼미의 좌우 이동
// Mobile 처리
if (Application.platform == RuntimePlatform.Android ||
Application.platform == RuntimePlatform.IPhonePlayer) {
// 중력 가속도 센서 읽기
float x = Input.acceleration.x;
// 왼쪽으로 기울였나?
if (x < -0.2f && view.x > 35) {
moveDir.x = 2 * x * speedSide;
}
// 오른쪽으로 기울였나?
if (x > 0.2f && view.x < Screen.width - 35) {
moveDir.x = 2 * x * speedSide;
}
} else {
}
// Keyboard 읽기
float key = Input.GetAxis("Horizontal");
if ((key < 0 && view.x > 35) ||
(key > 0 && view.x < Screen.width - 35)) {
moveDir.x = key * speedSide;
}
7.20 올빼미의 좌우 이동
// 매 프레임마다 점프 속도 감소
moveDir.y -= gravity * Time.deltaTime;
transform.Translate(moveDir * Time.smoothDeltaTime);
// 올빼미의 날개
int n = 2;
if (moveDir.y < 0) n = 1;
// 날개 펴기
// 날개 접기
transform.renderer.material.mainTexture = Resources.Load("owl" + n) as Texture2D;
}
7.20 올빼미의 좌우 이동
7.21 카메라의 이동
void MoveCamera () {
// 올빼미의 최대 높이 구하기
if (transform.position.y > maxY) {
maxY = transform.position.y;
// 카메라 위치 이동
Camera.main.transform.position = new Vector3(0, maxY - 2.5f, -10);
score = maxY * 1000;
}
// 가장 최근의 나뭇가지와 spPoint와의 거리 구하기
if (spPoint.position.y - newBranch.position.y >= 4) {
float x = Random.Range(-10f, 10f) * 0.5f;
Vector3 pos = new Vector3(x, spPoint.position.y, 0.3f);
newBranch = Instantiate(branch, pos, Quaternion.identity) as Transform;
// 나뭇가지의 회전방향 설정
int mx = (Random.Range(0, 2) == 0) ? -1 : 1;
int my = (Random.Range(0, 2) == 0) ? -1 : 1;
newBranch.renderer.material.mainTextureScale = new Vector2(mx, my);
}
}
7.22 Bird와 Gift 만들기
void MakeGift () {
if (Random.Range(1, 1000) < 980) return;
Vector3 pos = Vector3.zero; // 오브젝트 표시 위치
pos.y = maxY + Random.Range(4, 5.5f);
if (Random.Range(0, 100) < 50) {
pos.x = -12f;
Instantiate(bird, pos, Quaternion.identity); // 참새 만들기
} else {
//선물 만들기
pos.x = Random.Range(-5f, 5f);
Transform obj = Instantiate(gift, pos, Quaternion.identity) as Transform;
int n = Random.Range(1, 4);
obj.tag = "GIFT" + n;
obj.gameObject.renderer.material.mainTexture =
Resources.Load("gift" + n) as Texture2D;
}
}
7.23 Gift의 개수 제한
if (Random.Range(0, 100) < 50) {
// 참새 만들기
pos.x = -12f;
Instantiate(bird, pos, Quaternion.identity);
} else {
// 화면의 선물 수를 5개 이내로 제한
int n1 = GameObject.FindGameObjectsWithTag("GIFT1").Length;
int n2 = GameObject.FindGameObjectsWithTag("GIFT2").Length;
int n3 = GameObject.FindGameObjectsWithTag("GIFT3").Length;
if (n1 + n2 + n3 >= 5) return;
…
}
7.24 충돌의 판정
void OnTriggerEnter (Collider coll) {
switch (coll.transform.tag.Substring(0, 4)) {
case "GIFT" :
AudioSource.PlayClipAtPoint(sndGift, transform.position);
// 득점 처리
int n = int.Parse(coll.transform.tag.Substring(4));
score += n * 500;
giftCnt++;
// 선물 제거
coll.transform.SendMessage("DisplayScore", SendMessageOptions.DontRequireReceiv
break;
case "BIRD" :
if (coll.transform.eulerAngles.z != 0) return;
AudioSource.PlayClipAtPoint(sndBird, transform.position);
score -= 1000;
// 참새 추락 처리
coll.transform.SendMessage("DropBird", SendMessageOptions.DontRequireReceiver);
break;
}
}
7.25 득점 및 게임 오버 표시
void OnTriggerEnter (Collider coll) {
switch (coll.transform.tag.Substring(0, 4)) {
case "GIFT" :
AudioSource.PlayClipAtPoint(sndGift, transform.position);
// 득점 처리
int n = int.Parse(coll.transform.tag.Substring(4));
score += n * 500;
giftCnt++;
// 선물 제거
coll.transform.SendMessage("DisplayScore", SendMessageOptions.DontRequireReceiv
break;
case "BIRD" :
if (coll.transform.eulerAngles.z != 0) return;
AudioSource.PlayClipAtPoint(sndBird, transform.position);
score -= 1000;
// 참새 추락 처리
coll.transform.SendMessage("DropBird", SendMessageOptions.DontRequireReceiver);
break;
}
}
7.25 득점 및 게임 오버 표시
void OnGUI() {
GUI.skin = skin;
string tScore = "<size='28'><color='navy'>Score : ##</color></size>";
string tHeight = "<size='28'><color='navy'>Height : ##</color></size>";
string tGift = "<size='28'><color='navy'>Gift : ##</color></size>";
tScore = tScore.Replace("##", "" + (int)score);
tHeight = tHeight.Replace("##", "" + (int)maxY);
tGift = tGift.Replace("##", "" + giftCnt);
int w = Screen.width / 2;
int h = Screen.height / 2;
GUI.Label(new Rect(20, 30, 200, 80), tScore);
GUI.Label(new Rect(w - 50, 30, 150, 80), tHeight);
GUI.Label(new Rect(w * 1.5f, 30, 120, 80), tGift);
if (!isDead) return;
7.25 득점 및 게임 오버 표시
Screen.showCursor = true;
// 커서 보이기
// 배경 음악 바꾸기
if (audio.clip != sndOver) {
audio.clip = sndOver;
audio.loop = false;
audio.Play();
}
if (GUI.Button(new Rect(w - 70, h - 50, 140, 60), "Play Game")) {
Application.LoadLevel("MainGame");
}
if (GUI.Button(new Rect(w - 70, h + 50, 140, 60), "Quit Game")) {
Application.Quit();
}
}
7.26 모바일 기기의 중력가속도 센서
7.26 모바일 기기의 중력가속도 센서