- Life는 Image배열, 점수는 Text로 표현한다.
- UI가 해상도에 맞지 않을 때
- Canvas에 Canvas Scaler에서 Constant Pixel Size(픽셀 고정)으로 되어 있는걸, Scale With Screen Size로 바꿔준다.
- 죽었을 때 game over를 나타내는 Text와 , 재시작 Button을 추가
- 2개는 빈오브젝트를 생성해서 묶어준다.
- 크기를 알맞게 맞춰줘서 그림과 같이 배치했다.
- Enemy에 enemyScore변수를 추가하고, 파괴 됐을 때 player의 score점수를 올려준다.
if (health <= 0) { Player playerLogic = player.GetComponent<Player>(); playerLogic.score += enemyScore; Destroy(gameObject); }
- GameManager의 Update문에서 ScoreText를 업데이트해준다.
- 세자리마다 쉼표로 나눠주기 위해 string.Format("{0:n0}")을 사용.
// UI Score Update Player playerLogic = player.GetComponent<Player>(); scoreText.text = string.Format("{0:n0}", playerLogic.score);
- 적에게 맞았을 때 , Image를 투명상태로 만들어 남아있는 Life만 보이게 한다.
- GameManager에 UpdateLife함수를 추가해서 구현
public void UpdateLife(int Life) { // #. UI Init Disable for (int i = 0; i < 3; i++) lifeImage[i].color = new Color(1, 1, 1, 0); // #. Life Active for (int i = 0; i < Life; i++) lifeImage[i].color = new Color(1, 1, 1, 1); }
GameManager에 GameOver함수를 만들고, Life가 0이되면 GameOver함수를 실행
public void GameOver() { gameOverSet.SetActive(true); }
- OnClick 이벤트에 적용할 함수를 생성
public void Retry() { SceneManager.LoadScene(0); }
- Enemy L의 총알이 2개인데 2개의 총알을 모두 맞고 Life가 2번 깎여나가는 현상 발생
- bool값을 정의해서 이미 맞은 상태면 Life를 깎지 않는다.
if (isHit) return;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public bool isTouchTop;
public bool isTouchBottom;
public bool isTouchLeft;
public bool isTouchRight;
public int score;
public int health;
public float speed;
public float power;
public float curShotDelay;
public float maxShotDelay;
public bool isHit;
public GameManager gameManager;
public GameObject BulletA;
public GameObject BulletB;
Animator anim;
private void Awake()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
Move();
Fire();
Reload();
}
void Reload()
{
curShotDelay += Time.deltaTime;
}
void Fire()
{
if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭
return;
if (curShotDelay < maxShotDelay)
return;
switch(power)
{
case 1:
// Power 1
GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation);
Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
case 2:
// Power 2
GameObject BulletR = Instantiate(BulletA, transform.position + Vector3.right*0.1f, transform.rotation);
GameObject BulletL = Instantiate(BulletA, transform.position + Vector3.left*0.1f, transform.rotation);
Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
case 3:
// Power 3
GameObject BulletRR = Instantiate(BulletA, transform.position + Vector3.right*0.35f, transform.rotation);
GameObject BulletCC = Instantiate(BulletB, transform.position, transform.rotation);
GameObject BulletLL = Instantiate(BulletA, transform.position + Vector3.left*0.35f, transform.rotation);
Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>();
Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>();
rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
}
curShotDelay = 0;
}
void Move()
{
float h = Input.GetAxisRaw("Horizontal");
if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
h = 0;
float v = Input.GetAxisRaw("Vertical");
if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
v = 0;
Vector3 curPos = transform.position;
Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;
transform.position = curPos + nextPos;
// Animation
if (Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal"))
{
anim.SetInteger("Input", (int)h);
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Border")
{
switch(collision.gameObject.name)
{
case "Top":
isTouchTop = true;
break;
case "Bottom":
isTouchBottom = true;
break;
case "Left":
isTouchLeft = true;
break;
case "Right":
isTouchRight = true;
break;
}
}
else if(collision.gameObject.tag == "Enemy" || (collision.gameObject.tag == "EnemyBullet"))
{
if (isHit)
return;
isHit = true;
health--;
gameManager.UpdateLife(health);
if (health == 0)
gameManager.GameOver();
else
gameManager.RespawnPlayer();
gameObject.SetActive(false);
Destroy(collision.gameObject);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "Border")
{
switch (collision.gameObject.name)
{
case "Top":
isTouchTop = false;
break;
case "Bottom":
isTouchBottom = false;
break;
case "Left":
isTouchLeft = false;
break;
case "Right":
isTouchRight = false;
break;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject[] enemyObjs;
public Transform[] spawnPoints;
public GameObject player;
public float maxSpawnDelay;
public float curSpawnDelay;
public Text scoreText;
public Image[] lifeImage;
public GameObject gameOverSet;
void Update()
{
curSpawnDelay += Time.deltaTime;
if(curSpawnDelay > maxSpawnDelay)
{
SpawnEnemy();
maxSpawnDelay = Random.Range(0.5f, 3f);
curSpawnDelay = 0;
}
// UI Score Update
Player playerLogic = player.GetComponent<Player>();
scoreText.text = string.Format("{0:n0}", playerLogic.score);
}
void SpawnEnemy()
{
int randomEnemy = Random.Range(0, 3);
int spawnPoint = Random.Range(0, 7);
GameObject enemy = Instantiate(enemyObjs[randomEnemy], spawnPoints[spawnPoint].position, spawnPoints[spawnPoint].rotation);
Rigidbody2D rigid = enemy.GetComponent<Rigidbody2D>();
Enemy enemyLogic = enemy.GetComponent<Enemy>();
enemyLogic.player = player;
if(spawnPoint == 5) // Left Spawn
{
enemy.transform.Rotate(Vector3.forward * 90);
rigid.velocity = new Vector2(1, -enemyLogic.speed);
}
else if(spawnPoint == 6) // Right Spawn
{
enemy.transform.Rotate(Vector3.back * 90);
rigid.velocity = new Vector2(-1, -enemyLogic.speed);
}
else // Front Spawn
{
rigid.velocity = new Vector2(0, -enemyLogic.speed);
}
}
public void RespawnPlayer()
{
Invoke("RespawnPlayerExe", 2f);
}
public void RespawnPlayerExe()
{
Player playerLogic = player.GetComponent<Player>();
playerLogic.isHit = false;
player.transform.position = Vector3.down * 4f;
player.SetActive(true);
}
public void UpdateLife(int Life)
{
// #. UI Init Disable
for (int i = 0; i < 3; i++)
lifeImage[i].color = new Color(1, 1, 1, 0);
// #. Life Active
for (int i = 0; i < Life; i++)
lifeImage[i].color = new Color(1, 1, 1, 1);
}
public void GameOver()
{
gameOverSet.SetActive(true);
}
public void Retry()
{
SceneManager.LoadScene(0);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public string enemyName;
public float speed;
public int enemyScore;
public int health;
public float curShotDelay;
public float maxShotDelay;
public Sprite[] sprites;
public GameObject BulletA;
public GameObject BulletB;
public GameObject player;
SpriteRenderer spriteRenderer;
void Awake()
{
spriteRenderer = GetComponent<SpriteRenderer>();
}
void Update()
{
Fire();
Reload();
}
void Reload()
{
curShotDelay += Time.deltaTime;
}
void Fire()
{
if (curShotDelay < maxShotDelay)
return;
if(enemyName == "S")
{
GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation);
Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
Vector3 dirVec = player.transform.position - transform.position;
rigid.AddForce(dirVec.normalized * 10, ForceMode2D.Impulse);
}
else if(enemyName == "L")
{
GameObject BulletR = Instantiate(BulletB, transform.position + Vector3.right * 0.3f, transform.rotation);
GameObject BulletL = Instantiate(BulletB, transform.position + Vector3.left * 0.3f, transform.rotation);
Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
Vector3 dirVecR = player.transform.position - (transform.position + Vector3.right * 0.3f);
Vector3 dirVecL = player.transform.position - (transform.position + Vector3.left * 0.3f);
rigidR.AddForce(dirVecR.normalized * 4, ForceMode2D.Impulse);
rigidL.AddForce(dirVecL.normalized * 4, ForceMode2D.Impulse);
}
curShotDelay = 0;
}
void onDamaged(int dmg)
{
health -= dmg;
spriteRenderer.sprite = sprites[1];
Invoke("ReturnSprite", 0.1f);
if (health <= 0)
{
Player playerLogic = player.GetComponent<Player>();
playerLogic.score += enemyScore;
Destroy(gameObject);
}
}
void ReturnSprite()
{
spriteRenderer.sprite = sprites[0];
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "BorderBullet")
Destroy(gameObject);
else if(collision.gameObject.tag == "PlayerBullet")
{
Bullet bullet = collision.gameObject.GetComponent<Bullet>(); // collision.gameObject에서 GetComponent한다
onDamaged(bullet.dmg);
Destroy(collision.gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public int dmg;
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "BorderBullet")
{
Destroy(gameObject);
}
}
}