alarm 완료

This commit is contained in:
김형인
2025-07-09 00:23:45 +09:00
parent f312fecf0f
commit fdc1d3b8f3
17 changed files with 57 additions and 2671 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 74d9a9294205ec340ba5e232f6081ac0

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +0,0 @@
fileFormatVersion: 2
guid: 052faaac586de48259a63d0c4782560b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
generateWrapperCode: 1
wrapperCodePath:
wrapperClassName:
wrapperCodeNamespace:

View File

@@ -247,7 +247,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 150, y: 150}
m_SizeDelta: {x: 200, y: 150}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &8257610451063185897
MonoBehaviour:
@@ -678,7 +678,7 @@ GameObject:
- component: {fileID: 3374630250525829090}
- component: {fileID: 7240776144344761129}
m_Layer: 5
m_Name: AlarmSigleIconManager
m_Name: AlarmSingleIconManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@@ -714,7 +714,7 @@ MonoBehaviour:
m_GameObject: {fileID: 7314511769243682470}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a651278faa6ca71468e19553474e6bb5, type: 3}
m_Script: {fileID: 11500000, guid: 52c271c8fd8668e48b7f38bf461cf166, type: 3}
m_Name:
m_EditorClassIdentifier:
singleIcon: {fileID: 6655137998972703410}
@@ -859,7 +859,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: new Text
m_text:
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}
m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2}

View File

@@ -414,7 +414,7 @@ GameObject:
m_Component:
- component: {fileID: 4802890858156259540}
- component: {fileID: 7623125061856383678}
- component: {fileID: 9096332282778631911}
- component: {fileID: -348142651904544222}
m_Layer: 5
m_Name: InfoWindow
m_TagString: Untagged
@@ -454,7 +454,7 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4907041631117111019}
m_CullTransparentMesh: 1
--- !u!114 &9096332282778631911
--- !u!114 &-348142651904544222
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}

View File

