using System.Collections.Generic; using TMPro; using UnityEngine; using XRLib.UI; using XED.Manage; using System.Linq; namespace XED.UI { public class Panel_ObjectInfo : PanelBase { public enum InputFieldType { none, posX, posY, posZ, rotX, rotY, rotZ, scaX, scaY, scaZ, } public class SelectedInput { public InputFieldType type = InputFieldType.none; public float value = 0.0f; public SelectedInput(InputFieldType type, float value) { this.type = type; this.value = value; } } public TextMeshProUGUI Text_Name; public TMP_InputField InputField_PositionX; public TMP_InputField InputField_PositionY; public TMP_InputField InputField_PositionZ; public TMP_InputField InputField_RotationX; public TMP_InputField InputField_RotationY; public TMP_InputField InputField_RotationZ; public TMP_InputField InputField_ScaleX; public TMP_InputField InputField_ScaleY; public TMP_InputField InputField_ScaleZ; public event System.Action> onTransformChanged; private List selectedObjects = new List(); private SelectedInput lastSelectedInputField = new SelectedInput(InputFieldType.none ,0.0f); public override void AfterAwake() { InputField_PositionX.onValueChanged.AddListener(OnPosXChanged); InputField_PositionY.onValueChanged.AddListener(OnPosYChanged); InputField_PositionZ.onValueChanged.AddListener(OnPosZChanged); InputField_RotationX.onValueChanged.AddListener(OnRotXChanged); InputField_RotationY.onValueChanged.AddListener(OnRotYChanged); InputField_RotationZ.onValueChanged.AddListener(OnRotZChanged); InputField_ScaleX.onValueChanged.AddListener(OnScaXChanged); InputField_ScaleY.onValueChanged.AddListener(OnScaYChanged); InputField_ScaleZ.onValueChanged.AddListener(OnScaZChanged); InputField_PositionX.onDeselect.AddListener(OnDeselectInputField); InputField_PositionY.onDeselect.AddListener(OnDeselectInputField); InputField_PositionZ.onDeselect.AddListener(OnDeselectInputField); InputField_RotationX.onDeselect.AddListener(OnDeselectInputField); InputField_RotationY.onDeselect.AddListener(OnDeselectInputField); InputField_RotationZ.onDeselect.AddListener(OnDeselectInputField); InputField_ScaleX.onDeselect.AddListener(OnDeselectInputField); InputField_ScaleY.onDeselect.AddListener(OnDeselectInputField); InputField_ScaleZ.onDeselect.AddListener(OnDeselectInputField); ResetObjectInfo(); } void OnPosXChanged(string input) { OnTransformChanged(InputFieldType.posX, input); } void OnPosYChanged(string input) { OnTransformChanged(InputFieldType.posY, input); } void OnPosZChanged(string input) { OnTransformChanged(InputFieldType.posZ, input); } void OnRotXChanged(string input) { OnTransformChanged(InputFieldType.rotX, input); } void OnRotYChanged(string input) { OnTransformChanged(InputFieldType.rotY, input); } void OnRotZChanged(string input) { OnTransformChanged(InputFieldType.rotZ, input); } void OnScaXChanged(string input) { OnTransformChanged(InputFieldType.scaX, input); } void OnScaYChanged(string input) { OnTransformChanged(InputFieldType.scaY, input); } void OnScaZChanged(string input) { OnTransformChanged(InputFieldType.scaZ, input); } void OnTransformChanged(InputFieldType type, string input) { if (selectedObjects.Count == 0) { return; } float value = 0.0f; if (!float.TryParse(input, out value)) { return; } if (lastSelectedInputField.type != type) { AddUndoRedo(type, value); } lastSelectedInputField.value = value; foreach (GameObject gb in selectedObjects) { ChangeTransformValue(gb.transform, type, value); } onTransformChanged?.Invoke(selectedObjects); } public void OnTransformChanged(List objectTransforms) { selectedObjects = objectTransforms; if (objectTransforms.Count == 0) { ResetObjectInfo(); return; } bool equalPosX = selectedObjects.All(gb => Mathf.Approximately(gb.transform.position.x, selectedObjects[0].transform.position.x)); bool equalPosY = selectedObjects.All(gb => Mathf.Approximately(gb.transform.position.y, selectedObjects[0].transform.position.y)); bool equalPosZ = selectedObjects.All(gb => Mathf.Approximately(gb.transform.position.z, selectedObjects[0].transform.position.z)); bool equalRotX = selectedObjects.All(gb => Mathf.Approximately(gb.transform.eulerAngles.x, selectedObjects[0].transform.eulerAngles.x)); bool equalRotY = selectedObjects.All(gb => Mathf.Approximately(gb.transform.eulerAngles.y, selectedObjects[0].transform.eulerAngles.y)); bool equalRotZ = selectedObjects.All(gb => Mathf.Approximately(gb.transform.eulerAngles.z, selectedObjects[0].transform.eulerAngles.z)); bool equalScaX = selectedObjects.All(gb => Mathf.Approximately(gb.transform.localScale.x, selectedObjects[0].transform.localScale.x)); bool equalScaY = selectedObjects.All(gb => Mathf.Approximately(gb.transform.localScale.y, selectedObjects[0].transform.localScale.y)); bool equalScaZ = selectedObjects.All(gb => Mathf.Approximately(gb.transform.localScale.z, selectedObjects[0].transform.localScale.z)); Transform t = selectedObjects[0].transform; if (equalPosX) InputField_PositionX.SetTextWithoutNotify(t.position.x.ToString("F2")); if (equalPosY) InputField_PositionY.SetTextWithoutNotify(t.position.y.ToString("F2")); if (equalPosZ) InputField_PositionZ.SetTextWithoutNotify(t.position.z.ToString("F2")); if (equalRotX) InputField_RotationX.SetTextWithoutNotify(t.eulerAngles.x.ToString("F2")); if (equalRotY) InputField_RotationY.SetTextWithoutNotify(t.eulerAngles.y.ToString("F2")); if (equalRotZ) InputField_RotationZ.SetTextWithoutNotify(t.eulerAngles.z.ToString("F2")); if (equalScaX) InputField_ScaleX.SetTextWithoutNotify(t.localScale.x.ToString("F2")); if (equalScaY) InputField_ScaleY.SetTextWithoutNotify(t.localScale.y.ToString("F2")); if (equalScaZ) InputField_ScaleZ.SetTextWithoutNotify(t.localScale.z.ToString("F2")); } void AddUndoRedo(InputFieldType type, float value) { lastSelectedInputField = new SelectedInput(type, value); SelectedInput saveSelectedInput = lastSelectedInputField; List transformsChanged = new List(selectedObjects); List origValues; switch (type) { case InputFieldType.posX: origValues = transformsChanged.Select(t => t.transform.position.x).ToList(); break; case InputFieldType.posY: origValues = transformsChanged.Select(t => t.transform.position.y).ToList(); break; case InputFieldType.posZ: origValues = transformsChanged.Select(t => t.transform.position.z).ToList(); break; case InputFieldType.rotX: origValues = transformsChanged.Select(t => t.transform.eulerAngles.x).ToList(); break; case InputFieldType.rotY: origValues = transformsChanged.Select(t => t.transform.eulerAngles.y).ToList(); break; case InputFieldType.rotZ: origValues = transformsChanged.Select(t => t.transform.eulerAngles.z).ToList(); break; case InputFieldType.scaX: origValues = transformsChanged.Select(t => t.transform.localScale.x).ToList(); break; case InputFieldType.scaY: origValues = transformsChanged.Select(t => t.transform.localScale.y).ToList(); break; case InputFieldType.scaZ: origValues = transformsChanged.Select(t => t.transform.localScale.z).ToList(); break; default: origValues = new List(transformsChanged.Count); break; } ActionCommand command = new ActionCommand( () => { for (int i = 0; i< transformsChanged.Count; i++) { ChangeTransformValue(transformsChanged[i].transform, type, saveSelectedInput.value); } onTransformChanged?.Invoke(transformsChanged); }, () => { for (int i = 0; i < transformsChanged.Count; i++) { ChangeTransformValue(transformsChanged[i].transform, type, origValues[i]); } onTransformChanged?.Invoke(transformsChanged); }); CommandManager.I.AddCommand(command); } void ChangeTransformValue(Transform t, InputFieldType type, float v) { switch (type) { case InputFieldType.posX: t.position = new Vector3(v, t.position.y, t.position.z); break; case InputFieldType.posY: t.position = new Vector3(t.position.x, v, t.position.z); break; case InputFieldType.posZ: t.position = new Vector3(t.position.x, t.position.y, v); break; case InputFieldType.rotX: t.eulerAngles = new Vector3(v, t.eulerAngles.y, t.eulerAngles.z); break; case InputFieldType.rotY: t.eulerAngles = new Vector3(t.eulerAngles.x, v, t.eulerAngles.z); break; case InputFieldType.rotZ: t.eulerAngles = new Vector3(t.eulerAngles.x, t.eulerAngles.y, v); break; case InputFieldType.scaX: t.localScale = new Vector3(v, t.localScale.y, t.localScale.z); break; case InputFieldType.scaY: t.localScale = new Vector3(t.localScale.x, v, t.localScale.z); break; case InputFieldType.scaZ: t.localScale = new Vector3(t.localScale.x, t.localScale.y, v); break; } } void OnDeselectInputField(string lastInput) { Debug.Log("Deselect Input Field"); if (lastSelectedInputField.type != InputFieldType.none) { lastSelectedInputField = new SelectedInput(InputFieldType.none, 0.0f); } } public void SetObjectInfo(string name, List selectedObjects) { ResetObjectInfo(); if (name == null || selectedObjects == null) { return; } if (selectedObjects.Count == 0) { return; } string append = ""; if (!name.Equals("-")) { append = string.Format(" ({0})", selectedObjects.Count); } Text_Name.text = name + append; OnTransformChanged(selectedObjects); if (lastSelectedInputField.type != InputFieldType.none) { lastSelectedInputField = new SelectedInput(InputFieldType.none, 0.0f); } } public void ResetObjectInfo() { Text_Name.text = "-"; InputField_PositionX.SetTextWithoutNotify("-"); InputField_PositionY.SetTextWithoutNotify("-"); InputField_PositionZ.SetTextWithoutNotify("-"); InputField_RotationX.SetTextWithoutNotify("-"); InputField_RotationY.SetTextWithoutNotify("-"); InputField_RotationZ.SetTextWithoutNotify("-"); InputField_ScaleX.SetTextWithoutNotify("-"); InputField_ScaleY.SetTextWithoutNotify("-"); InputField_ScaleZ.SetTextWithoutNotify("-"); if (lastSelectedInputField.type != InputFieldType.none) { lastSelectedInputField = new SelectedInput(InputFieldType.none, 0.0f); } } } }