[ 레벨업 시스템 ] --> 레벨업 시 무기를 선택하는 로직 구현
- Canvas에서 우클릭 후 UI --> Image 생성(LevelUp)
- 앵커 누른 후 Shift + Alt 누른 후 꽉 찬 이미지로 선택
- 색상은 검은색에 A값을 150으로 설정 - 기존의 LevelUp 오브젝트 이름을 ItemGroup으로 변경
- LevelUp에서 우클릭 후 UI --> Image 생성(Panel)
- Source Sprite를 Panel로 변경
- Width = 100 | Height = 130으로 설정(마음대로)
- 색상은 R = 40, G =145 , B = 112(마음대로) - Panel에서 우클릭 후 UI --> Legacy --> Text 생성(Text Title)
- 앵커 누른 후 Shift + Alt 누른 후 상단 꽉 찬 이미지 클릭
- 텍스트 중앙정렬로 설정(Alignment)
- Height = 20으로 설정
- Font = neodgm으로 설정
- 색상은 흰색
- Text = 축하합니다! (Enter) 레벨이 상승했습니다! - Text에 Add Component
- Shadow(마음대로) - ItemGroup을 Panel에 자식으로 넣기(드래그&드랍)
- 앵커 선택 후 Shift + Alt 누른 후 꽉 찬 이미지 클릭
- Control Child Size에서 Width와 Height 모두 체크
- Spacing = 1로 설정
- Left, Right, Bottom = 5 | Top = 25로 설정
- Item 3,4 비활성화 - Item\Icon의 앵커 누른 후 Shift + Alt 누른 후 왼쪽 중단 이미지 클릭
- Pos X = 6 | Pos Y = 3으로 설정 - Text Level의 앵커 누른 후 Shift + Alt 누른 후 왼쪽 중단 이미지 클릭
- Width = 18로 설정
- Pos X = 6 | Pos Y = -10으로 설정 - Text Level을 Ctrl + D로 복사
- 이름을 Text Name으로 설정
- Text = 아이템 이름
- Font Size = 7로 설정
- Pos X = 26 | Pos Y = 6
- 텍스트 좌측 정렬로 설정 - Text Name을 Ctrl + D로 복사
- 이름을 Text Desc로 설정
- Font Size = 5로 설정
- Text = 아이템 설명 (Enter) 아이템 설명
- Pos X = 27 | Pos Y = -7로 설정 - Text Level, Text Desc 색상을 Panel 색상과 비슷하게 설정
- Item 1,2,3,4 모두 지운 후 Item 0를 4개 복사
- Item의 Data를 자신에 맞게 설정
- Item 3,4 비활성화 - 기존의 ItemData 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "Item", menuName = "Scriptble Object/ItemData")]
public class ItemData : ScriptableObject
{
public enum ItemType { Melee, Range, Glove, Shoe, Heal }
[Header("# Main Info")]
public ItemType itemType;
public int itemId;
public string itemName;
[TextArea] // 텍스트 여러 줄 입력 가능
public string itemDesc;
public Sprite itemIcon;
[Header("# Level Data")]
public float baseDamage;
public int baseCount;
public float[] damages;
public int[] counts;
[Header("# Weapon")]
public GameObject projectile;
public Sprite hand;
}
- Item 0의 Item Desc = 데미지 {0}% 증가 (Enter) 회전체 {1}개 추가
- Item 1의 Item Desc = 데미지 {0}% 증가 (Enter) 관통력 {1} 추가
- Item 2의 Item Desc = 연사속도 {0}% 증가
- Item 3의 Item Desc = 이동속 {0}% 증가
- Item 4의 Item Desc = 생명력 전체 회복
- 기존의 Item 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Item : MonoBehaviour
{
public ItemData data;
public int level;
public Weapon weapon;
public Gear gear;
Image icon;
Text textLevel;
Text textLName; // 이름 변수
Text textDesc; // 설명 변수
private void Awake()
{
icon = GetComponentsInChildren<Image>()[1];
icon.sprite = data.itemIcon;
Text[] texts = GetComponentsInChildren<Text>();
textLevel = texts[0];
textLName = texts[1]; //이름 변수 초기화
textDesc = texts[2]; //설명 변수 초기화
textLName.text = data.itemName; // 설명 변수 초기화
}
private void OnEnable()
{
textLevel.text = "LV." + (level + 1);
switch (data.itemType) // 로직 분리
{
case ItemData.ItemType.Melee: // Weapon
case ItemData.ItemType.Range: // Weapon
textDesc.text = string.Format(data.itemDesc, data.damages[level] * 100, data.counts[level]);
break;
case ItemData.ItemType.Glove: // Gear
case ItemData.ItemType.Shoe: // Gear
textDesc.text = string.Format(data.itemDesc, data.damages[level] * 100);
break;
default:
textDesc.text = string.Format(data.itemDesc);
break;
}
}
//LateUpdate() 삭제
public void OnClick()
{
switch(data.itemType)
{
case ItemData.ItemType.Melee:
case ItemData.ItemType.Range:
if(level == 0){
GameObject newWeapon = new GameObject();
weapon = newWeapon.AddComponent<Weapon>();
weapon.Init(data);
}
else{
float nextDamage = data.baseDamage;
int nextCount = 0;
nextDamage += data.baseDamage * data.damages[level];
nextCount += data.counts[level];
weapon.LevelUp(nextDamage, nextCount);
}
level++;
break;
case ItemData.ItemType.Glove:
case ItemData.ItemType.Shoe:
if (level == 0){
GameObject newGear = new GameObject();
gear = newGear.AddComponent<Gear>();
gear.Init(data);
}
else{
float nextRate = data.damages[level];
gear.LevelUp(nextRate);
}
level++;
break;
case ItemData.ItemType.Heal:
GameManager.instance.hp = GameManager.instance.maxHp;
break;
}
if(level == data.damages.Length)
{
GetComponent<Button>().interactable = false;
}
}
}
- C# 스크립트 생성(LevelUp)
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using System.Net.Http.Headers;
using UnityEngine;
public class LevelUp : MonoBehaviour
{
RectTransform rect; // RectTransform 변수
Item[] items; // Item[] 배열 변수
private void Awake()
{
rect = GetComponent<RectTransform>(); // Rectransform 초기화
items = GetComponentsInChildren<Item>(true); // Item[] 초기화
}
public void Show() // 창 활성화
{
Next();
rect.localScale = Vector3.one; // 활성화
GameManager.instance.Stop(); // Stop() 호출
}
public void Hide() // 창 비활성화
{
rect.localScale = Vector3.zero; // 비활성화
GameManager.instance.Resume(); // Resume() 호출
}
public void Select(int index)
{
items[index].OnClick(); // 버튼 클릭
}
void Next()
{
// 1. 모든 아이템 비활성화
foreach (Item item in items)
{
item.gameObject.SetActive(false);
}
// 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[0] != ran[2]) // 모두 같지 않게 선택이 됐을 때, 빠져나가기
break;
}
for(int index=0; index < ran.Length; index++)
{
Item ranItem = items[ran[index]];
// 3. 만렙 아이템의 경우는 소비 아이템으로 대체
if (ranItem.level == ranItem.data.damages.Length)
{
items[4].gameObject.SetActive(true);
}
else
{
ranItem.gameObject.SetActive(true);
}
}
}
}
- 기존의 GameManager 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
[Header("# Game Conrol")]
public bool isLive; // bool 변수
public float gameTime;
public float maxGameTime = 2 * 10f;
[Header("# Player Info")]
public int hp;
public int maxHp = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp; // LevelUp 변수
private void Awake()
{
instance = this;
}
void Start()
{
hp = maxHp;
// 임시 스크립트 (첫번째 캐릭터 무기 선택)
uiLevelUp.Select(0);
}
void Update()
{
if(!isLive)
{
return;
}
gameTime += Time.deltaTime;
if (gameTime > maxGameTime){
gameTime = maxGameTime;
}
}
public void GetExp()
{
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length-1)]) // 최고 경험치를 그대로 사용
{
level++;
exp = 0;
uiLevelUp.Show(); // LevelUp 창 활성화
}
}
public void Stop()
{
isLive = false;
Time.timeScale = 0; // 시간의 흐름 = 0 (배속)
}
public void Resume()
{
isLive = true;
Time.timeScale = 1; // 시간의 흐름 = 1
}
}
- LevelUp 오브젝트에 Add Component
- LevelUp(Script) - GameManager 오브젝트의 Ui Level Up에 LevelUp 오브젝트 넣기(드래그&드랍)
- Item 0~4 다중선택 후 Button의 On Click()에서 +버튼 누른 후, LevelUp 오브젝트 넣기(드래그&드랍)
- No Function을 LevelUp --> Hide로 변경 - LevelUp의 Rect Transform Scale = 0 | 0 | 0 으로 설정
- 각 스크립트의 Update 계열 로직에 조건 추가(GameManager, Player, Enemy, Spawner, Weapon)
ㅡ아래의 조건 추가ㅡ
if (!isLive)
return;
- 기존의 HUD 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using static Cinemachine.DocumentationSortingAttribute;
public class HUD : MonoBehaviour
{
public enum InforType { Exp, Level, Kill, Time, Health}
public InforType type;
Text myText;
Slider mySlider;
void Awake()
{
myText = GetComponent<Text>();
mySlider = GetComponent<Slider>();
}
private void LateUpdate()
{
switch (type)
{
case InforType.Exp:
float curExp = GameManager.instance.exp;
// 최고 경험치를 그대로 사용
float maxExp = GameManager.instance.nextExp[Mathf.Min(GameManager.instance.level, GameManager.instance.nextExp.Length - 1)];
mySlider.value = curExp/maxExp;
break;
case InforType.Level:
myText.text = string.Format("Lv.{0:F0}", GameManager.instance.level);
break;
case InforType.Kill:
myText.text = string.Format("{0:F0}", GameManager.instance.kill);
break;
case InforType.Time:
float remainTime = GameManager.instance.maxGameTime - GameManager.instance.gameTime;
int min = Mathf.FloorToInt(remainTime / 60);
int sec = Mathf.FloorToInt(remainTime % 60);
myText.text = string.Format("{0:D2}:{1:D2}", min, sec);
break;
case InforType.Health:
float curHp = GameManager.instance.hp;
float maxHp = GameManager.instance.maxHp;
mySlider.value = curHp / maxHp;
break;
}
}
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
★Slow and Steady★
'Unity 공부 > Unity_2D' 카테고리의 다른 글
| [Day 13] 플레이 캐릭터 선택 (0) | 2023.07.19 |
|---|---|
| [Day 12] 게임 시작과 종료 구현 (0) | 2023.07.18 |
| [Day 10] 무기 장착 표현 (0) | 2023.07.16 |
| [Day 9] 능력 업그레이드 구현 (0) | 2023.07.15 |
| [Day 8] HUD 제작 (0) | 2023.07.14 |