using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using WI; namespace CHN { public class MachineKPIManager : MonoBehaviour, ISingle { public UI_MachineKPI prefab_MachineKPI; private OrbitalController cam; private Machine[] machines; private List matchingMachines = new(); private SDictionary machineKPIs = new(); private UI_MachineKPI current_MachineKPI; public float defaultNameHeight; public float radius; public Vector3 originScale; public void SetMachineKPI(MachineKPIData machineKPIData) { foreach (var item in machineKPIs) { Destroy(item.Value.gameObject); } machineKPIs.Clear(); matchingMachines.Clear(); cam = FindSingle(); prefab_MachineKPI = Resources.Load("Prefabs/UI/PRF_UI_MachineKPI"); foreach (var data in machineKPIData.data.rows) { if (machineKPIs.ContainsKey(data.workcd)) continue; var machineKPI = Instantiate(prefab_MachineKPI, transform); machineKPI.SetData(data); machineKPI.onClickKPI += OnClickMachineKPI; machineKPI.name = data.workcd; machineKPIs.Add(data.workcd, machineKPI); } var building = FindSingle(); machines = building.floors.SelectMany(f => f.machines).ToArray(); foreach (var machine in machines) { if (machineKPIs.ContainsKey(machine.code)) { machine.machineKPI = machineKPIs[machine.code]; var machinePos = machine.centerPos; machine.machineKPI.transform.position = new Vector3(machinePos.x, machinePos.y + defaultNameHeight, machinePos.z); matchingMachines.Add(machine); } } } private void OnClickMachineKPI(UI_MachineKPI machineKPI) { if (current_MachineKPI != null) { current_MachineKPI.Shrink(); } current_MachineKPI = machineKPI; current_MachineKPI.Expand(); } private void Update() { SettingPos(); RangeDetection(); RectangleContainsPoint(); } private void RectangleContainsPoint() { if (Input.GetMouseButton(0)) { if (current_MachineKPI == null) return; if(!RectTransformUtility.RectangleContainsScreenPoint(current_MachineKPI.DetailsKPI, Input.mousePosition)) { current_MachineKPI.Shrink(); current_MachineKPI = null; } } } bool Test(Machine machine) { Vector3 viewPos = cam.camera.WorldToViewportPoint(machine.centerPos); if (viewPos.x >= 0 && viewPos.x <= 1 &&viewPos.y >= 0 && viewPos.y <= 1 && viewPos.z > 0) { return true; } return false; } void SettingPos() { foreach (var machine in matchingMachines) { var machinePos = machine.centerPos; Vector3 screenPos = cam.camera.WorldToScreenPoint(new Vector3(machinePos.x, machinePos.y + defaultNameHeight, machinePos.z)); if (screenPos.z > 0) { machine.machineKPI.transform.position = screenPos; } } } void RangeDetection() { var colliders = Physics.OverlapSphere(cam.camera.transform.position, radius); HashSet machinesInRange = new HashSet(); var layerMask = LayerMask.GetMask("Camera", "Floor Wall"); var currentFloor = FindSingle().currentFloor; foreach (var collider in colliders) { var machine = collider.GetComponent(); if (matchingMachines.Contains(machine)) { if (machine.GetComponentInParent() != currentFloor) continue; MachineKPIsActive(machine, layerMask); var distance = Vector3.Distance(cam.transform.position, machine.centerPos); var machineKPI = machine.machineKPI; machineKPI.transform.localScale = !machineKPI.isExpand ? (radius - distance) / radius * originScale : originScale; } machinesInRange.Add(machine); } foreach (var machine in matchingMachines) { if (!machinesInRange.Contains(machine)) { machine.machineKPI.Deactive(); } } } void MachineKPIsActive(Machine machine, LayerMask layerMask) { var dir = cam.camera.transform.localPosition - machine.centerPos; var hit = new RaycastHit(); if (Physics.Raycast(machine.centerPos, dir, out hit, Mathf.Infinity, layerMask)) { var hitCameraLayer = hit.collider.gameObject.layer.Equals(LayerMask.NameToLayer("Camera")); if (hitCameraLayer) { if (!Test(machine)) return; machine.machineKPI.Active(); } else { machine.machineKPI.Deactive(); } } } } }