189 lines
6.1 KiB
C#
189 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// VR 환경에서 로봇 프로그램의 상세 정보(스텝 리스트, 속도 등)를 표시하고 제어하는 뷰(View) 클래스
|
|
/// 프로그램 실행/정지, 리셋, 속도 조절 등의 사용자 입력을 받아 ProgramPresenter로 전달
|
|
/// </summary>
|
|
|
|
public class ProgramInfoView : MonoBehaviour
|
|
{
|
|
// --- 프로그램 정보 패널 ---
|
|
|
|
/// <summary>
|
|
/// 정보 패널이 활성화될 때 부착될 VR 컨트롤러(왼손)의 Transform
|
|
/// </summary>
|
|
[SerializeField] private Transform leftControllerTransform;
|
|
[SerializeField] private GameObject infoPanel; // 실제 켜고 끌 정보 패널의 최상위 게임 오브젝트
|
|
public InputActionReference showInfoPanel; // 패널을 토글(켜기/끄기)하는 입력 액션
|
|
public InputActionReference hideInfoPanel; // 패널을 강제로 숨기는 입력 액션
|
|
public InputActionReference[] playProgram; // 프로그램을 재생/정지하는 입력 액션 (예: A 또는 B버튼)
|
|
// 토글 상태 관리를 위한 플래그 변수들
|
|
private bool isPressingX = false;
|
|
private bool isPressingAorB = false;
|
|
|
|
[SerializeField] public TextMeshProUGUI jobName; // 작업 이름
|
|
[SerializeField] public TextMeshProUGUI jobSpeed; // 재생 속도
|
|
[SerializeField] private GameObject orderPrefab; // step의 UI 프리팹
|
|
[SerializeField] private GameObject endPrefab; // end의 UI 프리팹
|
|
[SerializeField] private Transform contentParent; // 스텝 UI 아이템들이 생성될 부모 Transform (Scroll View의 Content)
|
|
|
|
// 속도 관련 버튼
|
|
[SerializeField] private Button resetBtn;
|
|
[SerializeField] private Button startBtn;
|
|
[SerializeField] private Button stopBtn;
|
|
[SerializeField] private Button minusBtn;
|
|
[SerializeField] private Button plusBtn;
|
|
|
|
// 생성된 스텝 UI 아이템들을 관리하기 위한 리스트
|
|
private List<StepInfoItem> instantiatedStepItems = new List<StepInfoItem>();
|
|
|
|
// --- 이벤트 정의 (ProgramPresenter로 신호 전달) ---
|
|
public event Action OnResetClicked;
|
|
public event Action OnStartClicked;
|
|
public event Action OnStopClicked;
|
|
public event Action<int> OnMinusClicked;
|
|
public event Action<int> OnPlusClicked;
|
|
|
|
void Start()
|
|
{
|
|
infoPanel.SetActive(false);
|
|
|
|
// 입력 액션 이벤트 연결 (패널 표시/숨김)
|
|
if (showInfoPanel != null)
|
|
{
|
|
showInfoPanel.action.Enable();
|
|
showInfoPanel.action.performed += ShowProgramInfoPanel;
|
|
}
|
|
if (hideInfoPanel != null)
|
|
{
|
|
hideInfoPanel.action.Enable();
|
|
hideInfoPanel.action.performed += HideProgramInfoPanel;
|
|
}
|
|
// 입력 액션 이벤트 연결 (A/B 버튼)
|
|
if (playProgram != null)
|
|
{
|
|
for (int i = 0; i < playProgram.Length; i++)
|
|
{
|
|
playProgram[i].action.Enable();
|
|
playProgram[i].action.performed += PlayProgram;
|
|
}
|
|
}
|
|
|
|
resetBtn.onClick.AddListener(() => OnResetClicked?.Invoke());
|
|
startBtn.onClick.AddListener(() => OnStartClicked?.Invoke());
|
|
stopBtn.onClick.AddListener(() => OnStopClicked?.Invoke());
|
|
minusBtn.onClick.AddListener(() => OnMinusClicked?.Invoke(-1));
|
|
plusBtn.onClick.AddListener(() => OnPlusClicked?.Invoke(1));
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (showInfoPanel != null)
|
|
{
|
|
showInfoPanel.action.performed -= ShowProgramInfoPanel;
|
|
}
|
|
if (hideInfoPanel != null)
|
|
{
|
|
hideInfoPanel.action.performed -= HideProgramInfoPanel;
|
|
}
|
|
if (playProgram != null)
|
|
{
|
|
for (int i = 0; i < playProgram.Length; i++)
|
|
{
|
|
playProgram[i].action.performed -= PlayProgram;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Presenter로부터 데이터를 받아 UI 리스트를 갱신
|
|
/// 기존 목록을 모두 지우고, 새로운 스텝 데이터로 다시 채움
|
|
/// </summary>
|
|
/// <param name="program">로봇 프로그램 정보 (없으면 리턴)</param>
|
|
/// <param name="steps">파싱된 개별 스텝 리스트</param>
|
|
public void UpdateProgramInfo(RobotProgram program, List<RobotMoveStep> steps)
|
|
{
|
|
if (program == null) return;
|
|
|
|
// 기존 리스트 초기화 (UI 오브젝트 삭제)
|
|
foreach (Transform child in contentParent)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
instantiatedStepItems.Clear();
|
|
|
|
// 새 스텝 목록 생성
|
|
if (steps == null) return;
|
|
|
|
foreach (RobotMoveStep step in steps)
|
|
{
|
|
GameObject newPrefab = Instantiate(orderPrefab, contentParent);
|
|
StepInfoItem stepItemUI = newPrefab.GetComponent<StepInfoItem>();
|
|
|
|
if (stepItemUI != null)
|
|
{
|
|
stepItemUI.SetData(step);
|
|
instantiatedStepItems.Add(stepItemUI);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("orderPrefab에 StepInfoItem.cs 스크립트가 없습니다");
|
|
}
|
|
|
|
if (jobSpeed.text == "0%")
|
|
jobSpeed.text = $"{step.Speed}%";
|
|
}
|
|
|
|
// 마지막에 END 추가
|
|
Instantiate(endPrefab, contentParent);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 컨트롤러 입력(X버튼)으로 정보 패널을 켜거나 끔 (토글 방식)
|
|
/// </summary>
|
|
private void ShowProgramInfoPanel(InputAction.CallbackContext obj)
|
|
{
|
|
isPressingX = !isPressingX;
|
|
if (isPressingX)
|
|
{
|
|
infoPanel.transform.SetParent(leftControllerTransform);
|
|
infoPanel.transform.localPosition = new Vector3(0f, 0.2f, 0f);
|
|
infoPanel.transform.localRotation = Quaternion.Euler(0, 180, 0);
|
|
infoPanel.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
infoPanel.SetActive(false);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 컨트롤러 입력으로 정보 패널을 숨김
|
|
/// </summary>
|
|
private void HideProgramInfoPanel(InputAction.CallbackContext obj)
|
|
{
|
|
infoPanel.SetActive(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 컨트롤러 입력(A/B버튼)으로 프로그램을 재생하거나 정지 (토글 방식)
|
|
/// </summary>
|
|
private void PlayProgram(InputAction.CallbackContext obj)
|
|
{
|
|
isPressingAorB = !isPressingAorB;
|
|
if (isPressingAorB)
|
|
{
|
|
OnStartClicked?.Invoke();
|
|
}
|
|
else
|
|
{
|
|
OnStopClicked?.Invoke();
|
|
}
|
|
}
|
|
}
|