캔버스에 이미지 오브젝트 하나를 만들어준후 화면을 꽉 채우도록 앵커 설정을 해준다.
해당 LevelUp 오브젝트 안에 자식 오브젝트로 창이 될 이미지 오브젝트를 추가해준다.
창의 제목이 될 텍스트 오브젝트를 Panel의 자식 오브젝트로 추가
이제 ItemGroup을 Panel의 자식으로 설정한 후
Control Child Size : 자식 오브젝트를 자신의 크기에 맞게 자동 변경
텍스트를 복사해서 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 함수 호출은 다음과 같이 게임 매니저 스크립트를 수정해준다.
public void GetExp()
{
exp++;
if(exp == nextExp[level])
{
level++;
exp = 0;
uiLevelUp.Show();
}
}
Hide 함수 호출은 버튼 형식의 오브젝트인 아이템들이 OnClick 이벤트에서 호출되도록 인스펙터에서 설정해준다. 이 때 OnClick 이벤트를 하나 추가해주고 LevelUp 오브젝트를 드래그드랍해준 다음에 Hide 함수를 호출한다.
이제 LevelUp 창의 초기 Scale을 0으로 설정해준다.
기본 무기를 지급해서 레벨업을 진행할 수 있도록 진행한다. 이 때 근접무기 아이템 버튼을 한 번 누르면 되는데 이를 다음과 같이 스크립트를 수정해서 작동한다.
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를 게임 매니저에서 실행시켜준다.
private void Start()
{
health = maxHealth;
uiLevelUp.Select(0); //0번째 무기 버튼 Click이벤트 호출
}
아이템 선택 창에서 게임의 진행이 멈추도록 GameManager의 스크립트를 수정한다.
public void Stop()
{
isLive = false;
Time.timeScale = 0; //유니티의 시간 속도(배율)
}
public void Resume()
{
isLive = true;
Time.timeScale = 1; //유니티의 시간 속도(배율)
}
위에서 만든 Stop 함수를 레벨업 창이 나타날 때 호출, 레벨업창이 사라질 때 Resume을 호출 해주도록 LevelUp 스크립트를 수정한다.
//레벨업 창을 보여주는 함수
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를 다음과 같이 수정한다.
public void GetExp()
{
exp++;
if(exp == nextExp[Mathf.Min(level, nextExp.Length-1)])
{
level++;
exp = 0;
uiLevelUp.Show();
}
}
레벨이 만렙을 넘게되면 nextExp의 길이 - 1 값이 항상 더 작기 때문에 레벨 경험치가 고정된다. 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;