알람 수정 중
This commit is contained in:
@@ -44,7 +44,8 @@ namespace UVC.Factory.Alarm
|
||||
//알람 데이터가 AGV와 관련 없는것이 많아서, AGV 이름을 미리 정의합니다.
|
||||
for (int i = 1; i <= 115; i++)
|
||||
{
|
||||
agvNames.Add($"HFF09CNA8{i.ToString("D3")}");
|
||||
//agvNames.Add($"HFF09CNA8{i.ToString("D3")}");
|
||||
agvNames.Add($"HFF09CNA8061");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,17 +187,35 @@ namespace UVC.Factory.Alarm
|
||||
return;
|
||||
}
|
||||
|
||||
// 없으면 새로 생성
|
||||
FactoryObject? targetObject = dataManager!.FindByName(data.GetString("TRANSPORT_EQP_ID")!);
|
||||
Debug.Log($"AlarmManager {targetObject==null} {data.Id}, {data.GetString("TRANSPORT_EQP_ID")}");
|
||||
if (targetObject != null)
|
||||
|
||||
string? eqpId = data.GetString("TRANSPORT_EQP_ID");
|
||||
if (eqpId == null) return;
|
||||
|
||||
FactoryObject? targetObject = dataManager!.FindByName(eqpId);
|
||||
Debug.Log($"AlarmManager {targetObject==null} {data.Id}, {eqpId}");
|
||||
if (targetObject == null) return;
|
||||
|
||||
if (activeAlarmUIs.ContainsKey(eqpId))
|
||||
{
|
||||
if(activeAlarmUIs[eqpId].ContainsAlarm(data))
|
||||
{
|
||||
activeAlarmUIs[eqpId].UpdateAlarm(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeAlarmUIs[eqpId].AddAlarm(data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 없으면 새로 생성
|
||||
GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // 매니저 하위에 생성
|
||||
AlarmUIController newUiController = newUIObject.GetComponent<AlarmUIController>();
|
||||
newUiController.Initialize(targetObject, data);
|
||||
|
||||
activeAlarmUIs.Add(data.Id!, newUiController);
|
||||
activeAlarmUIs.Add(eqpId, newUiController);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -207,11 +226,22 @@ namespace UVC.Factory.Alarm
|
||||
Debug.LogError($"Modify Alarm Received No data. {data}");
|
||||
return;
|
||||
}
|
||||
string? eqpId = data.GetString("TRANSPORT_EQP_ID");
|
||||
if (eqpId == null) return;
|
||||
|
||||
// 이미 해당 설비에 알람 UI가 떠 있는지 확인
|
||||
if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController))
|
||||
if (activeAlarmUIs.TryGetValue(eqpId, out AlarmUIController uiController))
|
||||
{
|
||||
// 있으면 기존 UI에 알람 정보만 추가
|
||||
uiController.UpdateAlarm(data);
|
||||
// 있으면 기존 UI에 알람 정보 업데이트
|
||||
if (uiController.ContainsAlarm(data))
|
||||
{
|
||||
uiController.UpdateAlarm(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 없으면 새로 추가
|
||||
uiController.AddAlarm(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,13 +252,22 @@ namespace UVC.Factory.Alarm
|
||||
Debug.LogError($"Clear Alarm Received No data. {data}");
|
||||
return;
|
||||
}
|
||||
if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController))
|
||||
|
||||
string? eqpId = data.GetString("TRANSPORT_EQP_ID");
|
||||
if (eqpId == null) return;
|
||||
|
||||
if (activeAlarmUIs.TryGetValue(eqpId, out AlarmUIController uiController))
|
||||
{
|
||||
uiController.RemoveAlarm(data);
|
||||
if (uiController.GetAlarmCount() == 0)
|
||||
// 있으면 기존 UI에 알람 정보 업데이트
|
||||
if (uiController.ContainsAlarm(data))
|
||||
{
|
||||
activeAlarmUIs.Remove(data.Id!);
|
||||
Destroy(uiController.gameObject);
|
||||
uiController.RemoveAlarm(data);
|
||||
|
||||
if (uiController.GetAlarmCount() == 0)
|
||||
{
|
||||
activeAlarmUIs.Remove(data.Id!);
|
||||
Destroy(uiController.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using UVC.Util;
|
||||
|
||||
namespace UVC.Factory.Alarm
|
||||
{
|
||||
public class SingleAlarmIcon : MonoBehaviour
|
||||
public class AlarmSingleIcon : MonoBehaviour
|
||||
{
|
||||
|
||||
[Tooltip("알람 내용을 표시하는 텍스트입니다.")]
|
||||
@@ -18,12 +18,12 @@ namespace UVC.Factory.Alarm
|
||||
[Tooltip("확장된 알람 뷰입니다. 개별 알람 아이콘을 표시합니다.")]
|
||||
[SerializeField] private GameObject expandedView;
|
||||
[Tooltip("개별 알람 아이콘 프리팹입니다. 이 프리팹은 개별 알람 정보를 표시하는 UI 요소를 포함해야 합니다.")]
|
||||
[SerializeField] private GameObject singleAlarmIconPrefab; // 개별 알람 아이콘
|
||||
[SerializeField] private GameObject alarmSingleIconPrefab; // 개별 알람 아이콘
|
||||
|
||||
private Transform targetObject;
|
||||
private List<DataObject> alarms = new List<DataObject>();
|
||||
private bool isExpanded = false;
|
||||
private SingleAlarmIcon singleAlarmIcon1 = null;
|
||||
private AlarmSingleIcon singleAlarmIcon1 = null;
|
||||
|
||||
private RectTransform rectTransform;
|
||||
private Canvas mainCanvas;
|
||||
@@ -99,6 +99,11 @@ namespace UVC.Factory.Alarm
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsAlarm(DataObject alarm)
|
||||
{
|
||||
return alarms.Exists(a => a.Id == alarm.Id);
|
||||
}
|
||||
|
||||
public void AddAlarm(DataObject alarm)
|
||||
{
|
||||
alarms.Add(alarm);
|
||||
@@ -156,7 +161,7 @@ namespace UVC.Factory.Alarm
|
||||
// 여기에 단일 알람 아이콘을 보여주는 로직 추가
|
||||
if (singleAlarmIcon1 == null)
|
||||
{
|
||||
singleAlarmIcon1 = Instantiate(singleAlarmIconPrefab, transform).GetComponent<SingleAlarmIcon>();
|
||||
singleAlarmIcon1 = Instantiate(alarmSingleIconPrefab, transform).GetComponent<AlarmSingleIcon>();
|
||||
}
|
||||
singleAlarmIcon1.gameObject.SetActive(true);
|
||||
singleAlarmIcon1.SetData(alarms[0], targetObject);
|
||||
@@ -205,16 +210,17 @@ namespace UVC.Factory.Alarm
|
||||
}
|
||||
|
||||
// 원형으로 아이콘 배치
|
||||
float radius = 100.0f; // Canvas 좌표계에 맞는 반지름 값
|
||||
float radius = (alarms.Count - 1) * 20.0f; // Canvas 좌표계에 맞는 반지름 값
|
||||
|
||||
for (int i = 0; i < alarms.Count; i++)
|
||||
{
|
||||
float angle = i * Mathf.PI * 2f / alarms.Count;
|
||||
Vector3 pos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0) * radius;
|
||||
|
||||
GameObject iconObj = Instantiate(singleAlarmIconPrefab, expandedView.transform);
|
||||
GameObject iconObj = Instantiate(alarmSingleIconPrefab, expandedView.transform);
|
||||
iconObj.transform.localPosition = pos;
|
||||
// iconObj의 SingleAlarmIcon 스크립트에 알람 데이터 전달
|
||||
iconObj.GetComponent<SingleAlarmIcon>().SetData(alarms[i], targetObject);
|
||||
// iconObj의 AlarmSingleIcon 스크립트에 알람 데이터 전달
|
||||
iconObj.GetComponent<AlarmSingleIcon>().SetData(alarms[i], targetObject);
|
||||
}
|
||||
|
||||
//AnimateUISpace(0f); // 간격을 0으로 애니메이션
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8822a5b71db85f64483ede945af84867
|
||||
guid: ef255ae14c2a7a647ab9e652029763b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using UVC.Core;
|
||||
|
||||
namespace UVC.Util
|
||||
namespace UVC.Factory
|
||||
{
|
||||
/// <summary>
|
||||
/// 마우스 입력에 따라 카메라를 이동, 회전, 줌하는 컨트롤러입니다.
|
||||
@@ -116,15 +115,15 @@ namespace UVC.Util
|
||||
if (prevTransform != null && (prevTransform.position != transform.position || prevTransform.rotation != transform.rotation))
|
||||
{
|
||||
OnCameraChanged?.Invoke(transform);
|
||||
if(prevTransform.position != transform.position)
|
||||
if (prevTransform.position != transform.position)
|
||||
{
|
||||
OnCameraPositionChanged?.Invoke(transform.position);
|
||||
}
|
||||
if(prevTransform.rotation != transform.rotation)
|
||||
if (prevTransform.rotation != transform.rotation)
|
||||
{
|
||||
OnCameraRotionChanged?.Invoke(transform.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
prevTransform = transform; // 현재 카메라 위치 저장
|
||||
}
|
||||
|
||||
@@ -312,7 +311,7 @@ namespace UVC.Util
|
||||
float currentPitch = transform.eulerAngles.x;
|
||||
if (currentPitch > 180f) currentPitch -= 360f;
|
||||
if (currentPitch < minPitch || currentPitch > maxPitch) return;
|
||||
|
||||
|
||||
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||||
Vector3 zoomTarget;
|
||||
|
||||
@@ -364,7 +363,7 @@ namespace UVC.Util
|
||||
{
|
||||
position.y = maxCameraY; // 최대 높이 제한
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 카메라가 바라볼 대상의 중심점
|
||||
Vector3 targetPosition = equipmentPosition;
|
||||
@@ -400,11 +399,11 @@ namespace UVC.Util
|
||||
StopFocusCoroutine();
|
||||
|
||||
Vector3 position = equipmentPosition;
|
||||
if(position.y < minCameraY)
|
||||
if (position.y < minCameraY)
|
||||
{
|
||||
position.y = minCameraY; // 최소 높이 제한
|
||||
}
|
||||
else if(position.y > maxCameraY)
|
||||
else if (position.y > maxCameraY)
|
||||
{
|
||||
position.y = maxCameraY; // 최대 높이 제한
|
||||
}
|
||||
@@ -442,30 +441,30 @@ namespace UVC.Util
|
||||
{
|
||||
// 카메라가 바라볼 대상의 중심점
|
||||
Vector3 targetPosition = targetTransform;
|
||||
|
||||
|
||||
// 시작 위치와 회전 저장
|
||||
Vector3 startPosition = transform.position;
|
||||
Quaternion startRotation = transform.rotation;
|
||||
|
||||
|
||||
// 타겟을 보는 최종 위치와 회전 계산
|
||||
Vector3 directionToTarget = (targetPosition - startPosition).normalized;
|
||||
Vector3 endPosition = targetPosition - directionToTarget * distance;
|
||||
|
||||
|
||||
// 최종 회전값 계산
|
||||
Quaternion endRotation = Quaternion.LookRotation(targetPosition - endPosition);
|
||||
endRotation = ValidateRotation(endRotation); // 회전값 검증 및 수정
|
||||
|
||||
// 이동 시간 계산을 위한 변수
|
||||
float elapsedTime = 0f;
|
||||
|
||||
|
||||
while (elapsedTime < duration)
|
||||
{
|
||||
elapsedTime += Time.deltaTime;
|
||||
float t = Mathf.Clamp01(elapsedTime / duration);
|
||||
|
||||
|
||||
// 부드러운 이동을 위한 Easing 함수 적용
|
||||
float smoothT = EaseInOutCubic(t);
|
||||
|
||||
|
||||
// 위치와 회전 보간
|
||||
transform.position = Vector3.Lerp(startPosition, endPosition, smoothT);
|
||||
transform.rotation = Quaternion.Slerp(startRotation, endRotation, smoothT);
|
||||
@@ -474,11 +473,11 @@ namespace UVC.Util
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
// 정확한 최종 위치와 회전 설정
|
||||
transform.position = endPosition;
|
||||
transform.LookAt(targetPosition);
|
||||
|
||||
|
||||
// 회전 피봇 포인트 업데이트
|
||||
rotationPivot = targetPosition;
|
||||
|
||||
@@ -487,7 +486,7 @@ namespace UVC.Util
|
||||
DispatchEvnet();
|
||||
focusCoroutine = null; // 코루틴 완료 후 참조를 null로 설정
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Cubic ease-in/out 함수로 부드러운 이동 효과를 줍니다.
|
||||
/// </summary>
|
||||
@@ -497,7 +496,7 @@ namespace UVC.Util
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UVC.Data;
|
||||
using UVC.Factory.Modal;
|
||||
using UVC.Object3d;
|
||||
using UVC.UI.Info;
|
||||
|
||||
namespace UVC.Factory.Component
|
||||
{
|
||||
|
||||
8
Assets/Scripts/UVC/Factory/Modal.meta
Normal file
8
Assets/Scripts/UVC/Factory/Modal.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 331531bab0bc0974c89e2eb1560a5043
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,13 +1,13 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UVC.Core;
|
||||
using UVC.UI.Modal;
|
||||
|
||||
namespace UVC.UI.Info
|
||||
namespace UVC.Factory.Modal
|
||||
{
|
||||
/// <summary>
|
||||
/// 3D 객체를 따라다니며 정보를 표시하는 UI 창입니다.
|
||||
@@ -64,7 +64,7 @@ namespace UVC.UI.Info
|
||||
{
|
||||
copyButton.onClick.AddListener(CopyToClipboard);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 처음에는 정보 창을 숨깁니다.
|
||||
if (gameObject.activeSelf)
|
||||
@@ -79,6 +79,7 @@ namespace UVC.UI.Info
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
GUIUtility.systemCopyBuffer = message;
|
||||
Toast.Show("정보가 클립보드에 복사되었습니다.", 2f, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +138,7 @@ namespace UVC.UI.Info
|
||||
rectTransform.localPosition = new Vector3(localPoint.x, localPoint.y, rectTransform.localPosition.z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UI가 항상 보이도록 카메라를 향하게 설정 (World Space Canvas인 경우에만 필요)
|
||||
Canvas parentCanvas = GetComponentInParent<Canvas>();
|
||||
@@ -171,15 +172,17 @@ namespace UVC.UI.Info
|
||||
if (target == null) return;
|
||||
if (text != null)
|
||||
{
|
||||
message = string.Empty;
|
||||
string combinedString = string.Empty;
|
||||
foreach (var kvp in information)
|
||||
{
|
||||
// <indent> 태그를 사용하여 줄바꿈 시에도 정렬이 유지되도록 합니다.
|
||||
combinedString += $"{kvp.Key}<pos=40%><indent=40%>{kvp.Value ?? "null"}</indent>\n";
|
||||
message += $"{kvp.Key}: {kvp.Value ?? "null"}\n"; // 메시지에 추가
|
||||
}
|
||||
combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거
|
||||
message = message.TrimEnd('\n'); // 마지막 줄바꿈 제거
|
||||
text.text = combinedString;
|
||||
message = combinedString;
|
||||
}
|
||||
// size를 text에 맞게 조정합니다.
|
||||
RectTransform? rect = GetComponent<RectTransform>();
|
||||
115
Assets/Scripts/UVC/UI/Modal/Toast.cs
Normal file
115
Assets/Scripts/UVC/UI/Modal/Toast.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UVC.Core;
|
||||
|
||||
namespace UVC.UI.Modal
|
||||
{
|
||||
public class Toast : SingletonApp<Toast>
|
||||
{
|
||||
protected static string prefabPath = "Prefabs/UI/Modal/Toast";
|
||||
protected static GameObject prefab;
|
||||
protected static Toast toast;
|
||||
|
||||
|
||||
public static void Show(string message, float duration = 3f, float fadeInOutTime = 0.25f)
|
||||
{
|
||||
if (prefab == null) prefab = Resources.Load(prefabPath, typeof(GameObject)) as GameObject;
|
||||
if (prefab != null && toast == null)
|
||||
{
|
||||
GameObject go = UnityEngine.Object.Instantiate(prefab);
|
||||
toast = go.GetComponent<Toast>();
|
||||
toast.change(0);
|
||||
}
|
||||
if (toast != null)
|
||||
{
|
||||
toast.gameObject.SetActive(true);
|
||||
var canvass = GameObject.FindObjectsByType<Canvas>(FindObjectsSortMode.None);
|
||||
Canvas canvas = null;
|
||||
foreach (var c in canvass)
|
||||
{
|
||||
if (c.tag == "ModalCanvas")
|
||||
{
|
||||
canvas = c;
|
||||
toast.transform.SetParent(canvas.transform);
|
||||
toast.show(message, duration, fadeInOutTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected CanvasGroup canvasGroup;
|
||||
protected TextMeshProUGUI txt;
|
||||
|
||||
protected void show(string message, float duration = 3, float fadeInOutTime = 0.25f)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(showCoroutine(message, duration, fadeInOutTime));
|
||||
}
|
||||
|
||||
protected IEnumerator showCoroutine(string message, float duration = 3, float fadeInOutTime = 0.25f)
|
||||
{
|
||||
if (txt == null) txt = GetComponentInChildren<TextMeshProUGUI>();
|
||||
fitTextWidth(GetComponent<RectTransform>(), txt, message);
|
||||
|
||||
yield return fadeInOut(fadeInOutTime, true);
|
||||
change(1);
|
||||
float elapsedTime = 0.0f;
|
||||
while (elapsedTime < duration)
|
||||
{
|
||||
elapsedTime += Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return fadeInOut(fadeInOutTime, false);
|
||||
change(0);
|
||||
transform.SetParent(null);
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
protected IEnumerator fadeInOut(float durationTime, bool inOut)
|
||||
{
|
||||
float start = 0.0f;
|
||||
float end = 1.0f;
|
||||
if (!inOut)
|
||||
{
|
||||
start = 1.0f;
|
||||
end = 0.0f;
|
||||
}
|
||||
|
||||
float elapsedTime = 0.0f;
|
||||
|
||||
while (elapsedTime < durationTime)
|
||||
{
|
||||
float alpha = Mathf.Lerp(start, end, elapsedTime / durationTime);
|
||||
|
||||
change(alpha);
|
||||
|
||||
elapsedTime += Time.deltaTime;
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void change(float alpha)
|
||||
{
|
||||
if (canvasGroup == null) canvasGroup = GetComponent<CanvasGroup>();
|
||||
canvasGroup.alpha = alpha;
|
||||
}
|
||||
|
||||
private void fitTextWidth(RectTransform rect, TextMeshProUGUI text, string textValue)
|
||||
{
|
||||
text.text = textValue;
|
||||
|
||||
Vector2 rectSize = rect.sizeDelta;
|
||||
rectSize.x = text.preferredWidth + 20;
|
||||
rect.sizeDelta = rectSize;
|
||||
rect.anchoredPosition = new Vector2(0, rectSize.y + 10);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UVC/UI/Modal/Toast.cs.meta
Normal file
2
Assets/Scripts/UVC/UI/Modal/Toast.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d007f3f774d241a44a69d7349dd7c464
|
||||
Reference in New Issue
Block a user