Files
OCTOPUS_TWIN-Demo/Assets/Scripts/UI/ProjectListController.cs
2026-02-08 23:07:03 +09:00

294 lines
10 KiB
C#

using ChunilENG;
using Cysharp.Threading.Tasks;
using HyundaiWIA;
using KEPCO;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
namespace OCTOPUS_TWIN
{
public class ProjectListController : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private ProjectItemView itemPrefab; // 복제할 원본 버튼 프리팹
[SerializeField] private Transform contentParent; // 버튼들이 생성될 위치
[SerializeField] private List<ProjectData> projectDataList;
[Header("UI References")]
[SerializeField] private ToastPopup toastPopup; // 만들어둔 토스트 팝업 연결
[Header("References")]
[SerializeField] private GameObject homeRoot; // 홈 화면
[Tooltip("Chunil, KEPCO 등의 SceneMain들이 자식으로 있는 부모 오브젝트")]
[SerializeField] private Transform sceneMainRoot;
[Tooltip("Chunil, KEPCO 등의 모델들이 자식으로 있는 부모 오브젝트")]
[SerializeField] private Transform modelRoot;
[Tooltip("Chunil, KEPCO 등의 StaticCanvas들이 자식으로 있는 부모 오브젝트")]
[SerializeField] private Transform staticCanvasRoot;
[Tooltip("Chunil, KEPCO 등의 PopupCanvas들이 자식으로 있는 부모 오브젝트")]
[SerializeField] private Transform popupCanvasRoot;
[SerializeField] private Transform labelCanvasRoot;
[SerializeField] private Transform modalCanvasRoot;
public ProjectData currentProjectData;
[SerializeField]
private Volume volume;
private List<Object> prevSceneAssets = new();
private void Start()
{
GenerateList();
if (sceneMainRoot != null)
{
foreach (Transform child in sceneMainRoot)
{
child.gameObject.SetActive(false);
}
}
if (modelRoot != null)
{
foreach (Transform child in modelRoot)
{
child.gameObject.SetActive(false);
}
}
if (staticCanvasRoot != null)
{
foreach (Transform child in staticCanvasRoot)
{
child.gameObject.SetActive(false);
}
}
if (popupCanvasRoot != null)
{
foreach (Transform child in popupCanvasRoot)
{
child.gameObject.SetActive(false);
}
}
if (labelCanvasRoot != null)
{
foreach (Transform child in labelCanvasRoot)
{
child.gameObject.SetActive(false);
}
}
if (modalCanvasRoot != null)
{
foreach (Transform child in modalCanvasRoot)
{
child.gameObject.SetActive(false);
}
}
if (volume == null)
{
volume = FindAnyObjectByType<Volume>();
}
}
private void GenerateList()
{
// 기존에 혹시 테스트로 놔둔 버튼이 있다면 지우기
foreach (Transform child in contentParent)
{
Destroy(child.gameObject);
}
// 데이터 개수만큼 버튼 생성
foreach (var data in projectDataList)
{
// 프리팹 복제
ProjectItemView newItem = Instantiate(itemPrefab, contentParent);
// 데이터 주입 및 클릭 이벤트 연결
if (data.isLocked)
{
// 클릭 불가한 프로젝트 버튼
newItem.Setup(data, () =>
{
if (toastPopup != null) toastPopup.gameObject.SetActive(true);
});
}
else
{
newItem.Setup(data, OnProjectClicked); // 클릭 가능한 프로젝트 버튼
}
}
}
// 버튼이 클릭되었을 때 실행될 함수
private void OnProjectClicked(ProjectData selectedData)
{
//if (modelRoot == null)
//{
// Debug.LogError("Model Root가 연결되지 않았습니다");
// return;
//}
// 로딩 매니저 호출
if (UILoading.Instance != null)
{
UILoading.Instance.LoadProject(() =>
{
// 홈 화면 끄기
if (homeRoot != null) homeRoot.SetActive(false);
// 씬에 있는 오브젝트 프리팹 on/off
SwitchModel(selectedData);
});
}
else
{
// 로딩 시스템 없을 때 바로 전환
if (homeRoot != null) homeRoot.SetActive(false);
SwitchModel(selectedData);
}
}
// 실제 모델을 교체하는 함수
private async UniTask SwitchModel(ProjectData data)
{
// 기존에 켜져 있던 모델들 모두 끄기 (초기화)
if (currentProjectData != null)
{
//SetActiveProgjectDataObject(modelRoot, currentProjectData.modelPrefab.name, false);
SetActiveProgjectDataObject(staticCanvasRoot, currentProjectData.staticCanvasPrefab.name, false);
SetActiveProgjectDataObject(popupCanvasRoot, currentProjectData.popupCanvasPrefab.name, false);
SetActiveProgjectDataObject(sceneMainRoot, currentProjectData.sceneMain.name, false);
SetActiveProgjectDataObject(labelCanvasRoot, currentProjectData.labelCanvas.name, false);
}
await LoadActiveProjectScene(data);
currentProjectData = data;
//SetActiveProgjectDataObject(modelRoot, currentProjectData.modelPrefab.name, true);
SetActiveProgjectDataObject(staticCanvasRoot, currentProjectData.staticCanvasPrefab.name, true);
SetActiveProgjectDataObject(sceneMainRoot, currentProjectData.sceneMain.name, true);
SetActiveProgjectDataObject(popupCanvasRoot, currentProjectData.popupCanvasPrefab.name, true);
SetActiveProgjectDataObject(labelCanvasRoot, currentProjectData.labelCanvas.name, true);
switch (currentProjectData.projectName)
{
case "Chunil":
ChunilENGSceneMain.Instance.InitSceneMain();
break;
case "KEPCO":
KEPCOSceneMain.Instance.InitSceneMain();
break;
case "HyundaiWIA":
HyundaiWIASceneMain.Instance.InitSceneMain();
break;
}
}
private async UniTask LoadActiveProjectScene(ProjectData data)
{
//이전 씬 UnLoad
if (prevSceneAssets.Count != 0)
{
foreach (var unloadAsset in prevSceneAssets)
{
await SceneManager.UnloadSceneAsync(unloadAsset.name);
}
prevSceneAssets.Clear();
}
foreach (var scene in data.sceneAssets)
{
//로딩바 만들어줘야함
AsyncOperation t = SceneManager.LoadSceneAsync(scene.name, LoadSceneMode.Additive);
while (!t.isDone)
{
float progress = Mathf.Clamp01(t.progress / 0.9f);
//if (progressBar != null)
//{
// progressBar.value = progress;
//}
//if (percentageText != null)
//{
// percentageText.text = Mathf.RoundToInt(progress * 100f) + "%";
//}
//// Check if the loading is nearly complete (at 90%)
//if (operation.progress >= 0.9f)
//{
// // This is the final 10% where the scene is ready but not yet active
// // You can add a manual delay or wait for a user input here
// // For a smooth transition to 100% and activation:
// progressBar.value = 1f;
// if (percentageText != null)
// {
// percentageText.text = "100%";
// }
// // Allow the scene to activate, completing the loading process
// t.allowSceneActivation = true;
//}
prevSceneAssets.Add(scene);
await UniTask.NextFrame();
}
}
}
private void SetActiveProgjectDataObject(Transform parent, string targetName, bool isOn)
{
Transform targetModel = FindInChildren(parent, targetName);
if (targetModel != null)
{
targetModel.gameObject.SetActive(isOn);
}
else
{
Debug.LogError($"'{parent.name}' 아래에서 '{targetName}' 오브젝트를 찾을 수 없습니다. 이름을 확인해주세요.");
}
}
private Transform FindInChildren(Transform parent, string name)
{
foreach (Transform child in parent.GetComponentsInChildren<Transform>(true))
{
if (child.name == name)
return child;
}
return null;
}
public void ReturnHome()
{
if (prevSceneAssets.Count > 0)
{
foreach (var scene in prevSceneAssets)
{
SceneManager.UnloadSceneAsync(scene.name);
}
}
// 모델 다 끄기
if (modelRoot != null)
{
foreach (Transform child in modelRoot)
{
child.gameObject.SetActive(false);
}
}
// 홈 화면 켜기
if (homeRoot != null) homeRoot.SetActive(true);
}
}
}