Unity/유니티 기본

[4.9] 닷지 게임

ljw4104 2021. 4. 9. 14:19

 

  • 탄을 하나 맞을때마다 유저의 체력 -3이 되고 탄은 사라짐.
  • 탄이 유저에게 맞지않아 사라지지 않은 상태에서 벽을 맞으면 스코어가 +1이 되고 사라짐.
  • 30초 간격으로 5초동안 패턴이 어렵게 바뀜.
  • 여러대를 맞아도 피격 애니메이션은 한번만 출력됨.
  • 피격중에는 움직일 수 없음.

 

InGame.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class InGame : MonoBehaviour
{
    public System.Action OnHit;
    public System.Action OnScoreUp;

    private UIManager ui;
    private PlayerController player;
    private BulletSpawner[] bulletSpawner;
    private float time = 0;
    private float hardTime = 0;
    private int score = 0;
    private bool isHardTime;
    // Start is called before the first frame update
    void Start()
    {
        this.ui = FindObjectOfType<UIManager>();
        this.player = FindObjectOfType<PlayerController>();
        this.bulletSpawner = FindObjectsOfType<BulletSpawner>();

        this.OnHit = this.HitPlayer;
        this.OnScoreUp = this.UpdateScore;
        this.ui.restart.gameObject.SetActive(false);
        this.ui.restart.onClick.AddListener(() =>
        {
            SceneManager.LoadScene(0);
        });
    }

    // Update is called once per frame
    void Update()
    {
        if (this.player.isDie)
        {
            this.ui.restart.gameObject.SetActive(true);
        }
        else
        {
            this.time += Time.deltaTime;
            this.ui.timeLabel.text = "TIME : " + (int)this.time + "sec";
        }
        
        if((int)time != 0 && (int)time % 30 == 0)
        {
            isHardTime = true;
        }

        if (isHardTime)
        {
            hardTime += Time.deltaTime;
            if (hardTime < 5)
            {
                this.bulletSpawner[0].OnHard(0.1f, 0.3f);
                this.bulletSpawner[1].OnHard(0.1f, 0.3f);
                this.ui.timeLabel.color = Color.red;
            }
            else
            {
                isHardTime = false;
            }
        }
        else
        {
            hardTime = 0;
            this.bulletSpawner[0].OnHard(0.5f, 3);
            this.bulletSpawner[1].OnHard(0.5f, 3);
            this.ui.timeLabel.color = Color.white;
        }
    }

    public void HitPlayer()
    {
        if(player.Hp > 0)
        {
            this.player.isHit = true;
            this.player.PlayAnimation("damage");
            this.player.Hp -= 3; 
            this.ui.hpBar.fillAmount -= 0.03f;
            this.ui.hpLabel.text = "LEFT HP : " + player.Hp;
        }

        if(this.player.Hp < 0)
        {
            this.player.Hp = 0;
            this.ui.hpBar.fillAmount = 0;
            this.ui.hpLabel.text = "LEFT HP : " + player.Hp;
            this.player.Die();
        }
    }

    public void UpdateScore()
    {
        this.score++;
        this.ui.scoreLabel.text = "SCORE : " + this.score;
    }
}

 

 

UIManager.cs

using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public Button restart;
    public Image hpBar;
    public Text hpLabel;
    public Text scoreLabel;
    public Text timeLabel;
}

 

 

BulletSpawner.cs

using UnityEngine;

public class BulletSpawner : MonoBehaviour
{
    public GameObject bulletPrefab;
    public float spawnRateMin = 0.5f;
    public float spawnRateMax = 3;
    public System.Action<float, float> OnHard;

    private Transform target;
    private float spawnRate;
    private float timeAfterSpawn;
    private PlayerController player;
    // Start is called before the first frame update
    void Start()
    {
        this.timeAfterSpawn = 0;
        this.spawnRate = Random.Range(this.spawnRateMin, this.spawnRateMax);
        this.target = FindObjectOfType<PlayerController>().transform;
        this.player = FindObjectOfType<PlayerController>();
        this.OnHard = UpdateSpawnTime;
    }

    // Update is called once per frame
    void Update()
    {
        if (!player.isDie)
        {
            this.timeAfterSpawn += Time.deltaTime;
            if (this.timeAfterSpawn > this.spawnRate)
            {
                this.timeAfterSpawn = 0;
                var bullet = Instantiate(bulletPrefab, this.transform.position, this.transform.rotation);
                bullet.transform.LookAt(target);
                this.spawnRate = Random.Range(this.spawnRateMin, this.spawnRateMax);
            }
        }
    }

    public void UpdateSpawnTime(float min, float max)
    {
        this.spawnRateMin = min;
        this.spawnRateMax = max;
    }
}

 

 

Bullet.cs

using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float speed = 15f;
    
    private InGame inGame;
    private Rigidbody bulletRigidbody;
    // Start is called before the first frame update
    void Start()
    {
        this.bulletRigidbody = GetComponent<Rigidbody>();
        this.bulletRigidbody.velocity = this.transform.forward * speed;
        this.inGame = FindObjectOfType<InGame>();

        Destroy(this.gameObject, 3f);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.CompareTag("Player"))
        {
            this.inGame.OnHit();
            Destroy(this.gameObject);
        }
        else if (other.CompareTag("Wall"))
        {
            this.inGame.OnScoreUp();
            Destroy(this.gameObject);
        }
    }
}

 

 

PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed = 8f;
    public Rigidbody playerRigidbody;
    public bool isDie;
    public bool isHit;

    private Animation anim;
    private float timer = 0;
    [SerializeField]
    public int Hp
    {
        get; set;
    }
    public int MaxHp
    {
        get; private set;
    }
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animation>();
        this.Hp = this.MaxHp = 100;
    }

    // Update is called once per frame
    void Update()
    {
        float x = 0;
        float z = 0;
        if (!this.isDie)
        {
            if (!isHit)
            {
                x = Input.GetAxis("Horizontal");
                z = Input.GetAxis("Vertical");

                float translation = z * this.speed * Time.deltaTime;
                float rotation = x * 6f;

                this.transform.Translate(0, 0, translation);
                this.transform.Rotate(0, rotation, 0);
            }

            if (!isHit && (x != 0 || z != 0))
            {
                PlayAnimation("run@loop");
            }
            else if (isHit)
            {
                timer += Time.deltaTime;
                PlayAnimation("damage");
                if(timer > 0.25f)
                {
                    isHit = false;
                    timer = 0;
                }
            }
            else
            {
                PlayAnimation("idle@loop");
            }
        }
    }

    public void Die()
    {
        this.isDie = true;
        PlayAnimation("die");
    }

    public void PlayAnimation(string message)
    {
        this.anim.Play(message);
    }
}