1. Bad, Good Object ๋ง๋ค๊ธฐ
ํด๋ฆญ์ ๊ฐ ์ค๋ธ์ ํธ๋ง๋ค ์ด๋ฒคํธ๋ฅผ ์คํํ๊ธฐ ์ํด Collider๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ , ์๋ก ์ฌ๋ผ๊ฐ๋ค๊ฐ ๋จ์ด์ง๋ ํจ๊ณผ๋ฅผ ์ํด Rigidbody๋ฅผ ์ถ๊ฐํด์ค๋ค.
2. ๊ฐ์ฒด๋ฅผ ๋ฌด์์๋ก ๊ณต์ค์ ๋์ง๊ธฐ
public class Target : MonoBehaviour{
private Rigidbody targetRb;
private float minSpeed = 12;
private float maxSpeed = 16;
private float maxTorgue = 10;
private float xRange = 4;
private float ySpawnPos = -3;
void Start() {
targetRb = GetComponent<Rigidbody>();
targetRb.AddForce(RangeForce(), ForceMode.Impulse);
targetRb.AddTorque(RandomTorgue(), RandomTorgue(), RandomTorgue(), ForceMode.Impulse);
transform.position = RandomSpawnPos();
}
private Vector3 RangeForce() {
return Vector3.up * Random.Range(minSpeed, maxSpeed);
}
private float RandomTorgue() {
return Random.Range(-maxTorgue, maxTorgue);
}
private Vector3 RandomSpawnPos() {
return new Vector3(Random.Range(-xRange, xRange), ySpawnPos);
}
}
๊ฐ์ฒด ํ์ ์ ์ํ rigidbody.AddTorgue(Vector vector, ForceMode mode = ForceMode.Force) ํจ์๋ฅผ ์ด์ฉํ๋ค.
์ด ๋, AddTorgue ์ธ์์ vector๋ ํ์ ๋ฐฉํฅ์ ์๋ฏธํ๋ค.
3. ๊ฒ์ ๋งค๋์ ์ ์ค๋ธ์ ํธ ์์ฑ์ ์ํ ์ฝ๋ฃจํด ๋ง๋ค๊ธฐ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
[SerializeField] private List<GameObject> targets;
private float spawnRate = 1.0f;
void Start() {
StartCoroutine(SpawnTarget());
}
IEnumerator SpawnTarget() {
while (true) {
yield return new WaitForSeconds(spawnRate);
int index = Random.Range(0, targets.Count);
Instantiate(targets[index]);
}
}
}
Hierarchy์ GameManager ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ค๊ณ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฐ๊ฒฐํด์ค ํ targets ๋ฆฌ์คํธ์ target ๊ฐ์ฒด๋ค์ ์ฐ๊ฒฐํด์ฃผ๋ฉด ์๋์ผ๋ก 1์ด๋น ์์ฑ๋์ด ํ์ด์ค๋ฅด๋ target ๊ฐ์ฒด๋ค์ ํ์ธํ ์ ์๋ค.
4. ํด๋ฆญ ์, Sensor ํต๊ณผ์ ๊ฐ์ฒด ํ๊ดดํ๊ธฐ
//๋ง์ฐ์ค ์ด๋ฒคํธ
private void OnMouseDown() {
Destroy(gameObject);
}
Target ์คํฌ๋ฆฝํธ์ OnMouseDown() ํจ์๋ฅผ ์ถ๊ฐํด์ค๋ค. ์ฆ, target ๊ฐ์ฒด์ ๋ง์ฐ์ค ํด๋ฆญ ์ด๋ฒคํธ ๋ฐ์์ ๊ฐ์ฒด๋ ์ญ์ ๋๋ค.
OnMouseDown() ํจ์๋ Unity์์ ์ ๊ณตํ๋ ์์ฒด ํจ์๋ก Mouse ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ์ง์ ๋ฐ์์ ์ํํ๋ค.
//ํธ๋ฆฌ๊ฑฐ ์ด๋ฒคํธ
private void OnTriggerEnter(Collider other) {
Destroy(gameObject);
}
๋ํ Prototype5 ์ฌ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ธ์๋ Sensor์ Box Collider ๊ฐ ๋ฌ๋ ค์์ผ๋ฏ๋ก Collider ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ด์ฉํด์ ์ด๊ณณ์ ์ง๋๋ ๊ฐ์ฒด๋ฅผ ์ญ์ ํ์.
5. ๊ฐ์ฒด ํด๋ฆญ์ ์ ์ ์ถ๊ฐ
//Target.cs
private float ySpawnPos = -3;
//๋ง์ฐ์ค ์ด๋ฒคํธ
private void OnMouseDown() {
Destroy(gameObject);
GameManager.gameManger.UpdateScore(pointValue);
}
๊ฐ Target ๊ฐ์ฒด๋ง๋ค ์ ์ ๋ณ์๋ฅผ ๋ง๋ค์ด์ Prefab ์์์ ์ถ๊ฐํด์ค๋ค.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class GameManager : MonoBehaviour
{
[SerializeField] private List<GameObject> targets;
[SerializeField] private TextMeshProUGUI scoreText;
private float spawnRate = 1.0f;
private int gameScore = 0;
public static GameManager gameManger;
void Awake() {
if (gameManger == null) gameManger = this;
}
void Start() {
StartCoroutine(SpawnTarget());
UpdateScore(0);
}
IEnumerator SpawnTarget() {
while (true) {
yield return new WaitForSeconds(spawnRate);
int index = Random.Range(0, targets.Count);
Instantiate(targets[index]);
}
}
public void UpdateScore(int scoreToAdd) {
gameScore += scoreToAdd;
scoreText.text = "Score: "+ gameScore.ToString();
}
}
GameManager ํด๋์ค๋ฅผ ์ฑ๊ธํค ํจํด์ผ๋ก ๋ง๋ค์ด์ฃผ๊ณ UpdateScore(int scoreToAdd) ํจ์๋ฅผ ํตํด ์ ์๋ฅผ ์ ๋ฐ์ดํธ ํด์ค๋ค.
6. ํด๋ฆญ์ ํฐ์ง๋ Particle ์ถ๊ฐ
[SerializeField] private ParticleSystem explosionParticle;
//๋ง์ฐ์ค ์ด๋ฒคํธ
private void OnMouseDown() {
Destroy(gameObject);
GameManager.gameManger.UpdateScore(pointValue);
Instantiate(explosionParticle, transform.position, explosionParticle.transform.rotation);
}
Target ๊ฐ์ฒด์ ParticleSystem ๋ณ์๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ Particle ์ ์ฐ๊ฒฐํด์ค๋ค.
๊ฐ์ฒด์ ํด๋ฆญ์ด ๋ฐ์ํ์ ๋, particle์ ํด๋น ์์น์ ์์ฑํด์ค๋ค.
7. GameOver, Restart ๊ธฐ๋ฅ ์ถ๊ฐ
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
[SerializeField] private List<GameObject> targets;
[SerializeField] private TextMeshProUGUI scoreText;
[SerializeField] private GameObject gameOverWindow;
private float spawnRate = 1.0f;
private int gameScore = 0;
public static GameManager gameManger;
void Awake() {
if (gameManger == null) gameManger = this;
}
void Start() {
Time.timeScale = 1;
StartCoroutine(SpawnTarget());
UpdateScore(0);
}
IEnumerator SpawnTarget() {
while (true) {
yield return new WaitForSeconds(spawnRate);
int index = Random.Range(0, targets.Count);
Instantiate(targets[index]);
}
}
public void UpdateScore(int scoreToAdd) {
gameScore += scoreToAdd;
scoreText.text = "Score: "+ gameScore.ToString();
if (gameScore < 0){
gameOverWindow.SetActive(true);
Time.timeScale = 0;
}
}
public void RestartGame() {
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
๋๋ gameScore ๊ฐ ์์๊ฐ์ด ๋์์ ๋, TimeScale์ 0์ผ๋ก ๋ง๋ค๋ฉด์ GameOver ๋๋๋ก ๊ตฌํํ๋ค.
Restart ๋ฒํผ์ ํด๋ฆญํ๋ฉด RstartGame() ํจ์๊ฐ ํธ์ถ๋๋๋ก ์ฐ๊ฒฐํ์์ผ๋ฉฐ, SceneManger.LoadScene(SceneManger.GetActiveScene().name) ํจ์๋ก ํ์ฌ ํ์ฑํ ๋์ด ์๋ ์ฌ์ ์ฌ๋ก๋ํ ์ ์๋ค.