[Unity][2D-Game] Undead Survivor (12)

suhan0304·2023년 11월 10일
0

유니티 - Undead Survivor

목록 보기
15/21
post-thumbnail

Review

  • 플레이어에 Hand 오브젝트를 만들어 양손을 만들어주었다.
  • 레벨이 1이 되면 양손이 활성화 되도록 만들어주었다.
  • 플레이어으 FlipX 여부에따라 무기 또한 위치와 회전이 재설정되게 조정하였다.

강의영상 (12) - 레벨업 시스템


개발

UI 완성하기

캔버스에 이미지 오브젝트 하나를 만들어준후 화면을 꽉 채우도록 앵커 설정을 해준다.

  • 색을 검정, 투명도 150으로 설정
  • 이름을 LevelUp으로 설정
    - 기존 LevelUp은 ItemGroup으로 변경

해당 LevelUp 오브젝트 안에 자식 오브젝트로 창이 될 이미지 오브젝트를 추가해준다.

  • 스프라이트를 Panel로 설정
  • width / height = 100 / 130
  • 색을 언데드 색으로 수정
  • 이름을 Panel 로 설정


창의 제목이 될 텍스트 오브젝트를 Panel의 자식 오브젝트로 추가

  • 앵커 위쪽 꽉차게 설정
  • Height = 20으로 설정
  • 가운데 정렬, 글꼴 neodgm, 사이즈 8, 흰색으로 설정
  • shadow 컴포넌트 추가 후 0.5 / -0.5로 설정
  • 문구를 아래 사진과 같이 수정
  • Pos Y = -3으로 수정
  • 이름을 Text Title로 수정


이제 ItemGroup을 Panel의 자식으로 설정한 후

  • ItemGroup의 앵커를 상하좌우 꽉 차게 설정
  • Vertical Layout Group 컴포넌트의 Control Child Size의 Width, Height 둘 다 체크
  • 여백을 주기 위해 Spacing을 1로 수정
  • left = right = Bottom = 5 / Top = 25로 수정
  • 자식 오브젝트의 Item3, Item4를 비활성화

Control Child Size : 자식 오브젝트를 자신의 크기에 맞게 자동 변경

  • 아이템 버튼의 이미지와 텍스트를 왼쪽 기준으로 앵커 변경 및 위치 조정
  • 아이템 버튼 이미지의 PosX = 6 , Pos Y = 3
  • 아이템 버튼 텍스트의 PosX = 6 , Pos Y = 10

  • 텍스트를 복사해서 Text Name이라는 이름으로 아이템 이름을 배치
  • 아이템 이름의 글자 크기는 7, 왼쪽 정렬로 설정
  • 아이템 이름의 PosX = 27, Pos Y = 6으로 설정

  • 텍스트를 복사해서 Text Desc이라는 이름으로 아이템 설명을 배치

  • 아이템 설명의 글자 크기는 5로 설정

  • 아이템 설명Pos X = 27, Pos Y = -5로 설정

    	텍스트 색상은 마은대로 설정 

작업하지 않은 버튼은 지우고 새롭게 작업한 아이템 버튼으로 추가 복사 (아이템 3, 4번은 비활성화)

새롭게 복하나 아이템 버튼의 스크립트블 오브젝트 변수 초기화


아이템 텍스트

ItemData 스크립트에 인스펙터에 텍스트를 여러 줄 넣을 수 있게 TextArea 속성을 itemDesc 위에 작성한 후 인스펙터에서 설명 작성

[TextArea]
public string intemDesc;

이제 Item 스크립트에 이름과 설명 텍스트 변수를 추가 및 초기화를 진행한다.

GetComponents의 순서는 계층 구조의 순서를 따라가기 때문에 Level아 texts[0], Name이 texts[1], Desc가 texts[2]에 위치하게 된다.

이제 버튼이 활성화 될 때 레벨 텍스트를 조정하면 되므로 OnEnable 함수에 레벨 설정 로직을 옮긴다.
이후 아이템 타입에 따라 switch case 문으로 로직을 분리시켜 넘겨줄 매개변수를 지정한다.


창 컨트롤

이제 레벨업 창을 관린하는 LevelUp 스크립트를 작성한 후에 LevelUp 오브젝트의 컴포넌트로 추가한다.

public class LevelUp : MonoBehaviour
{
    RectTransform rect;

    // Start is called before the first frame update
    void Start()
    {
        rect = GetComponent<RectTransform>();
        
    }

    //레벨업 창을 보여주는 함수
    public void show()
    {
        rect.localScale = Vector3.one;
    }

    //레벨업 창을 숨기는 함수
    public void Hide()
    {
        rect.localScale = Vector3.zero;
    }
}

게임 매니저에 레벨언 ui를 관린할 변수를 선언해준 후에 게임 매니저의 인스펙터에 LevelUp 오브젝트를 드래그드랍해서 초기화를 시켜준다.

게임 매니저의 레벨업 부분에서 다음과 같이 show 함수를 호출하고, 아이템 레벨업 선택 시 Hide 함수를 호출한다.

show 함수 호출은 다음과 같이 게임 매니저 스크립트를 수정해준다.

Gamemanger.cs

public void GetExp()
{
    exp++;

    if(exp == nextExp[level])
    {
        level++;
        exp = 0;
        uiLevelUp.Show();
    }
}

Hide 함수 호출은 버튼 형식의 오브젝트인 아이템들이 OnClick 이벤트에서 호출되도록 인스펙터에서 설정해준다. 이 때 OnClick 이벤트를 하나 추가해주고 LevelUp 오브젝트를 드래그드랍해준 다음에 Hide 함수를 호출한다.

