공식 예제 중 Space Shooter를 만들어보았다.
사이트 → https://unity3d.com/kr/learn/tutorials/s/space-shooter-tutorial
2D 슈팅게임이지만 완전 2D로 만든건 아니고 3D방식으로 제작하더라.
에셋스토어로 들어가서 Space Shooter Tutorial을 다운로드받고 순서따라 영상보면서 만들면 된다.
PlayerController 스크립트 -> 플레이어에서 플레이어의 이동, 탄발사를 관리
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] // 게임화면 경계선을 지정 public class Boundary { public float xMin, xMax, zMin, zMax; } // 플레이어의 동작을 관리하는 스크립트 public class PlayerController : MonoBehaviour { // 속도와 회전수치를 받음 public float speed; public float tilt; public Boundary boundary; // 탄과 탄 발사위치를 받음 public GameObject shot; public Transform shotSpawn; // 탄 발사주기 조정 public float fireRate; private float nextFire; // Use this for initialization void Start () { } // Update is called once per frame void Update () { // Input.GetAxis를 이용하면 좌우나 상하 이동시 0~1값을 리턴해준다. float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = Input.GetAxis("Vertical"); // 수치만큼 벡터를 생성해서 그만큼의 속도(벡터)를 줌. Vector3 movemont = new Vector3(moveHorizontal, 0.0f, moveVertical); this.GetComponent<Rigidbody>().velocity = movemont * speed; // position의 x값과 z값이 min~max를 넘어가면 Mathf.Clamp 함수를 이용해서 안으로 넣어줌 this.GetComponent<Rigidbody>().position = new Vector3 ( Mathf.Clamp(this.GetComponent<Rigidbody>().position.x, boundary.xMin, boundary.xMax), 0.0f, Mathf.Clamp(this.GetComponent<Rigidbody>().position.z, boundary.zMin, boundary.zMax) ); // 플레이어를 회전 this.GetComponent<Rigidbody>().rotation = Quaternion.Euler(0.0f, 0.0f, this.GetComponent<Rigidbody>().velocity.x * -tilt); // 스페이스바를 누르고 있을때. 현재시간이 다음발사시간을 넘어서면 탄이 발사됨 if (Input.GetKey(KeyCode.Space) && Time.time > nextFire) { // 발사 후 다음 발사시간을 조정 nextFire = Time.time + fireRate; // 발사위치에서 탄을 Instantiate(shot, shotSpawn.position, shotSpawn.rotation); } } } | cs |
Mover 스크립트 -> 탄에 적용되어서 탄이 생성되면 알아서 앞으로 나가게한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mover : MonoBehaviour { public float speed; // Use this for initialization void Start () { // 발사된 탄은 스스로 this.GetComponent<Rigidbody>().velocity = transform.forward * speed; } // Update is called once per frame void Update () { } } | cs |
DestroyByBoundary -> 빈 오브젝트를 화면 경계선 크기만큼 설정한 후 Collider를 넣어서
탄이 이 경계선에서 나가면 죽게 만듬.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByBoundary : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } private void OnTriggerExit(Collider other) { Destroy(other.gameObject); } } | cs |
DestroyByTime -> 생성한 후 시간이 지나면 알아서 삭제되도록 함. 이펙트에 넣어서 이펙트가 끝나면 죽도록
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyByTime : MonoBehaviour { public float lifetime; // Use this for initialization void Start () { // 생성후 lifetime 후에 알아서 Destroy(gameObject, lifetime); } // Update is called once per frame void Update () { } } | cs |
DestroyByContact -> 행성(장애물)에 들어가는 스크립트로 다른 무언가와 충돌하면 반응하고 삭제하게 만듬
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | using System.Collections; using System.Collections.Generic; using UnityEngine; // 행성에 들어감 public class DestroyByContact : MonoBehaviour { public GameObject explosion; public GameObject playerexplosion; public int scoreValue; private GameController gamecontroller; // Use this for initialization void Start () { // 게임컨트롤러를 찾아줌 GameObject gameControllerObject = GameObject.FindWithTag("GameController"); if(gameControllerObject != null) { gamecontroller = gameControllerObject.GetComponent<GameController>(); } } // Update is called once per frame void Update () { } private void OnTriggerEnter(Collider other) { // Boundary 오브젝트와 충돌하면 아무것도 아님 if (other.tag == "Boundary") { return; } // 다른것과 충돌하면 현재위치에 폭발 이펙트를 생성 Instantiate(explosion, transform.position, transform.rotation); // 캐릭터와 충돌하면 if (other.tag == "Player") { // 캐릭터폭발 이펙트 생성하고, 컨트롤러에서 게임오버함수 실행 Instantiate(playerexplosion, other.transform.position, other.transform.rotation); gamecontroller.GameOver(); } // 컨트롤러에서 점수를 올려주고 gamecontroller.AddScore(scoreValue); // 자기 자신(행성)과 충돌한 적(탄 or 캐릭터)을 둘다 삭제 Destroy(other.gameObject); Destroy(gameObject); } } | cs |
GameController -> 게임 컨트롤러에 들어가 점수, 게임오버, UI등을 관리
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class GameController : MonoBehaviour { public GameObject hazard; public Vector3 spawnValue; public int hazardCount; public float spawnWait; public float startWait; public float waveWait; public Text scoreText; public Text restartText; public Text gameOverText; private bool gameOver; private bool restart; private int score; // 코루틴으로 적 생성 IEnumerator SpawnWaves() { yield return new WaitForSeconds(startWait); while (true) { for (int i = 0; i < hazardCount; i++) { Vector3 spawnPosition = new Vector3(Random.Range(-spawnValue.x, spawnValue.x), spawnValue.y, spawnValue.z); Quaternion spawnRotation = Quaternion.identity; Instantiate(hazard, spawnPosition, spawnRotation); // spawnWait마다 주기적으로 적생성 yield return new WaitForSeconds(spawnWait); } // 한 웨이브가 끝나면 waveWait 후에 적을 생성 yield return new WaitForSeconds(waveWait); // gameover 변수가 true가되면 재시작 text를 출력 if(gameOver) { restartText.text = "Press 'R' for Restart"; restart = true; break; } } } // 스코어를 출력하는 함수 void UpdateScore() { scoreText.text = "score: " + score; } // 스코어를 증가시키는 함수 public void AddScore(int newScoreValue) { score += newScoreValue; UpdateScore(); } // 게임오버시 게임오버를 출력하고 변수를 true로 활성화 public void GameOver() { gameOverText.text = "Game Over!"; gameOver = true; } // Use this for initialization void Start () { // 기본 변수 및 텍스트 초기화 gameOver = false; restart = false; gameOverText.text = ""; restartText.text = ""; // 초기점수 세팅 및 출력 score = 0; UpdateScore(); // 코루틴 시작하여 적 생성 StartCoroutine(SpawnWaves()); } // Update is called once per frame void Update () { // restart가 true가 됐을시 R키를 누르면 main씬을 새로 Load해줌. if(restart) { if(Input.GetKeyDown (KeyCode.R)) { //Application.LoadLevel(Application.loadedLevel); SceneManager.LoadScene("Main", LoadSceneMode.Single); } } } } | cs |
실행화면
만든 게임은 분할압축하여 업로드하였다.
예제랑 똑같은데 더 허접한 듯
'프로그래밍 공부 > Unity 프로젝트' 카테고리의 다른 글
2D 슈팅게임 (0) | 2018.04.11 |
---|---|
캔버스를 이용한 2D 슈팅게임 (미완성) (0) | 2018.04.11 |
유니티 입문에 도움되는 사이트 (0) | 2018.03.21 |
벽돌깨기 게임 (0) | 2018.03.19 |
유니티 기초 - 4 에셋스토어 이용하기 (0) | 2018.03.19 |