Carrot
본문 바로가기
Unity/멋쟁이사자처럼 부트캠프

[멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(42일차) - 2D 슈팅 게임 (1)

by 독기품은토끼 2025. 7. 16.
✅ 오늘의 학습 목표
1. 유니티 교재 - 2D 슈팅 게임 만들기


[사용한 Asset]

 

Awesome Cartoon Airplanes | 3D 항공 | Unity Asset Store

Elevate your workflow with the Awesome Cartoon Airplanes asset from Richard Lester. Find this & other 항공 options on the Unity Asset Store.

assetstore.unity.com

 

Rockets, Missiles & Bombs - Cartoon Low Poly Pack | 3D 무기 | Unity Asset Store

Elevate your workflow with the Rockets, Missiles & Bombs - Cartoon Low Poly Pack asset from BenjaTheMaker. Find this & other 무기 options on the Unity Asset Store.

assetstore.unity.com

 

Cartoon FX Remaster Free | 시각 효과 파티클 | Unity Asset Store

Add depth to your next project with Cartoon FX Remaster Free from Jean Moreno. Find this & more 시각 효과 파티클 on the Unity Asset Store.

assetstore.unity.com

 

Space Star Field Backgrounds | 2D 텍스처 및 소재 | Unity Asset Store

Elevate your workflow with the Space Star Field Backgrounds asset from Dilapidated Meow. Find this & more 텍스처 및 소재 on the Unity Asset Store.

assetstore.unity.com

 

1. 플레이어

using UnityEngine;

public class PlayerMove : MonoBehaviour
{
   public float speed = 5;

   void Update()
   {
      float h = Input.GetAxis("Horizontal");
      float v = Input.GetAxis("Vertical");
      Vector3 dir =  new Vector3(h, v, 0);

      transform.position += dir * speed * Time.deltaTime;
   }
}

 

 

2. 총알

1. 총알 이동

using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float speed = 5;

    void Update()
    {
        Vector3 dir = Vector3.up;
        
        transform.position += dir * speed * Time.deltaTime;
    }
}

 

2. 총알 발사

using UnityEngine;

public class PlayerFire : MonoBehaviour
{
    public GameObject bulletFactory;
    public GameObject firePosition;

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            GameObject bullet = Instantiate(bulletFactory);
            bullet.transform.position = firePosition.transform.position; // 위치 초기화
        }
    }
}

 

GetButtonDown 함수의 인자값인 "Fire1"은  사용자 입력처리인 Input Mnager에 등록되어 있다.

마우스 왼 클릭을 하면 총알이 발사되는 구조이다.

 

3. 적

1. 적 이동 & 충돌

using System;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    private Vector3 dir;
    public float speed = 5;

    public GameObject explosionFactory;
    
    void Start()
    {
        int ranValue = UnityEngine.Random.Range(0, 10);

        if (ranValue < 3) // 30%
        {
            GameObject target = GameObject.Find("Player");
            dir = target.transform.position - transform.position; // 플레이어를 바라보는 방향 값
            dir.Normalize();
        }
        else // 70%
        {
            dir = Vector3.down;
        }
    }

    void Update()
    {
        transform.position += dir * speed * Time.deltaTime;
    }
    
    private void OnCollisionEnter(Collision other)
    {
        //// 점수 증가
        GameObject smObject = GameObject.Find("ScoreManager");
        ScoreManager sm = smObject.GetComponent<ScoreManager>();

        // sm.SetScore(sm.GetScore() + 1); // 책에 적힌 거
        var score = sm.GetScore() + 1;
        sm.SetScore(score);

        // 파티클 생성
        GameObject explosion = Instantiate(explosionFactory);
        explosion.transform.position = transform.position;
        
        // 파괴 기능
        Destroy(other.gameObject);
        Destroy(gameObject);
    }
}

 

2. 적 자동 생성

using UnityEngine;

public class EnemyManager : MonoBehaviour
{
    private float currentTime; // 타이머

    private float minTime = 1;
    private float maxTime = 5;
    
    public float createTime = 1f; // 생성 주기

    public GameObject enemyFactory;

    void Start()
    {
        createTime = Random.Range(minTime, maxTime);
    }

    void Update()
    {
        currentTime += Time.deltaTime;

        if (currentTime > createTime) // 타이머가 생성 주기를 넘었다면
        {
            // 생성
            GameObject enemy = Instantiate(enemyFactory);
            enemy.transform.position = transform.position;
            
            // 타이머 초기화
            currentTime = 0f;
        }
    }
}

 

3. Destroy Zone

화면을 벗어나는 물체(총알, 적)를 제거해 메모리 낭비를 막아주려고 한다.

 

우선 일정 거리를 지나치면 자동으로 제거되도록 하기 위해 화면 바깥쪽에 보이지 않는 벽 오브젝트(Trigger)를 배치했고, 총알이나 적이 이 벽과 충돌하면 해당 오브젝트를 제거하도록 했다.

그런데 벽끼리도 충돌을 감지해서 서로 제거되는 문제가 있어서, Physics Settings > Layer Collision Matrix에서 벽(Layer)끼리의 충돌 체크를 해제해 불필요한 충돌이 발생하지 않도록 설정했다.

using UnityEngine;

public class DestroyZone : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        Destroy(other.gameObject);
    }
}

 

 

4. 배경 & UI

1. 무한 배경 맵

using UnityEngine;

public class Background : MonoBehaviour
{
    public Material bgMaterial;

    public float scrollSpeed = 0.2f;

    void Update()
    {
        Vector2 direction = Vector2.up;

        bgMaterial.mainTextureOffset += direction * scrollSpeed * Time.deltaTime;
    }
}

 

배경에 스크롤 기능을 추가해서 이동하는 시각 효과를 주었고

배경음악도 같이 넣어주었다.

 

2. Score UI

using TMPro;
using UnityEngine;

public class ScoreManager : MonoBehaviour
{
    public TextMeshProUGUI currentScoreUI;
    public TextMeshProUGUI bestScoreUI;

    private int currentScore;
    private int bestScore;

    void Start()
    {
        bestScore = PlayerPrefs.GetInt("BestScore", 0);

        bestScoreUI.text = "최고 점수 : " + bestScore;
    }

    public void SetScore(int value)
    {
        currentScore = value;

        currentScoreUI.text = "현재 점수 : " + currentScore;

        if (currentScore > bestScore)
        {
            bestScore = currentScore;
            bestScoreUI.text = "최고 점수 : " + bestScore;

            PlayerPrefs.SetInt("BestScore", bestScore);
        }
    }

    public int GetScore()
    {
        return currentScore;
    }
}