이제 LevelUp 창의 초기 Scale을 0으로 설정해준다.


기본 무기 지급

기본 무기를 지급해서 레벨업을 진행할 수 있도록 진행한다. 이 때 근접무기 아이템 버튼을 한 번 누르면 되는데 이를 다음과 같이 스크립트를 수정해서 작동한다.

LevelUp.cs

public class LevelUp : MonoBehaviour
{
    RectTransform rect;
    Item[] items;

    // Start is called before the first frame update
    void Awake()
    {
        rect = GetComponent<RectTransform>();
        items = GetComponentsInChildren<Item>(true); // true면 비활성화 된 item 컴포넌트도 가져온다.
        
    }

    //레벨업 창을 보여주는 함수
    public void Show()
    {
        rect.localScale = Vector3.one;
    }

    //레벨업 창을 숨기는 함수
    public void Hide()
    {
        rect.localScale = Vector3.zero;
    }

    public void Select(int index)
    {
        items[index].OnClick();
    }
}

이제 새로 작성한 select를 게임 매니저에서 실행시켜준다.

GameManager.cs

private void Start()
{
    health = maxHealth;
    uiLevelUp.Select(0); //0번째 무기 버튼 Click이벤트 호출
}

시간 컨트롤

아이템 선택 창에서 게임의 진행이 멈추도록 GameManager의 스크립트를 수정한다.

GameManager.cs

public void Stop()
{
    isLive = false;
    Time.timeScale = 0; //유니티의 시간 속도(배율)
}

public void Resume()
{
    isLive = true;
    Time.timeScale = 1; //유니티의 시간 속도(배율)
}

위에서 만든 Stop 함수를 레벨업 창이 나타날 때 호출, 레벨업창이 사라질 때 Resume을 호출 해주도록 LevelUp 스크립트를 수정한다.

LevelUp.cs

//레벨업 창을 보여주는 함수
public void Show()
{
    rect.localScale = Vector3.one;
    GameManager.Instance.Stop();
}

//레벨업 창을 숨기는 함수
public void Hide()
{
    rect.localScale = Vector3.zero;
    GameManager.Instance.Resume();
}

각 스크립트의 update 계열 로직에 다음과 같은 조건을 추가해준다.

if (!isLive)
	return;

Update, FixedUpdate, LateUpdate 모두 추가해주어야한다.

실행해준 후 플레이어의 isLive를 체크해주면 게임이 정상 작동하면서 레벨업 시 레벨업창이 뜨면서 시간이 멈추는 것을 확인할 수 있다.


랜덤 아이템

이제 아이템이 랜덤으로 3개를 활성화 시키는 함수를 제작해 활성화 시키면서 레벨, 설명 문구 또한 같이 초기화되는 로직이 잘 작동되도록 스크립트를 수정한다.

####LevelUp.cs

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

public class LevelUp : MonoBehaviour
{
    RectTransform rect;
    Item[] items;

    // Start is called before the first frame update
    void Awake()
    {
        rect = GetComponent<RectTransform>();
        items = GetComponentsInChildren<Item>(true); // true면 비활성화 된 item 컴포넌트도 가져온다.
    }

    //레벨업 창을 보여주는 함수
    public void Show()
    {
        Next();
        rect.localScale = Vector3.one;
        GameManager.Instance.Stop();
    }

    //레벨업 창을 숨기는 함수
    public void Hide()
    {
        rect.localScale = Vector3.zero;
        GameManager.Instance.Resume();
    }

    public void Select(int index)
    {
        items[index].OnClick();
    }

    void Next()
    {
        //1. 모든 아이템 비활성화
        foreach(Item item in items)
        {
            item.gameObject.SetActive(false); //item 컴포넌트의 게임오브젝트로 넘어가 비활성화
        }

        //2. 랜덤 아이템 3개 활성화
        int[] ran = new int[3];
        while (true)
        {
            ran[0] = Random.Range(0, items.Length);
            ran[1] = Random.Range(0, items.Length);
            ran[2] = Random.Range(0, items.Length);

            if (ran[0] != ran[1] && ran[1] != ran[2] && ran[2] != ran[0])
                break;
        }

        for(int i=0;i<ran.Length;i++)
        {
            Item ranItem = items[ran[i]];

            //3. 만렙 아이템의 경우는 소비 아이템으로 대체
            if (ranItem.level == ranItem.data.damages.Length)
            {
                items[4].gameObject.SetActive(true);
            }
            else
            {
                ranItem.gameObject.SetActive(true);
            }
        }
        
    }
}

무한 레벨업이 되도록 GameManager의 GetExp를 다음과 같이 수정한다.

GameManager.cs

public void GetExp()
{
    exp++;

    if(exp == nextExp[Mathf.Min(level, nextExp.Length-1)])
    {
        level++;
        exp = 0;
        uiLevelUp.Show();
    }
}

레벨이 만렙을 넘게되면 nextExp의 길이 - 1 값이 항상 더 작기 때문에 레벨 경험치가 고정된다. HUD의 겅험치 바도 다음과 같이 수정한다.

HUD

case InfoType.Exp:
    float curExp = GameManager.Instance.exp; //현재 exp
    float maxExp = GameManager.Instance.nextExp[Mathf.Min(GameManager.Instance.level, GameManager.Instance.nextExp.Length - 1)]; //레벨업에 필요한 경험치
    mySlider.value = curExp / maxExp;
    break;

결과물

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글