Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
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
Archives
Today
Total
관리 메뉴

인텔리킴의 Unity Studying & Game Analysis

29. 유니티 2D 종스크롤 슈팅 - 아이템, 필살기 구현 본문

게임 개발 일지/유니티 엔진 공부

29. 유니티 2D 종스크롤 슈팅 - 아이템, 필살기 구현

인텔리킴 2024. 5. 31. 20:46

준비

아이템 배치

먼저 아이템 애니메이션 및 스크립트 작성

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Item : MonoBehaviour
{
    public string type;
    Rigidbody2D rigid;
    void Start()
    {
        rigid = GetComponent<Rigidbody2D>();
        rigid.velocity = Vector2.down * 3;
    }
}

 

아이템 스크립트에는 type 변수와 아이템 속도만 지정

 

else if (collision.gameObject.tag == "Item")
{
    Item item = collision.gameObject.GetComponent<Item>();
    switch (item.type)
    {
        case "Coin":
            score += 200;
            break;
        case "Power":
            if (maxPower == power)
            {
                score += 400;
            }
            else
                power++;
            break;
        case "Boom":

            break;
    }
}

 

스위치문을 이용해 특정 아이템 먹었을때 케이스 작성

필살기 구현

폭발 이펙트 구현

폭발 오브젝트 및 폭발 애니메이션 구현

 

case "Boom":
    //이펙트 보여주기
    boomEffect.SetActive(true);
    Invoke("OffBoomEffect", 2f);
    //적 모두 처리
    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
    for(int i=0; i < enemies.Length; i++)
    {
        Enemy enemyLogic = enemies[i].GetComponent<Enemy>();
        enemyLogic.onHit(30);
    }
    //적 총알 모두 처리
    GameObject[] bullets = GameObject.FindGameObjectsWithTag("EnemyBullet");
    for (int i = 0; i < bullets.Length; i++)
    {
        Destroy(bullets[i]);
    }
    break;

* FindGameObjectsWithTag : 태그로 장면의 모든 오브젝트를 추출 (s가 붙으면 다중 없으면 한개)

폭탄이 터질때 적 모두 처리하고 적 총알도 모두 처리 함

 

하지만 이방법을 사용하면 폭탄을 저장했다 사용할 수 없고 폭탄 아이템을 먹었을때만 폭탄이 사용됨

 

Input을 이용한 폭탄 함수로 분리

void Boom()
{
    if (!Input.GetButton("Fire2"))
        return;
    if (isBoomTime)
        return;
    if (bomb == 0)
        return;
    bomb--;
    isBoomTime = true;

    //이펙트 보여주기
    boomEffect.SetActive(true);
    Invoke("OffBoomEffect", 2f);
    //적 모두 처리
    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
    for (int i = 0; i < enemies.Length; i++)
    {
        Enemy enemyLogic = enemies[i].GetComponent<Enemy>();
        enemyLogic.onHit(30);
    }
    //적 총알 모두 처리
    GameObject[] bullets = GameObject.FindGameObjectsWithTag("EnemyBullet");
    for (int i = 0; i < bullets.Length; i++)
    {
        Destroy(bullets[i]);
    }
}

만약 폭탄 쏜 시간이 아니고 폭탄 버튼을 눌렀고 폭탄 갯수가 0개가 아니라면 폭탄 사용가능

Update문에 위 함수 불러와서 발동

 

else if (collision.gameObject.tag == "Item")
{
    Item item = collision.gameObject.GetComponent<Item>();
    switch (item.type)
    {
        case "Coin":
            score += 200;
            break;
        case "Power":
            if (maxPower == power)
            {
                score += 400;
            }
            else
                power++;
            break;
        case "Boom":
            if (maxBomb == bomb)
            {
                score += 800;
            }
            else
                bomb++;
            break;
    }
    Destroy(collision.gameObject);

아이템 획득했을 때의 함수도 똑같이 설정

 

필살기 UI도 제작

폭탄 UI 제작

public void UpdateBombIcon(int life)
{
    // UI Bomb Init Disable
    for (int index = 0; index < 3; index++)
    {
        bombImage[index].color = new Color(1, 1, 1, 0);
    }
    // UI Bomb Init Active
    for (int index = 0; index < life; index++)
    {
        bombImage[index].color = new Color(1, 1, 1, 1);
    }
}

 

UpdateLifeIcon 함수를 토대로 UpdateBombIcon 함수 제작

아이템 먹을 때와 사용했을때 Bomb아이콘 업데이트 되게 함

 

폭발 UI 적용 완료

 

아이템 드랍

if (health <= 0) {
    Player playerLogic = player.GetComponent<Player>();
    playerLogic.score += enemyScore;

    //아이템 랜덤드랍
    int ran = Random.Range(0, 10);
    if (ran < 5)
        Debug.Log("아이템 없음");
    else if (ran < 8)
    {
        Instantiate(item[0], transform.position, item[0].transform.rotation);
    }
    else if (ran < 9)
    {
        Instantiate(item[1], transform.position, item[1].transform.rotation);
    }
    else if (ran < 10)
    {
        Instantiate(item[2], transform.position, item[2].transform.rotation);
    }
    Destroy(gameObject);
}

Enemy 스크립트에 아이템 목록 배열을 제작한 후 랜덤 변수를 이용해서 아이템 생성

아이템 생성은 Instantiate 함수 이용

 

적을 죽이면 아이템 떨어짐

예외처리

가끔 onHit함수가 한번에 두번 처리되면 아이템이 두개씩 나옴

 

public void onHit(int dmg)
{
    //예외처리
    if (health <= 0)
        return;
    health -= dmg;
    //평소 스프라이트는 0, 피격시 스프라이트는 1
    spriteRenderer.sprite = sprites[1];
    //데미지 들어오고 일정 시간 후 원래대로 스프라이트 돌아오게 함
    Invoke("ReturnSprite", 0.1f);
    if (health <= 0) {
        Player playerLogic = player.GetComponent<Player>();
        playerLogic.score += enemyScore;

        //아이템 랜덤드랍
        int ran = Random.Range(0, 10);
        if (ran < 5)
            Debug.Log("아이템 없음");
        else if (ran < 8)
        {
            Instantiate(item[0], transform.position, item[0].transform.rotation);
        }
        else if (ran < 9)
        {
            Instantiate(item[1], transform.position, item[1].transform.rotation);
        }
        else if (ran < 10)
        {
            Instantiate(item[2], transform.position, item[2].transform.rotation);
        }
        Destroy(gameObject);
    }
}

함수 맨 앞에 체력 0 이하면 리턴하는 함수 추가해서 리턴

 

기능 구현