using System.Collections.Generic; using System.Linq; using Core; using Script.Gameplay.Edit; using Script.Gameplay.Interface; using Script.Gameplay.Player; using UnityEngine; using Script.Gameplay.Input; namespace UI { // 用于显示和编辑 Facility 上的各个 IEditComponent 组件的 UI 面板 public class PlayerEditViewer : UIBase { [SerializeField] private GameObject componentEditViewerPrefab; [SerializeField] private GameObject noEditableTargetPanel; [SerializeField] private float panelRadius = 100f; public List componentViewers = new List(); private PlayerEditController editController; private InputManager inputManager; protected override void Awake() { base.Awake(); inputManager = InputManager.Instance; ControllerLocator.Instance.TryGetWait(OnGetPlayerEditController); } public void OnBeginEdit(GameObject target) { this.gameObject.SetActive(true); if (target != null) { ClearComponentUI(); GenerateComponentUI(EditableManager.GetEditableComponents(target)); } else { if (noEditableTargetPanel != null) { noEditableTargetPanel.SetActive(true); } } } public void OnEndEdit(GameObject target) { this.gameObject.SetActive(false); ClearComponentUI(); if (noEditableTargetPanel != null) { noEditableTargetPanel.SetActive(false); } } // 获取 PlayerEditController 的回调 private void OnGetPlayerEditController(PlayerEditController controller) { this.editController = controller; this.editController.OnBeginEditTarget += OnBeginEdit; this.editController.OnEndEditTarget += OnEndEdit; //Debug.Log("PlayerEditViewer obtained PlayerEditController."); } private void ClearComponentUI() { foreach (var viewer in componentViewers) { if (viewer != null) { if (Application.isPlaying) Destroy(viewer.gameObject); else DestroyImmediate(viewer.gameObject); } } componentViewers.Clear(); } // 根据 components 生成 UI, 根据拥有的 IEditComponent 的数量动态生成 UI 元素。布局为环绕着面板中心排列(自适应间隔)。 private void GenerateComponentUI(List components) { if (components == null || components.Count == 0 || componentEditViewerPrefab == null) return; // 计算半径:如果有 RectTransform 就根据面板大小自适应,否则使用默认值 float radius = panelRadius; var rect = GetComponent(); if (rect != null) { radius = Mathf.Min(rect.rect.width, rect.rect.height) * 0.4f; } int n = components.Count; float angleStep = 360f / n; for (int i = 0; i < n; i++) { float angleDeg = angleStep * i; float angleRad = Mathf.Deg2Rad * angleDeg; Vector2 localPos = new Vector2(Mathf.Cos(angleRad), Mathf.Sin(angleRad)) * radius; var go = Instantiate(componentEditViewerPrefab, transform); go.name = $"{componentEditViewerPrefab.name}_{i}"; var viewer = go.GetComponent(); if (viewer != null) { viewer.SetComponent(components[i]); // 注入此UI需要的组件数据 componentViewers.Add(viewer); } // 如果是 UI 元素,优先设置 RectTransform.anchoredPosition var childRect = go.GetComponent(); if (childRect != null) { childRect.anchoredPosition = localPos; childRect.localRotation = Quaternion.identity; childRect.localScale = Vector3.one; } else { go.transform.localPosition = new Vector3(localPos.x, localPos.y, 0f); go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; } // 如果预制件包含接收组件的方法(例如 SetComponent),通过 SendMessage 传递。若无则忽略。 //go.SendMessage("SetComponent", components[i], SendMessageOptions.DontRequireReceiver); } } } }