@@ -174,7 +174,6 @@ GameObject:
- component: {fileID: 88083293}
- component: {fileID: 88083292}
- component: {fileID: 88083291}
- component: {fileID: 88083294}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
@@ -243,31 +242,6 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &88083294
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 88083290}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0b148fe25e99eb48b9724523833bab1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Delegates:
- eventID: 0
callback:
m_PersistentCalls:
m_Calls: []
- eventID: 1
callback:
m_PersistentCalls:
m_Calls: []
- eventID: 4
callback:
m_PersistentCalls:
m_Calls: []
--- !u!1 &330585543
GameObject:
m_ObjectHideFlags: 0
@@ -2185,7 +2159,8 @@ PrefabInstance:
propertyPath: m_Name
value: InfoWindow
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedComponents:
- {fileID: 9096332282778631911, guid: 036e56b4c097fc8409ffced10ff53562, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []

View File

@@ -36,20 +36,13 @@ namespace UVC.Factory.Alarm
public void Show(DataObject data)
{
string combinedString = string.Empty;
// DataObject에 있는 모든 키-값 쌍을 순회합니다.
foreach (var kvp in data)
{
// <indent> 태그를 사용하여 줄바꿈 시에도 정렬이 유지되도록 합니다.
//combinedString += $"{kvp.Key}<pos=40%><indent=40%>{kvp.Value ?? "null"}</indent>\n";
// <margin-right=60%>: 키가 텍스트 컨테이너 너비의 40%를 넘지 않도록 제한합니다.
// 키가 길면 이 지점에서 자동으로 줄바꿈됩니다.
// <pos=40%>: 값의 시작 위치를 40% 지점으로 지정합니다.
// <margin-right=0>: 다음 줄에 영향을 주지 않도록 마진을 리셋합니다.
//combinedString += $"<margin-right=60%>{kvp.Key}</margin-right><pos=40%><margin-right=0>{kvp.Value ?? "null"}</margin-right>\n";
// <width=40%>: 키 텍스트의 너비를 전체의 40%로 제한합니다. 키가 이 너비를 초과하면 자동으로 줄바꿈됩니다.
// <pos=40%>: 값 텍스트의 시작 위치를 40% 지점으로 설정합니다.
combinedString += $"<width=40%>{kvp.Key}</width><pos=40%><valign='top'><indent=40%>{kvp.Value ?? "null"}</indent></valign>\n";
}
combinedString += $"ALARM_TYPE<indent=40%>{data.GetString("ALARM_TYPE") ?? "null"}</indent>\n";
combinedString += $"CODE<indent=40%>{data.GetString("CODE") ?? "null"}</indent>\n";
combinedString += $"MACHINENAME<indent=40%>{data.GetString("MACHINENAME") ?? "null"}</indent>\n";
combinedString += $"MESSAGE<indent=40%>{data.GetString("MESSAGE") ?? "null"}</indent>\n";
combinedString += $"TIMESTAMP<indent=40%>{data.GetString("TIMESTAMP") ?? "null"}</indent>\n";
combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거
detailTxt.text = combinedString;

View File

@@ -39,7 +39,7 @@ namespace UVC.Factory.Alarm
// 현재 클러스터가 펼쳐진 상태인지 여부를 나타내는 플래그입니다.
private bool isExpanded = false;
// 알람이 하나일 때 사용되는 단일 알람 아이콘의 인스턴스입니다.
private AlarmSigleIconManager singleAlarmIcon1 = null;
private AlarmSingleIconManager singleAlarmIcon1 = null;
// UI 위치 계산에 필요한 컴포넌트들입니다.
private RectTransform rectTransform;
@@ -79,8 +79,8 @@ namespace UVC.Factory.Alarm
// 클러스터 아이콘 클릭 시 OnPointerClick 메서드가 호출되도록 이벤트 핸들러를 등록합니다.
clusterView.OnClickHandler += OnPointerClick;
// 카메라 위치가 변경될 때마다 OnCameraPositionChangedHandler가 호출되도록 등록합니다.
FactoryCameraController.Instance.OnCameraPositionChanged += OnCameraPositionChangedHandler;
// 카메라 높이가 변경될 때마다 OnCameraPositionUpChangedHandler가 호출되도록 등록합니다.
FactoryCameraController.Instance.OnCameraPositionUpChanged += OnCameraPositionUpChangedHandler;
}
/// <summary>
@@ -214,7 +214,7 @@ namespace UVC.Factory.Alarm
if (singleAlarmIcon1 == null)
{
// 단일 아이콘이 없으면 새로 생성합니다.
singleAlarmIcon1 = Instantiate(alarmSingleIconManagerPrefab, transform).GetComponent<AlarmSigleIconManager>();
singleAlarmIcon1 = Instantiate(alarmSingleIconManagerPrefab, transform).GetComponent<AlarmSingleIconManager>();
}
singleAlarmIcon1.gameObject.SetActive(true);
singleAlarmIcon1.SetData(alarms[0], targetObject);
@@ -267,10 +267,10 @@ namespace UVC.Factory.Alarm
if (singleAlarmIcon1 != null) singleAlarmIcon1.gameObject.SetActive(false);
// 재활용을 위해 기존에 생성된 아이콘들을 딕셔너리에 저장합니다. (Key: 알람 ID, Value: 아이콘 인스턴스)
var existingIcons = new Dictionary<string, AlarmSigleIconManager>();
var existingIcons = new Dictionary<string, AlarmSingleIconManager>();
foreach (Transform child in expandedView.transform)
{
AlarmSigleIconManager icon = child.GetComponent<AlarmSigleIconManager>();
AlarmSingleIconManager icon = child.GetComponent<AlarmSingleIconManager>();
if (icon != null && icon.Data != null)
{
if (!existingIcons.ContainsKey(icon.Data.Id))
@@ -280,12 +280,12 @@ namespace UVC.Factory.Alarm
}
}
var activeIcons = new List<AlarmSigleIconManager>();
var activeIcons = new List<AlarmSingleIconManager>();
// 현재 알람 목록을 순회하며 아이콘을 업데이트하거나 새로 생성
foreach (var alarmData in alarms)
{
AlarmSigleIconManager icon;
AlarmSingleIconManager icon;
if (existingIcons.TryGetValue(alarmData.Id, out icon))
{
// 기존 아이콘 재사용
@@ -296,7 +296,7 @@ namespace UVC.Factory.Alarm
{
// 새 아이콘 생성
GameObject iconObj = Instantiate(alarmSingleIconManagerPrefab, expandedView.transform);
icon = iconObj.GetComponent<AlarmSigleIconManager>();
icon = iconObj.GetComponent<AlarmSingleIconManager>();
icon.SetData(alarmData, targetObject);
icon.OnDetail = OnDetailSingle;
}
@@ -355,12 +355,12 @@ namespace UVC.Factory.Alarm
/// 개별 알람 아이콘 중 하나가 상세 보기를 활성화했을 때 호출됩니다.
/// </summary>
/// <param name="alarmSingle">상세 보기를 활성화한 아이콘</param>
private void OnDetailSingle(AlarmSigleIconManager alarmSingle)
private void OnDetailSingle(AlarmSingleIconManager alarmSingle)
{
// 다른 모든 아이콘들의 상세 보기는 숨깁니다.
foreach (Transform child in expandedView.transform)
{
AlarmSigleIconManager existingIcon = child.GetComponent<AlarmSigleIconManager>();
AlarmSingleIconManager existingIcon = child.GetComponent<AlarmSingleIconManager>();
if (existingIcon != null)
{
if (existingIcon != alarmSingle) existingIcon.HideDetail(); // 다른 아이콘은 숨김
@@ -377,7 +377,7 @@ namespace UVC.Factory.Alarm
// 모든 개별 아이콘의 상세 보기를 숨깁니다.
foreach (Transform child in expandedView.transform)
{
AlarmSigleIconManager existingIcon = child.GetComponent<AlarmSigleIconManager>();
AlarmSingleIconManager existingIcon = child.GetComponent<AlarmSingleIconManager>();
if (existingIcon != null && existingIcon.IsDetailViewActive) existingIcon.HideDetail();
}
if (singleAlarmIcon1 != null && singleAlarmIcon1.IsDetailViewActive)
@@ -404,23 +404,19 @@ namespace UVC.Factory.Alarm
});
}
private float cameraY = 0f;
/// <summary>
/// 카메라 위치가 변경될 때 호출되는 이벤트 핸들러입니다.
/// 사용자가 줌 아웃(카메라가 멀어짐)하면 펼쳐진 클러스터를 자동으로 닫습니다.
/// </summary>
private void OnCameraPositionChangedHandler(Vector3 position)
private void OnCameraPositionUpChangedHandler(float gap)
{
Debug.Log($"Camera position changed: {cameraY}, {position.y}, {isZoomIn}");
if (cameraY < position.y && isZoomIn)
if (isZoomIn)
{
// 줌 인 상태에서 카메라 위치가 변경되면 클러스터를 해제
CollapseCluster();
isZoomIn = false; // 줌 인 상태를 해제합니다.
}
cameraY = position.y; // 카메라의 Y 위치를 업데이트
}
private void OnDestroy()
@@ -431,7 +427,7 @@ namespace UVC.Factory.Alarm
uiSpacingTweener.Kill();
}
FactoryCameraController.Instance.OnCameraPositionChanged -= OnCameraPositionChangedHandler;
FactoryCameraController.Instance.OnCameraPositionUpChanged -= OnCameraPositionUpChangedHandler;
clusterView.OnClickHandler -= OnPointerClick;
targetObject = null;
alarms.Clear();

View File

@@ -137,7 +137,7 @@ namespace UVC.Factory.Alarm
var RemovedItems = new List<DataObject>(arr.RemovedItems);
var ModifiedList = arr.ModifiedList;
Debug.Log($"AlarmManager OnUpdateData: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
//Debug.Log($"AlarmManager OnUpdateData: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
// 'CLEAR_TIME'이 설정된 항목은 '해제된 알람'으로 간주하고, 제거 리스트에 추가합니다.
// AddedItems나 ModifiedList에 포함되어 있더라도 CLEAR_TIME이 있으면 즉시 해제 처리하기 위함입니다.
@@ -224,7 +224,7 @@ namespace UVC.Factory.Alarm
// 설비 ID를 이용해 씬에서 실제 FactoryObject를 찾습니다.
FactoryObject? targetObject = dataManager!.FindByName(eqpId);
Debug.Log($"AlarmManager {targetObject == null} {data.Id}, {eqpId}");
//Debug.Log($"AlarmManager {targetObject == null} {data.Id}, {eqpId}");
if (targetObject == null) return;
// 해당 설비에 이미 활성화된 알람 UI가 있는지 확인합니다.

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a651278faa6ca71468e19553474e6bb5

View File

@@ -8,7 +8,7 @@ namespace UVC.Factory.Alarm
/// <summary>
/// 개별 알람을 나타내는 가장 기본적인 UI 컴포넌트입니다.
/// 이 컴포넌트는 버튼 기능과 텍스트 표시 기능을 가지고 있으며,
/// 상위 관리자인 'AlarmSigleIconManager'에 의해 제어됩니다.
/// 상위 관리자인 'AlarmSingleIconManager'에 의해 제어됩니다.
/// </summary>
public class AlarmSingleIcon : MonoBehaviour
{
@@ -35,7 +35,7 @@ namespace UVC.Factory.Alarm
/// <summary>
/// 이 버튼이 클릭되었을 때 호출될 이벤트를 정의합니다.
/// 상위 관리자(AlarmSigleIconManager)가 이 이벤트를 구독하여 클릭 시 특정 동작(예: 상세 정보 표시)을 수행합니다.
/// 상위 관리자(AlarmSingleIconManager)가 이 이벤트를 구독하여 클릭 시 특정 동작(예: 상세 정보 표시)을 수행합니다.
/// </summary>
public Action OnClickHandler;

View File

@@ -8,7 +8,7 @@ namespace UVC.Factory.Alarm
/// 개별 알람 아이콘 하나를 관리하는 클래스입니다.
/// 평소에는 간단한 아이콘(AlarmSingleIcon)으로 표시되고, 클릭하면 상세 정보(AlarmDetailView)를 보여줍니다.
/// </summary>
public class AlarmSigleIconManager : MonoBehaviour
public class AlarmSingleIconManager : MonoBehaviour
{
[Header("UI Components")]
[Tooltip("알람을 간략하게 표시하는 아이콘 UI입니다.")]
@@ -21,7 +21,7 @@ namespace UVC.Factory.Alarm
/// 이 아이콘의 상세 보기가 활성화될 때 호출되는 이벤트입니다.
/// 상위 관리자인 AlarmIconManager가 다른 아이콘들의 상세 보기를 닫는 등의 관리를 위해 사용합니다.
/// </summary>
public Action<AlarmSigleIconManager> OnDetail;
public Action<AlarmSingleIconManager> OnDetail;
// 이 아이콘이 표시하는 실제 알람 데이터입니다.
private DataObject data;

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 52c271c8fd8668e48b7f38bf461cf166

View File

@@ -65,6 +65,14 @@ namespace UVC.Factory
///</remarks>
public Action<Vector3> OnCameraPositionChanged;
/// <summary>
/// 카메라 높이가 변경될 때 발생합니다.
/// </summary>
/// <remarks>이 이벤트는 카메라 높이가 업데이트될 때마다 트리거됩니다. 구독자는
/// 이 이벤트를 사용하여 UI 요소를 업데이트하거나 새 높이를 기반으로 계산을 수행하는 등 카메라 높이 변경에 대응할 수 있습니다.
///</remarks>
public Action<float> OnCameraPositionUpChanged;
/// <summary>
/// 카메라의 회전이 변경될 때 발생합니다.
/// </summary>
@@ -86,7 +94,8 @@ namespace UVC.Factory
}
}
private Transform prevTransform; // 이전 카메라 거리
private Quaternion prevRotation; // 이전 카메라 각도
private Vector3 prevPosition; // 이전 카메라 위치
private Vector3 lastPanPosition;
private Vector3 rotationPivot;
@@ -98,7 +107,8 @@ namespace UVC.Factory
{
// 스크립트 시작 시, 회전의 기준이 되는 중심점을 카메라 앞쪽으로 초기화합니다.
rotationPivot = transform.position + transform.forward * 10f;
this.prevTransform = transform; // 초기 카메라 위치 저장
this.prevRotation = transform.rotation; // 초기 카메라 각도 저장
this.prevPosition = transform.position; // 초기 카메라 위치 저장
}
private void StopFocusCoroutine()
@@ -112,19 +122,21 @@ namespace UVC.Factory
private void DispatchEvnet()
{
if (prevTransform != null && (prevTransform.position != transform.position || prevTransform.rotation != transform.rotation))
if (prevPosition != transform.position || prevRotation != transform.rotation)
{
OnCameraChanged?.Invoke(transform);
if (prevTransform.position != transform.position)
if (prevPosition != transform.position)
{
OnCameraPositionChanged?.Invoke(transform.position);
if (prevPosition.y < transform.position.y) OnCameraPositionUpChanged?.Invoke(transform.position.y - prevPosition.y);
}
if (prevTransform.rotation != transform.rotation)
if (prevRotation != transform.rotation)
{
OnCameraRotationChanged?.Invoke(transform.rotation);
}
}
prevTransform = transform; // 현재 카메라 위치 저장
prevRotation = transform.rotation; // 현재 카메라 각도 저장
prevPosition = transform.position; // 현재 카메라 위치 저장
}
private void ValidateCameraTransform()

View File

@@ -838,6 +838,7 @@ PlayerSettings:
platformArchitecture: {}
scriptingBackend:
Android: 1
Standalone: 1
il2cppCompilerConfiguration: {}
il2cppCodeGeneration: {}
il2cppStacktraceInformation: {}