Chapter 11-3. 포션 제조 : 포션 제조 대기열, 독립적인 쿨타임
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
포션 제조 : 포션 제조 대기열
이렇게 CREATE 버튼을 누르면 해당 포션이 밑에 대기열에 올라오게 되며, 생성이 다 될때까지의 게이지를 보여주는 슬라이더가 활성화된다. 포션 생성이 완료되면 포션 아이템이 생성되고 대기열은 한 자리씩 앞으로 땡겨오게 된다. 이미 포션 제작 중인게 있으면 생성할 포션은 대기열 뒤에 자리잡게 된다. 그냥 Queue 큐와 똑같은 원리!
🚀 포션 제조 대기열 UI
슬라이더
포션이 제작 중일 때의 쿨타임을 슬라이더로 표시할 것이다. 슬라이더 UI 처음 만들 떄 생기는 동그란 손잡이 부분이 Handle Slide Area
인데 이 부분은 미관을 위해 없애주었다.
슬라이더의 value
가 100% 채워져도 오른쪽에 이렇게 공간이 남는 이유는 Fill Area
의 Right 패딩값 때문이다. 슬라이더가 채워지는 그 오브젝트는 Fill Area
의 자식인 Fill
인데, Fill Area
의 Rect Transform 에서 Right 패딩값이 커서 생기는 문제였다.
Fill Area
의 Right 패딩 값을 줄여주니 해결 됨.
슬라이더는 포션 제조중일 때만 활성화할 것이라서 평소엔 비활성화 해둔다.
대기열 큐
- 빈 오브젝트
Queue
- 대기열 큐의 4 개의 자리를 의미하는 각각의 4 개 이미지
슬라이더와 4 개의 대기열 이미지는 평소 비활성화. 포션이 제조 중일 때만 활성화할 것이다.
🚀 포션 제조 대기열 동작시키기
📜ArchemyTable
private bool isOpen = false;
private bool isCrafting = false; // 아이템의 제작 시작 여부 (ture면 제작 中)
private Queue<ArchemyItem> archemyItemQueue = new Queue<ArchemyItem>(); // 연금 테이블 아이템 제작 대기열 큐
private ArchemyItem currentCraftingItem; // 현재 제작 중인 연금 아이템(큐의 첫 번째 원소)
private float craftingTime; // 제작 시간
private float currentCraftingTime; // 실제 갱신되는 시간. craftingTime 가 되기까지 갱신됨
[SerializeField] private Slider slider_gauge; // 슬라이더 게이지
[SerializeField] private GameObject go_Liquid; // 동작 시키면 액체 등장(포션 제작 중이면 등장)
[SerializeField] private Image[] image_CraftingItems; // 대기열 슬롯에 있는 아이템 이미지들
[SerializeField] private Transform tf_BaseUI; // 연금 아이템 베이스 UI
[SerializeField] private Transform tf_PotionAppearPos; // 포션이 생성될 위치
- 실제 대기 큐 👉 크기 3 을 넘지 않게 할 것이다.
- UI 이미지로서의 대기 큐 👉 4 개의 이미지를 사용하지만 가장 왼쪽 하나는 현재 제작 중인 포션의 이미지를 나타낼 것이고 나머지 3 개는 현재 큐의 원소로 있는 대기 중인 포션들로 쓸 것이다.
go_Liquid
의 경우 이것이다. 포션이 제조중이면 연금 테이블 위에 있는 이 go_Liquid
액체 오브젝트가 활성화 되게 할 것이고 포션 제조 중이 아니면 비활성화 해 빈 액체인 상태로 보이게 하는 효과를 줄 것이다. 평소엔 비활성화.
void Update()
{
if (!isFinish())
{
Crafting();
}
if (isOpen)
if (Input.GetKeyDown(KeyCode.Escape))
CloseWindow();
}
private bool isFinish()
{
if(archemyItemQueue.Count == 0 && !isCrafting)
{
go_Liquid.SetActive(false);
slider_gauge.gameObject.SetActive(false);
return true;
}
else
{
go_Liquid.SetActive(true);
slider_gauge.gameObject.SetActive(true);
return false;
}
}
private void Crafting()
{
if (!isCrafting && archemyItemQueue.Count != 0)
DequeueItem();
if (isCrafting) // DequeItem 을 통해 isCrafting = true 즉 제작 중이된 후
{
currentCraftingTime += Time.deltaTime;
slider_gauge.value = currentCraftingTime;
if (currentCraftingTime >= craftingTime)
ProductionComplete();
}
}
private void DequeueItem()
{
isCrafting = true; // 대기열에서 뺏으니 제작 시작
currentCraftingItem = archemyItemQueue.Dequeue();
craftingTime = currentCraftingItem.itemCraftingTime;
currentCraftingTime = 0;
slider_gauge.maxValue = craftingTime;
CraftingImageChange();
}
private void CraftingImageChange()
{
image_CraftingItems[0].gameObject.SetActive(true); // 첫 번재 대기열 이미지는 무조건 보여져야 함. 제작 중이니까
for (int i = 0; i < archemyItemQueue.Count + 1; i++) // 이미지는 그대로 남아있으니까 +1 (위에서 Dequeue 하기 전 상태)
{
image_CraftingItems[i].sprite = image_CraftingItems[i + 1].sprite; // 이미지 하나씩 땡겨오기
if (i + 1 == archemyItemQueue.Count + 1)
image_CraftingItems[i + 1].gameObject.SetActive(false);
}
}
public void Buttonclick(int _buttonNum)
{
if (archemyItemQueue.Count < 3)
{
archemyItemQueue.Enqueue(archemyItems[_buttonNum]);
image_CraftingItems[archemyItemQueue.Count].gameObject.SetActive(true);
image_CraftingItems[archemyItemQueue.Count].sprite = archemyItems[_buttonNum].itemImage;
}
}
private void ProductionComplete()
{
isCrafting = false;
image_CraftingItems[0].gameObject.SetActive(false);
Instantiate(currentCraftingItem.go_ItemPrefab, tf_PotionAppearPos.position, Quaternion.identity);
}
public bool GetIsOpen()
{
return isOpen;
}
- Update
!isFinish()
제조해야할 포션이 하나라도 있을 때만Crafting()
포션을 제작한다.
- isFinish
- 포션 제조 대기열 큐에 아무것도 없고 현재 제작중도 아니라면 더 이상 포션 제조 안해도 되므로, 즉 연금테이블이 할 일은 다 끝났으므로
ture
를 리턴한다. 액체도 비활하고 슬라이더도 비활하고! - 포션 제조 대기열 큐에 하나라도 있거나 현재 제작중이라면 포션 제조를 해야 한다.
false
를 리턴해서 업데이트 문에서 Crafting() 될 수 있도록 한다. 액체와 슬라이더를 활성화한다.
- 포션 제조 대기열 큐에 아무것도 없고 현재 제작중도 아니라면 더 이상 포션 제조 안해도 되므로, 즉 연금테이블이 할 일은 다 끝났으므로
- Crafting
- 현재 제조 중인건 아닌데 and 대기열 큐에 있는 포션 갯수가 0 이 아니라면
- 👉 다음 포션 아이템을 제조해야 하므로 대기 큐에 있는 포션들 한 칸씩 땡겨야 한다. DequeueItem()
- 현재 제조 중이라면
- (DequeueItem() 끝나서 한 칸씩 땡겨오기 완료 하고 지금 제작해야 할 포션의 제작 시간도
craftingTime
에 저장이 된 상태고isCrafting = true
된 후임) - 👉 제조 시작! 포션 쿨타임 돌려야 함
currentCraftingTime
을 1 프레임씩 업데이트. 시간 갱신.- 슬라이더 게이지 업데이트
- 시간이
craftingTime
에 다다랐다면 포션 아이템 오브젝트를 생성해야 한다. ProductionComplete()
- (DequeueItem() 끝나서 한 칸씩 땡겨오기 완료 하고 지금 제작해야 할 포션의 제작 시간도
- 현재 제조 중인건 아닌데 and 대기열 큐에 있는 포션 갯수가 0 이 아니라면
- DequeueItem
- 다음 포션 아이템을 제조해야 하므로 대기 큐에 있는 포션들 한 칸씩 땡긴다. 그리고나서 이제 제작해야할 포션 아이템 데이터를 받아 온다.
isCrafting
= true (이제 제작 시작)- 이제 제작해야할 포션 아이템의 데이터를 받아온다.
currentCraftingItem
이제 제작 해야할 아이템 (대기 큐에서 Dequeue())craftingTime
이제 제작 해야할 아이템의 총 쿨타임currentCraftingTime
이제 시간 갱신해야 하므로 0 으로 초기화- 슬라이더의 최대 값은
craftingTime
- 대기열 큐의 이미지를 한 칸씩 땡겨와야 한다.
- 👉 CraftingImageChange
- 다음 포션 아이템을 제조해야 하므로 대기 큐에 있는 포션들 한 칸씩 땡긴다. 그리고나서 이제 제작해야할 포션 아이템 데이터를 받아 온다.
- CraftingImageChange
- 대기열 큐의 이미지를 한 칸씩 앞으로 땡겨 온다. 현재 대기열에 있는 아이템이 2 개라면 대기열 이미지 4개 중 3개만 활성화 해야 한다.(나머지 하나는 현재 제작중인 이미지)
- 첫 번째 이미지는 무조건 보여져야 한다. 제작 중인 이미지를 나타내므로!
- C# 상에서의 대기열 Queue 에선 아이템을 뺏지만 UI 이미지 상으로는 아직 안뺏다! 그러므로 for문을
archemyItemQueue.Count + 1
전 까지 돌아야 한다. 그러면서 이미지 하나씩 한칸 앞으로 땡겨오기 - Dequeue 되어 1 줄은 맨 뒷자리 이미지는 비활성화 한다.
- 대기열 큐의 이미지를 한 칸씩 앞으로 땡겨 온다. 현재 대기열에 있는 아이템이 2 개라면 대기열 이미지 4개 중 3개만 활성화 해야 한다.(나머지 하나는 현재 제작중인 이미지)
- Buttonclick
- 포션 아이템은 대기열 큐 크기가 3 미만인 경우에만 생성되야 한다. 따라서 3 을 넘으면 CREATE 버튼을 눌러도 아무 반응이 없도록!!
- 대기열 큐 크기가 3 미만이면 큐에 해당 포션 아이템을 삽입한다.
- 삽입한 아이템이 자리하는 그 자리의 이미지를 활성화하고 Sprite 도 할당해준다.
- 포션 아이템은 대기열 큐 크기가 3 미만인 경우에만 생성되야 한다. 따라서 3 을 넘으면 CREATE 버튼을 눌러도 아무 반응이 없도록!!
- ProductionComplete
- 제작이 끝났으니 포션 프리팹으로 포션 아이템을 생성한다.
isCrafting
= false- 첫 번째 이미지 비활성화 (제작 중임을 나타내는 이미지)
- 포션 생성
- 제작이 끝났으니 포션 프리팹으로 포션 아이템을 생성한다.
- 빨간 포션의 제작 시간은 4 초
- 4 개의 이미지를
iamge_CraftingItems
에 할당
📜ActionController
private void ArchemyInfoAppear()
{
if (!hitInfo.transform.GetComponent<ArchemyTable>().GetIsOpen())
{
Reset();
lookArchemyTable = true;
actionText.gameObject.SetActive(true);
actionText.text = "연금 테이블 조작 " + "<color=yellow>" + "(E)" + "</color>";
}
}
액션 텍스트가 계속 보여서 포션 제작 UI 가 떠 있을 땐 액션텍스트가 보이지 않도록 수정
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기