using UnityEngine;
using UnityEngine.UI;
public class FloatingText : MonoBehaviour
{
public float moveSpeed;
public float destroyTime;
public Text text;
private Vector3 vector;
// Update is called once per frame
void Update()
{
vector.Set(text.transform.position.x, text.transform.position.y + (moveSpeed * Time.deltaTime), text.transform.position.z);
//Time.deltaTime로 초당 움직임으로 적용
text.transform.position = vector;
destroyTime -= Time.deltaTime;
if(destroyTime <= 0)
{
Destroy(this.gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
public static Inventory Instance;//인벤토리 인스턴스
private DatabaseManager theDatabase;//데이터 베이스 접근
private OrderManager theOrder; //오더매니져
private AudioManager theAudio; //오디오매니져
private OkOrCancel theOOC; //아이템 선택 받아옴
public string key_sound;
public string enter_sound;
public string cancel_sound;
public string open_sound;
public string beep_sound; //비프음을 포함한 각종 효과음
private InventorySlot[] slots; //인벤토리 슬롯들
private List<Item> inventoryItemList; //플레이어가 소지한 아이템 리스트
private List<Item> inventoryTabList; //선택한 탭에 따라 다르게 보여질 아이템 리스트
public Text Description_Text; //아이템 부연설명
public string[] tabDescription; //탭 부연설명
public Transform tf; //slot(슬롯)의 부모객체
public GameObject go; //인벤토리 활성화 비활성화
public GameObject[] selectedTabImages; //4개의 탭 패널
public GameObject go_OOC; //선택지 활성화 비활성화
public GameObject prefab_Floating_text; //플로팅 텍스트 아이템 획득시 이름 알림
private int selectedItem; //선택된 아이템
private int selectedTab; //선택 된 텝
private bool activated; //인벤토리 활성화시 true;
private bool tabActivated; //탭 활성화시 true;
private bool itemActivated; //아이템 활성화시 true;
private bool stopkeyInput; //키 입력제한(소비 할때 질의가 나올텐데, 그때 입력방지)
private bool preventExec; //중복실행 제한
private WaitForSeconds waitTime = new WaitForSeconds(0.01f);
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
Instance = this;//인벤토리 인스턴스
theAudio = FindAnyObjectByType<AudioManager>(); //오디오매니져
theOrder = FindAnyObjectByType<OrderManager>(); //오더매니져
theDatabase = FindAnyObjectByType<DatabaseManager>();
theOOC = FindAnyObjectByType<OkOrCancel>(); //아이템 선택 매니져
inventoryItemList = new List<Item>(); //아이템 리스트화
inventoryTabList = new List<Item>(); //탭 리스트화
slots = tf.GetComponentsInChildren<InventorySlot>();//겟 컴포넌츠 인 칠드런으로 인벤토리 슬롯들을 불러옴
}
public void GetAnItem(int _itemID, int _count = 1)
{
for (int i = 0; i < theDatabase.itemList.Count; i++)//데이터베이스 아이템 검색
{
if (_itemID == theDatabase.itemList[i].itemID)//데이터 베이스에 아이템 발견
{
var clone = Instantiate(prefab_Floating_text, PlayerManager.instance.transform.position, Quaternion.Euler(Vector3.zero));
clone.GetComponent<FloatingText>().text.text = theDatabase.itemList[i].itemName + " " + _count + "개 획득 +";
clone.transform.SetParent(this.transform);
for (int j = 0; j < inventoryItemList.Count; j++)//소지품에 같은 아이템이 있는지 확인
{
if (inventoryItemList[j].itemID == _itemID)//소지품에 같은 아이템이 있다 -> 개수만 증감시켜줌
{
if (inventoryItemList[j].itemType == Item.ItemType.Use)
{
inventoryItemList[j].itemCount += _count;
}else
{
inventoryItemList.Add(theDatabase.itemList[i]);
}
return;
}
}
inventoryItemList.Add(theDatabase.itemList[i]);//없을시 해당 아이템 추가
inventoryItemList[inventoryItemList.Count - 1].itemCount = _count;
return;
}
}
Debug.LogError("데이터 베이스에 해당 ID값을 가진 아이템이 존재하지 않습니다");//데이터베이스에 ItemID 없음
}
public void RemoveSlot()//모든 슬롯을 비활성화
{
for (int i = 0; i < slots.Length; i++) //i = 0이고 i는 slots들보다 적고 i++로 증감
{
slots[i].RemoveItem(); //InventorySlot스크립트에서 아이템이 사라지는 로직 slots[i]로 여러개를 선택
slots[i].gameObject.SetActive(false); //로직 slots[i]로 여러개를 선택 후 오브젝트를 비활성화
}
}//인벤토리 슬롯 초기화
public void ShowTab()//탭 활성화
{
RemoveSlot();
SelectedTab();
}
public void SelectedTab()//선택된 탭을 제외하고 다른 모든 탭의 컬러 알파값 0으로 조정
{
StopAllCoroutines();//모든 코루틴 정지
Color color = selectedTabImages[selectedTab].GetComponent<Image>().color;//탭의 반짝임을 위해 배열을 받아옴
color.a = 0f; //위에 선택된 배열의 컬러 알파값이 0
for(int i =0; i < selectedTabImages.Length; i++) //i=0과 같고 i는 선택된 탭보다 작다, i++로 증감
{
selectedTabImages[i].GetComponent<Image>().color = color; //위의 i번째에 선택된 오브젝트의 컬러값을 가져옴
}
Description_Text.text = tabDescription[selectedTab]; //각 탭에 위치한 설명을 출력함
StartCoroutine(SelectedTabEffectCoroutine()); //스타트 코루틴, 탭효과를 출력!
}
IEnumerator SelectedTabEffectCoroutine() //위의 탭 효과를 출력
{
while (tabActivated) //탭이 true면 반복됨
{
Color color = selectedTabImages[selectedTab].GetComponent<Image>().color; //선택한 탭의 color, Image를 받아옴
while (color.a < 0.5f) //반복문 알파값이 반절보다 작을때
{
color.a += 0.03f;
selectedTabImages[selectedTab].GetComponent<Image>().color = color; //컬러 알파값에 계속 0.03f정도 더해줌
yield return waitTime; //0.01f 정도 대기
}
while (color.a > 0f) //알파값이 0보다 클 경우 반복
{
color.a -= 0.03f; //알파값에 0.03f정도 계속 빼서 내려줌
selectedTabImages[selectedTab].GetComponent<Image>().color = color; //컬러값에 적용
yield return waitTime; //0.01f 대기
}
yield return new WaitForSeconds(0.3f); //0.3초 대기
}
}//선택된 탭 반짝임 효과
public void ShowItem()//아이템 활성화(inventoryTabList에 조건에 맞는 아이템들만 넣어주고, 인벤토리 슬롯에 출력)
{
inventoryTabList.Clear(); //인벤토리 탭 리스트 초기화
RemoveSlot(); //표시되는 슬롯 초기화
selectedItem = 0; //선택된 아이템 배열의 0번째 선택
switch (selectedTab)//탭에 따른 아이템 분류
{
case 0:
for(int i =0; i < inventoryItemList.Count; i++)
{
if(Item.ItemType.Use == inventoryItemList[i].itemType)//소모품
inventoryTabList.Add(inventoryItemList[i]);//Add로 쫘악 펼쳐줌
}
break;
case 1:
for (int i = 0; i < inventoryItemList.Count; i++)
{
if (Item.ItemType.Equip == inventoryItemList[i].itemType)//장비품
inventoryTabList.Add(inventoryItemList[i]);//Add로 쫘악 펼쳐줌
}
break;
case 2:
for (int i = 0; i < inventoryItemList.Count; i++)
{
if (Item.ItemType.Quest == inventoryItemList[i].itemType)//퀘스트 아이템
inventoryTabList.Add(inventoryItemList[i]);//Add로 쫘악 펼쳐줌
}
break;
case 3:
for (int i = 0; i < inventoryItemList.Count; i++)
{
if (Item.ItemType.ETC == inventoryItemList[i].itemType)//기타
inventoryTabList.Add(inventoryItemList[i]);//Add로 쫘악 펼쳐줌
}
break;
}//탭에 따른 아이템 분류, 그것을 인벤토리 탭 리스트에 추가
for(int i = 0;i < inventoryTabList.Count; i++)//인벤토리 탭 리스트의 내용을 인벤토리 슬롯에 추가
{
slots[i].gameObject.SetActive(true);//인벤토리 아이템 리스트를 활성화
slots[i].Additem(inventoryTabList[i]);//Additem으로 쫘악 배열을 펼쳐줌
}
SelectedItem();
}
public void SelectedItem()//선택된 아이템을 제외하고, 다른 모든 탭의 컬러 알파값을 0으로 조정
{
StopAllCoroutines();//모든 코루틴 종료
if (inventoryTabList.Count > 0)//조건문 인벤토리 탭 리스트가 0보다 크다면
{
Color color = slots[0].selected_Item.GetComponent<Image>().color;//슬롯 0번재의 Image와 Color을 받아옴
color.a = 0f; //초기값은 0f
for (int i = 0; i < inventoryTabList.Count; i++) //반복문 i는 0이고 i는 인벤토리 탭 카운트리스트보다 작고 i++증감
slots[i].selected_Item.GetComponent<Image>().color = color; //반복문의 Image와 Color을 받아옴
Description_Text.text = inventoryTabList[selectedItem].itemDescription;//설명문에 인벤토리 탭 리스트의 배열의 셀렉티드 아이템의 아이템 설명과 같다
StartCoroutine(SelectedItemEffectCoroutine()); //선택된 아이템 이팩트 실행
}
else
Description_Text.text = "해당 타입의 아이템을 소유하고 있지 않습니다";//만약 해당탭에 해당하는 아이템이 없을 경우 메시지 출력
}
IEnumerator SelectedItemEffectCoroutine()//선택된 아이템 반짝임 효과
{
while (itemActivated) //아이템 선택이 true가 될 경우
{
Color color = slots[0].GetComponent<Image>().color; //슬롯의 배열에 해당하는 슬롯의 Image와 color을 받아와서
while (color.a < 0.5f) //반복문 알파값이 0.5f보다 클 경우
{
color.a += 0.03f; //0.03f만큼 계속 더해짐
slots[selectedItem].selected_Item.GetComponent<Image>().color = color;//위의 컬러 적용
yield return waitTime; //0.01초 대기
}
while (color.a > 0f) //알파값이 0보다 클 경우
{
color.a -= 0.03f; //0.03f만큼 계속 빼줌
slots[selectedItem].selected_Item.GetComponent<Image>().color = color;//컬러에 적용
yield return waitTime; //0.01초 대기
}
yield return new WaitForSeconds(0.3f);
}
}
// Update is called once per frame
void Update()
{
if (!stopkeyInput)//키 입력제한이 false일때
{
if (Input.GetKeyDown(KeyCode.I))
{
activated = !activated;//true/false on/off
if (activated)//인벤토리 활성화를 True
{
theAudio.Play(open_sound); //여는 소리 재생
theOrder.NotMove(); //오더매니져의 움직임 정지
go.SetActive(true); //오브젝트 활성화
selectedTab = 0; //탭창에서 0번째 탭을 선택
tabActivated = true; //탭부터 보게 탭부분을 true화
itemActivated = false; //아이템 창은 false화
ShowTab();
}
else
{
theAudio.Play(cancel_sound); //캔슬소리 재생
StopAllCoroutines(); //모든 코루틴 종료
go.SetActive(false); //오브젝트 false로 비활성화
tabActivated = false; //탭 비활성화
itemActivated = false; //아이템 부분 비활성화
theOrder.Move(); //오더매니져 이동 활성화
}
}//I키로 실행
if (activated) //인벤토리 활성화시
{
if (tabActivated) //탭 활성화시 키 입력 처리
{
if (Input.GetKeyDown(KeyCode.RightArrow)) //오른쪽 버튼을 누름
{
if (selectedTab < selectedTabImages.Length - 1) //선택 된 탭이 선택된 탭 이미지에서 -1한 값보다 작을 경우
selectedTab++; //선택된 탭 값을 ++로
else //아니라면
selectedTab = 0; //탭 선택을 0으로 함
theAudio.Play(key_sound); //사운드 재생
SelectedTab(); //탭선택 실행
}
if (Input.GetKeyDown(KeyCode.LeftArrow)) //왼쪽 버튼 누름
{
if (selectedTab > 0) //선택된 탭 값이 0보다 크다면
selectedTab--; //-- 감소 선택
else //아니라면 선택된 탭과 선택된 탭 이미지에서 -1한 값과 같다
selectedTab = selectedTabImages.Length - 1;
theAudio.Play(key_sound); //소리재생
SelectedTab(); //탭선택 실행
}
else if (Input.GetKeyDown(KeyCode.Z)) //Z키 입력으로 탭 선택시
{
theAudio.Play(enter_sound); //소리 재생
Color color = selectedTabImages[selectedTab].GetComponent<Image>().color;//선택된 배열 탭의 배열에 선택된 탭 넘버를 넣어준 후 해당 Image와 color을 받아와서
color.a = 0.25f; //선택된 컬러의 알파값을 0.25f로 바꿔 줌
selectedTabImages[selectedTab].GetComponent<Image>().color = color; //위의 바꾼 컬러를 적용해 줌
itemActivated = true; //아이템 선택 활성화
tabActivated = false; //탭선택 비활성화
preventExec = true; //키 중복입력 방지
ShowItem(); //Item선택 활성화
}
}
else if (itemActivated) //아이템 창 활성화시
{
if(inventoryTabList.Count > 0) //아이템 탭 리스트 카운트가 0보다 클 경우
{
if (Input.GetKeyDown(KeyCode.DownArrow)) //키보드 아래쪽 화살표 누를시
{
if (selectedItem < inventoryTabList.Count - 2) //조건문 선택된 아이템이 인벤토리탭리스트 카운트에서 2뺀 값보다 작을 경우
selectedItem += 2; //2를 계속 더 해줌
else //조건이 아니라면
selectedItem %= 2; //2를 나누고 남은 값을 대입해준다
theAudio.Play(key_sound);
SelectedItem(); //선택된 아이템의 알파값을 제외하고 다른 슬롯의 알파값을 초기화
}
else if (Input.GetKeyDown(KeyCode.UpArrow)) //위쪽 버튼을 누를 경우
{
if (selectedItem > 1) //조건문 1보다 클 경우
selectedItem -= 2; //2를 빼준다
else //조건이 아니라면
selectedItem = inventoryTabList.Count - 1 - selectedItem; //선택 된 아이템은 선택된 아이템 값 카운트에서 1을 빼주고 선택된 아이템을 빼준 값과 같다
theAudio.Play(key_sound);
SelectedItem(); //선택된 아이템의 알파값을 제외하고 다른 슬롯의 알파값을 초기화
}
else if (Input.GetKeyDown(KeyCode.RightArrow)) //오른쪽을 버튼을 누른 경우
{
if (selectedItem < inventoryTabList.Count - 1) //선택된 아이템이 인벤토리 배열에서 카운트된 숫자 -1한 값보다 적을 경우
selectedItem++; //선택된 아이템 번호를 증감하여 오른쪽으로 이동
else
selectedItem = 0; //아니라면 0과 같다
theAudio.Play(key_sound);
SelectedItem(); //선택된 아이템의 알파값을 제외하고 다른 슬롯의 알파값을 초기화
}
else if (Input.GetKeyDown(KeyCode.LeftArrow)) //왼쪽 버튼을 누름
{
if (selectedItem > 0) //0보다 클 경우
selectedItem--; //숫자를 감소하여 왼쪽으로 이동
else
selectedItem = inventoryTabList.Count - 1; //그게 아니라면 선택된 아이탬 순서는 카운트된 인벤토리 탭에서 -1 값과 같다
theAudio.Play(key_sound);
SelectedItem(); //선택된 아이템의 알파값을 제외하고 다른 슬롯의 알파값을 초기화
}
else if (Input.GetKeyDown(KeyCode.Z) && !preventExec) //z를 클릭하면서 중복이 방지된 경우
{
if (selectedTab == 0)//소모품
{
theAudio.Play(enter_sound);
stopkeyInput = true;
StartCoroutine(OOCCoroutine());
}
else if (selectedTab == 1)
{
//장비장착
}
else
{
theAudio.Play(beep_sound);
}
}
}
if (Input.GetKeyDown(KeyCode.X))//x버튼을 눌른 경우
{
theAudio.Play(cancel_sound);//캔슬 사운드 재생
StopAllCoroutines(); //모든 코루틴 종료
itemActivated = false; //아이템 선택 비활성화
tabActivated = true; //탭선택 활성화
ShowTab();
Debug.Log("X키가 눌렸습니다");
}
}
if (Input.GetKeyUp(KeyCode.Z))//중복 실행 방지
preventExec = false;
}
}
}
IEnumerator OOCCoroutine()//OK,Cancel
{
go_OOC.SetActive(true);//OkOrC 오브젝트를 활성화
theOOC.ShowTwoChoice("사용", "취소");//사용 취소를 선택
yield return new WaitUntil(()=> !theOOC.activated);//theOOC가 false가 될때 멈춤
if (theOOC.GetResult())//레절트 값을 받아옴
{
for(int i = 0; i < inventoryItemList.Count; i++)//인벤토리에서 아이템 리스트를 검색
{
if (inventoryItemList[i].itemID == inventoryTabList[selectedItem].itemID)//검색한 아이템이 맞는지 확인
{
theDatabase.UseItem(inventoryItemList[i].itemID);//데이터베이스에서 Use아이템일 경우
if (inventoryItemList[i].itemCount > 1)//1보다 클 경우
inventoryItemList[i].itemCount--;//하나 감소
else
inventoryItemList.RemoveAt(i);//만약 하나일 경우 없셈
ShowItem();
break;
}
}
}
stopkeyInput = false;
go_OOC.SetActive(false);
}
}
아이템 획득이나 데미지를 입었을때 순간적으로 뜨는 텍스트를 표시해 줄 것이다
UI > Legacy > Text를 선택해서 텍스트를 만들어 주자
이름은 FloatingText 이다
Text의 설정 값
15포인트의 글씨크기 가로,세로에 Overflow 잘보이게 흰색을 처리해주자
그리고 그 아래 컴포넌트를 보면 Outline가 보일탠데 이건 글씨 바깟을 진하게 입혀주는 컴포넌트이다
이제 FloatingText 라고 하는 C# 스크립트를 작성해주자
주석만으로 설명이 가능해서 주석으로 채워 넣었다
이제 Inventory 스크립트로 가자
그리고 Inventory스크립트에 추가로 작성해주자
빨간선으로 묵어놓은 것이 작성해준 코드이다
주석으로 설명이 가능해서 주석으로 설명해놓았다
그리고 이제 우리가 만들어 놓은 FloatingText 오브젝트에
Floating Text 스크립트를 넣어주자
Move Speed에 15
Destory Time에 1.5초
Text 슬롯에는 우리가 만들어 준 FloatingText 텍스트 오브젝트를 넣어준다
이제 우리가 만들어 놓은 FloatingText 는 Project에 끌어 넣어서 프리팹으로 만들어 준다
이제 복제한 프리팹을 질리도록 사용할 것이다
그리고 Inventory오브젝트로 들어가서 이번에 새로 작성해서 만들어진
Prfab_Floating_text에 이번에 새로 만들은 프리팹을 넣어준다
이제 테스트를 해보면...
이렇게 작동이 잘 된다!
'쯔꾸르식 유니티 게임 공부' 카테고리의 다른 글
29.피격효과 스텟구현 (0) | 2025.03.05 |
---|---|
28.슬라임(몬스터) 구현 (0) | 2025.02.28 |
26.획득한 아이템 사용 (0) | 2025.02.26 |
25a.아이템 습득 버그피스 (0) | 2025.02.26 |
25.아이템 습득 (0) | 2025.02.25 |