using UnityEngine; using UnityEngine.EventSystems; /// /// Manages layer selection, deselection, and restoring original transforms. /// Attach to the parent GameObject that contains all layer children. /// public class LayerSelector : MonoBehaviour { [HideInInspector] public Transform selectedLayer = null; [Header("Info Panel")] public LayerInfoPanel infoPanel; // Stored original state per layer index private Transform[] layers; private Vector3[] originalPositions; private Vector3[] originalScales; private Quaternion[] originalRotations; private bool savedOriginal = false; void Start() { int count = transform.childCount; layers = new Transform[count]; originalPositions = new Vector3[count]; originalScales = new Vector3[count]; originalRotations = new Quaternion[count]; for (int i = 0; i < count; i++) layers[i] = transform.GetChild(i); } // Call once before the first selection so we capture the "rest" state void SaveOriginal() { if (savedOriginal) return; for (int i = 0; i < layers.Length; i++) { originalPositions[i] = layers[i].localPosition; originalScales[i] = layers[i].localScale; originalRotations[i] = layers[i].localRotation; } savedOriginal = true; Debug.Log("[LayerSelector] Original transforms saved."); } void Update() { // Ignore clicks/taps that land on UI if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()) return; // --- Touch --- if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) { Touch touch = Input.GetTouch(0); if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject(touch.fingerId)) return; Ray ray = Camera.main.ScreenPointToRay(touch.position); if (!TryHitLayer(ray)) CheckDeselect(ray); return; } // --- Mouse (Editor) --- if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (!TryHitLayer(ray)) CheckDeselect(ray); } } // Returns true if a LayerInteract was hit and handled bool TryHitLayer(Ray ray) { if (Physics.Raycast(ray, out RaycastHit hit)) { LayerInteract interact = hit.transform.GetComponent(); if (interact != null) { interact.TapSelect(); return true; } } return false; } void CheckDeselect(Ray ray) { if (selectedLayer == null) return; if (Physics.Raycast(ray, out RaycastHit hit)) { if (!hit.transform.IsChildOf(this.transform)) Deselect(); } else { Deselect(); } } // --------------------------------------------------------------- // PUBLIC API // --------------------------------------------------------------- public void SelectLayer(Transform layer) { SaveOriginal(); // Hide all siblings, show only the selected one foreach (Transform l in layers) l.gameObject.SetActive(l == layer); selectedLayer = layer; LayerInteract interact = layer.GetComponent(); interact?.SetSelected(true); if (infoPanel != null && interact != null) infoPanel.Show(interact.layerTitle, interact.layerDescription, interact.narasiClipIndex); } public void Deselect() { for (int i = 0; i < layers.Length; i++) { layers[i].gameObject.SetActive(true); layers[i].localPosition = originalPositions[i]; layers[i].localRotation = originalRotations[i]; layers[i].localScale = originalScales[i]; } foreach (Transform l in layers) l.GetComponent()?.SetSelected(false); if (infoPanel != null) infoPanel.Hide(); selectedLayer = null; } }