using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class UIStage : MonoBehaviour
{
public enum eState
{
Lock, Doing, Complete
}
public TMP_Text[] arrTxtStageNum;
public GameObject[] arrStateGo; //0: lock, 1: doing, 2: complete
public eState state;
public int starCount = 0;
[SerializeField]
private GameObject[] starOn;
public void Init(int stageNum)
{
foreach (var tmpText in this.arrTxtStageNum)
{
tmpText.text = stageNum.ToString();
}
this.ChangeState(eState.Lock);
}
public void ChangeState(eState state)
{
this.InActiveAll();
this.state = state;
int index = (int)this.state;
this.arrStateGo[index].SetActive(true);
}
private void InActiveAll()
{
foreach (var go in this.arrStateGo)
{
go.SetActive(false);
}
}
public void UpdateStars()
{
if (state == eState.Doing)
{
ChangeState(eState.Complete);
starCount = 1;
for(int i = 0; i < 3; i++)
{
starOn[i].SetActive(false);
}
starOn[starCount-1].SetActive(true);
return;
}
if (state == eState.Complete && starCount < 3)
{
starCount++;
starOn[starCount - 1].SetActive(true);
}
}
}
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using Newtonsoft.Json;
public class UIStageController : MonoBehaviour
{
[SerializeField]
private UIStage[] arrUIStages;
private List<StageData> stageDatas = new List<StageData>();
private void Start()
{
LoadStageData();
InitStages();
}
private void LoadStageData()
{
string path = Path.Combine(Application.persistentDataPath, "stage_info.json");
if (File.Exists(path))
{
string json = File.ReadAllText(path);
stageDatas = JsonConvert.DeserializeObject<List<StageData>>(json);
}
else
{
Debug.LogError("stage_info.json을 찾을 수 없습니다!");
}
}
private void InitStages()
{
for (int i = 0; i < stageDatas.Count && i < arrUIStages.Length; i++)
{
arrUIStages[i].Init(stageDatas[i].stageNum);
arrUIStages[i].ChangeState((UIStage.eState)stageDatas[i].state);
int currentIndex = i; //클로저
// 클릭을 위한 EventTrigger 설정
EventTrigger trigger = arrUIStages[i].gameObject.GetComponent<EventTrigger>();
if (trigger == null)
{
trigger = arrUIStages[i].gameObject.AddComponent<EventTrigger>();
}
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerClick;
entry.callback.AddListener((data) => { OnStageClicked((PointerEventData)data, arrUIStages[currentIndex]); });
trigger.triggers.Add(entry);
}
}
private void OnStageClicked(PointerEventData data, UIStage uiStage)
{
if (uiStage.state == UIStage.eState.Lock) // Lock
return;
// 현재 클릭한 스테이지의 인덱스
int clickedStageIndex = System.Array.IndexOf(arrUIStages, uiStage);
// 첫 번째 스테이지가 아니라면, 바로 전 스테이지의 상태를 확인
if (clickedStageIndex > 0 && arrUIStages[clickedStageIndex - 1].state != UIStage.eState.Complete)
return; // 바로 전 스테이지가 Complete 상태가 아니라면 리턴
uiStage.UpdateStars();
if (uiStage.state == UIStage.eState.Complete && uiStage.starCount == 3 && clickedStageIndex < arrUIStages.Length - 1)
{
arrUIStages[clickedStageIndex + 1].ChangeState(UIStage.eState.Doing);
}
// 현재 스테이지의 상태와 별의 수를 stageDatas에 업데이트
stageDatas[clickedStageIndex].state = (int)uiStage.state;
stageDatas[clickedStageIndex].starCount = uiStage.starCount;
SaveStageData(); // stageDatas의 변경 내용을 stage_info.json파일에 저장
}
private void SaveStageData()
{
string path = Path.Combine(Application.persistentDataPath, "stage_info.json");
string json = JsonConvert.SerializeObject(stageDatas);
File.WriteAllText(path, json);
}
}
15. UIStage 클릭을 통한 이미지 전환과 별(Star_On) 활성화를 위한 스크립트 수정
*** StarCount 확인을 위해 클릭마다 별이 증가하며, 3개가 됬을시에 다음 Stage 오픈
*** Image에 Raycast Target 기능으로 Event Trigger를 통한 클릭 이벤트를 설정할때, Image 또는 자식 객체에 Button 컴포넌트가 있다면 Event Trigger가 작동하지 않는다.
'KDT > 유니티 심화' 카테고리의 다른 글
LearnUGUI 연습 (6. ShopChest 정적 스크롤뷰 만들기) (0) | 2023.09.09 |
---|---|
LearnUGUI 연습 (5. UIPageStage 단계 별 적용하기) (0) | 2023.09.08 |
LearnUGUI 연습 (3. Stage 만들기) (0) | 2023.09.06 |
LearnUGUI 연습 (2. 버튼 만들기) (0) | 2023.09.05 |
LearnUGUI 연습 (1. 프로젝트 세팅하기) (0) | 2023.09.04 |