using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class Equipment : MonoBehaviour
{
private OrderManager theOrder; //오더메니져
private AudioManager theAudio; //오디오매니져
private PlayerStat thePlayerStat; //플레이어 스텟
private Inventory theInven; //인벤토리
private OkOrCancel theOOC; //OKorCancel오브젝트
public string key_sound;
public string enter_sound;
public string open_sound;
public string close_sound;
public string takeoff_sound; //각종 사운드
public string equip_sound;
private const int WEAPON = 0, SHILED = 1, AMULT = 2, LEFT_RING = 3, RIGHT_RING = 4,//const는 변수값을 수정할 수 없다
HELMET = 5, ARMOR = 6, LEFT_GLOVE = 7, RIGHT_GLOVE = 8, BELT = 9,
LEFT_BOOTS = 10, RIGHT_BOOTS = 11;
private const int ATK = 0, DEF = 1, HPR = 6, MPR = 7;
private int added_atk, added_def, added_hpr, added_mpr;
public GameObject equipWeapon;
public GameObject go; //장비창 키고 끄기
public GameObject go_OOC; //OkOrCancel 키고 끄기
public Text[] text; //스텟
public Image[] img_slots; //장비 아이콘들
public GameObject go_selected_Slot_UI; //선택된 장비 슬롯UI
public Item[] equipItemList; //장착된 장비 리스트
private int selectedSlot; //선택된 장비 슬롯
public bool activated = false; //Equip창 활성화
private bool inputKey = true; //키 입력 활성화
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()//각종 메니져 장착
{
theInven = FindAnyObjectByType<Inventory>();
theOrder = FindAnyObjectByType<OrderManager>();
theAudio = FindAnyObjectByType<AudioManager>();
thePlayerStat = FindAnyObjectByType<PlayerStat>();
theOOC = FindAnyObjectByType<OkOrCancel>();
}
public void ShowText()
{
if(added_atk == 0)
{
text[ATK].text = thePlayerStat.atk.ToString();
}
else
{
text[ATK].text = thePlayerStat.atk.ToString() + "(+" + added_atk + ")";
}
if(added_def == 0)
{
text[DEF].text = thePlayerStat.def.ToString();
}
else
{
text[DEF].text = thePlayerStat.def.ToString() + "(+" + added_def + ")";
}
if(added_hpr == 0)
{
text[HPR].text = thePlayerStat.recover_hp.ToString();
}
else
{
text[HPR].text = thePlayerStat.recover_hp.ToString() + "(+" + added_hpr + ")";
}
if(added_mpr == 0)
{
text[MPR].text = thePlayerStat.recover_hp.ToString();
}
else
{
text[MPR].text = thePlayerStat.recover_mp.ToString() + "(+" + added_mpr + ")";
}
}
public void EquipItem(Item _item)//장착 아이템 적용
{
string temp = _item.itemID.ToString();//아이템 ID를 문자화
temp = temp.Substring(0, 3); //3번째 글씨까지 검색
switch (temp) //검색한 3글자로 스위치문화
{
case "200"://무기
EquipItemCheck(WEAPON, _item);
equipWeapon.SetActive(true);
equipWeapon.GetComponent<SpriteRenderer>().sprite = _item.itemIcon;//겟컴포넌트 스프라이트렌더러.스프라이트 아이콘 = _item.itemIcon;
break;
case "201"://방패
EquipItemCheck(SHILED, _item);
break;
case "202"://아뮬렛
EquipItemCheck(AMULT, _item);
break;
case "210"://반지
EquipItemCheck(LEFT_RING, _item);
break;
}
}
public void EquipItemCheck(int _count, Item _item)//인수로 숫자와 아이템 변수를 받아옴
{
if (equipItemList[_count].itemID == 0) //장착된 아이템 숫자번호가 0이라면
{
equipItemList[_count] = _item; //인수로 받아온 아이템이 장착되게 해줌
}
else
{
theInven.EquipToInventory(equipItemList[_count]);//숫자로 아이템 종류를 구분해서 받아옴
equipItemList[_count] = _item; //아이템 창에 장착한 것을 도로 넣어줌
}
EquipEffect(_item);
theAudio.Play(equip_sound);
ShowText();
}
public void SelectedSlot()
{
go_selected_Slot_UI.transform.position = img_slots[selectedSlot].transform.position;
//게임오브젝트 선택된 아이템슬롯 transform.position은 img_slots[selectedSlot].transform.position과 같다
}
public void ClearEquip()
{
Color color = img_slots[0].color;
color.a = 0f; //선택된 장비창의 이미지 알파값을 0으로 한다
for(int i = 0; i < img_slots.Length; i++)//이미지 슬롯의 배열을 쫘알 보여준다
{
img_slots[i].sprite = null; //장비 아이콘이 없으면 빈 네모칸을 비움
img_slots[i].color = color; //마찬가지로 빈 네모칸의 알파값을 0으로 만듬
}
}
public void ShowEquip()
{
Color color = img_slots[0].color;
color.a = 1f; //0번 슬롯 아이템의 컬러의 a값을 1로 한다
for (int i = 0; i < img_slots.Length; i++) //for문으로 모든 아이템 슬롯 배열을 불러온다
{
if (equipItemList[i].itemID != 0) //장비된 아이템 슬롯의 아이템ID가 0이 아니라면
{
img_slots[i].sprite = equipItemList[i].itemIcon;//슬롯에 장비된 아이템의 아이콘을 불러온다
img_slots[i].color = color; //color의 컬러의 a값을 1로 한다
}
}
}
private void EquipEffect(Item _item)//장비 아이템 장착효과
{
thePlayerStat.atk += _item.atk;
thePlayerStat.def += _item.def;
thePlayerStat.recover_hp += _item.recover_hp;
thePlayerStat.recover_mp += _item.recover_mp;
added_atk += _item.atk;
added_def += _item.def;
added_hpr += _item.recover_hp;
added_mpr += _item.recover_mp;
}
private void TakeOfEffect(Item _item)
{
thePlayerStat.atk -= _item.atk;
thePlayerStat.def -= _item.def;
thePlayerStat.recover_hp -= _item.recover_hp;
thePlayerStat.recover_mp -= _item.recover_mp;
added_atk -= _item.atk;
added_def -= _item.def;
added_hpr -= _item.recover_hp;
added_mpr -= _item.recover_mp;
}
// Update is called once per frame
void Update()
{
if (inputKey)
{
if (Input.GetKeyDown(KeyCode.E))//e키로 장비창 불러오기
{
activated = !activated;//On/Off
if (activated)//활성화 됬을경우
{
theOrder.NotMove(); //오더 매니져 움직임 정지
theAudio.Play(open_sound); //사운드 재생
go.SetActive(true); //장비창을 활성화한다
selectedSlot = 0; //처음 선택된 슬롯은 0번
SelectedSlot(); //슬롯 선택 함수
ClearEquip(); //장비 아이템 클리어 함수
ShowEquip(); //장비된 아이템 보여주는 함수
ShowText(); //장비 장착시 능력치 변화
}
else//그렇지 않을 경우
{
theOrder.Move(); //움직임 활성화
theAudio.Play(close_sound); //사운드 재생
go.SetActive(false); //장비창 비활성화
ClearEquip(); //장비 아이템 클리어 함수
}
}
if (activated)
{
if (Input.GetKeyDown(KeyCode.DownArrow))
{
if (selectedSlot < img_slots.Length - 1)
selectedSlot++;
else
selectedSlot = 0;
theAudio.Play(key_sound);
SelectedSlot();
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
if (selectedSlot < img_slots.Length - 1)
selectedSlot++;
else
selectedSlot = 0;
theAudio.Play(key_sound);
SelectedSlot();
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
if (selectedSlot > 0)
selectedSlot--;
else
selectedSlot = img_slots.Length - 1;
theAudio.Play(key_sound);
SelectedSlot();
}
else if (Input.GetKeyDown(KeyCode.UpArrow))
{
if (selectedSlot > 0)
selectedSlot--;
else
selectedSlot = img_slots.Length - 1;
theAudio.Play(key_sound);
SelectedSlot();
}
else if (Input.GetKeyDown(KeyCode.Z))
{
if (equipItemList[selectedSlot].itemID != 0)
{
theAudio.Play(enter_sound);
inputKey = false;
StartCoroutine(OOCCoroutine("벗기", "취소"));
}
}
}
}
}
IEnumerator OOCCoroutine(string _up,string _down) //인수로 위쪽 텍스트와 아래쪽 텍스트를 바꿀수 있게해줌
{
go_OOC.SetActive(true); //OkOrC 오브젝트의 panel을 활성화
theOOC.ShowTwoChoice(_up, _down); //사용 취소를 선택
yield return new WaitUntil(() => !theOOC.activated);//theOOC가 false가 될때 멈춤
if (theOOC.GetResult()) //레절트 값을 받아옴
{
theInven.EquipToInventory(equipItemList[selectedSlot]);
TakeOfEffect(equipItemList[selectedSlot]);
if(selectedSlot == WEAPON)
equipWeapon.SetActive(false);
ShowText();
equipItemList[selectedSlot] = new Item(0, "", "", Item.ItemType.Equip);
theAudio.Play(takeoff_sound);
ClearEquip();
ShowEquip();
}
inputKey = true;//키 활성화
go_OOC.SetActive(false); //OkOrCancal 오브젝트 비활성화
}
}
이번 시간에는 스프라이트 애니메이션으로 아이템을 장착하고 공격모션이나 이동모션을 바꿔주는 것을 배운다
일단 Player을 선택하고 빈 오브젝트를 만들어 준다
그뒤 SpriteRenderer 컴포넌트를 추가해 준 다음 20001번 검 아이템 아이콘을 찾아서 연결해준다
그뒤 애니메이터로 들어가서 포지션과 로테이션을 적절하게 수정해서 이렇게 검을 들고 있는 모습을 녹화해준다
이와 같은 요령으로 up,down,left,right 쪽 전부 수정해준다
다음은 이동 모션을 수정 할 것이다
스프라이트가 겹치는 순서를 신경써주면서 이렇게 프레임별로 이동하는 애니메이션을 넣어준다
그런데 글을 읽고 실습을 하면 알게 될 텐데
유니티 엔진은 기본적으로 부드럽게 애니메이션을 재생하기 때문에 칼부분이 프레임에 맞춰서 딱딱 끊어지게 움직이지 않는다
답은 프레임 노드를 쫘악 드래그해서 클릭하고 Both Tangents > Constant 를 선택해주면 된다
그러면 필자처럼 뚝뚝 끊기는 애니메이션이 만들어진다
이제 공격모션도 방향별로 전부 수정해준다
이제 스크립트를 수정해보자 Equipment 스크립트를 열어주자
위 스크린샷에서 체크한 아이템 장비 스프라이트 부분을 선언해주자
다음은 빨간색으로 채크한 부분을 추가해주자
97번 줄은 게임 오브젝트를 활성화 한다는 뜻이고
98번 줄은 스프라이트렌더러에서 스프라이트 부분을 인수로 넘어온 아이템 아이콘과 같게 해준다는 뜻이다
참고로 겟컴포넌트로 선언해주는 변수가 있는데...
위 스샷을 참고하면서 보자
일단 GetComponent는 컴포넌트를 불러온다는 뜻이고
SpriteRenderer은 스프라이트렌더러 컴포넌트를 불러오고
sprite는 스프라이트렌더러 내부의 sprite 항목을 불러온다는 뜻이다
너무 어렵게 생각하지 말자
다음은 여기에 체크된 부분을 추가하자
조건문으로 선택된 슬롯이 웨폰일 경우 웨폰을 비활성화한다는 뜻이다
이제 인스펙터 슬롯에 연결해주자
우리는 아이템을 장착하는 것을 구현했기 때문에 무기 스프라이트를 None로 바꿔준다
그리고 GameObject를 비활성화 해준다
이제 구현된 것을 확인하자
구현이 잘 되었다
'쯔꾸르식 유니티 게임 공부' 카테고리의 다른 글
36.적 체력바 개별구현 (0) | 2025.03.14 |
---|---|
35.HUD 체력바 구현 (0) | 2025.03.14 |
33.장비아이템 효과 추가 (0) | 2025.03.11 |
32.장비창 구현 (0) | 2025.03.10 |
26.a 오타 수정 (0) | 2025.03.08 |