Skip to content
Snippets Groups Projects
Commit 08aff386 authored by mhby1g21's avatar mhby1g21
Browse files

refactored helper prefabs to also be windowed menu in AVVR

parent 6318b742
No related branches found
No related tags found
1 merge request!2Gdp 4.2.16 - Refactor Unity utilities tools to be windowed menu instead of prefabs
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR #if UNITY_EDITOR
using UnityEngine;
using UnityEditor; using UnityEditor;
#endif using System.Collections.Generic;
public class AudioCameraPositioner : MonoBehaviour
{
public Camera mainCamera;
public List<AudioSource> audioSources = new List<AudioSource>();
public GameObject modelWrapper;
// Shared data structure
[System.Serializable] [System.Serializable]
public class PositionSetting public class PositionSetting
{ {
...@@ -17,47 +11,39 @@ public class AudioCameraPositioner : MonoBehaviour ...@@ -17,47 +11,39 @@ public class AudioCameraPositioner : MonoBehaviour
public Vector3 position; public Vector3 position;
} }
public PositionSetting cameraPosition = new PositionSetting { name = "Camera" }; // Shared logic class that both MonoBehaviour and EditorWindow can use
public List<PositionSetting> audioSourcePositions = new List<PositionSetting>(); public static class AudioCameraPositionerLogic
{
private Vector3 roomSize; public static void PositionCamera(Camera camera, Vector3 position)
private Vector3 roomCenter;
private Vector3 roomMinPoint;
public void PositionCamera()
{ {
if (mainCamera == null) if (camera == null)
{ {
Debug.LogError("Main camera is not assigned!"); Debug.LogError("Main camera is not assigned!");
return; return;
} }
mainCamera.transform.position = cameraPosition.position; Undo.RecordObject(camera.transform, "Position Camera");
Debug.Log($"Camera positioned at: {cameraPosition.position}"); camera.transform.position = position;
Debug.Log($"Camera positioned at: {position}");
} }
public void PositionAudioSources() public static void PositionAudioSources(List<AudioSource> sources, List<PositionSetting> positions)
{ {
for (int i = 0; i < audioSources.Count && i < audioSourcePositions.Count; i++) for (int i = 0; i < sources.Count && i < positions.Count; i++)
{ {
if (audioSources[i] == null) if (sources[i] == null)
{ {
Debug.LogWarning($"Audio source at index {i} is not assigned!"); Debug.LogWarning($"Audio source at index {i} is not assigned!");
continue; continue;
} }
audioSources[i].transform.position = audioSourcePositions[i].position; Undo.RecordObject(sources[i].transform, "Position Audio Source");
Debug.Log($"Audio source '{audioSourcePositions[i].name}' positioned at: {audioSourcePositions[i].position}"); sources[i].transform.position = positions[i].position;
Debug.Log($"Audio source '{positions[i].name}' positioned at: {positions[i].position}");
} }
} }
public void PositionAll() public static void AlignRoomCorner(GameObject modelWrapper, int cornerIndex)
{
PositionCamera();
PositionAudioSources();
}
public void AlignRoomCorner(int cornerIndex)
{ {
if (modelWrapper == null) if (modelWrapper == null)
{ {
...@@ -65,20 +51,22 @@ public class AudioCameraPositioner : MonoBehaviour ...@@ -65,20 +51,22 @@ public class AudioCameraPositioner : MonoBehaviour
return; return;
} }
Undo.RecordObject(modelWrapper.transform, "Align Room Corner");
// Step 1: Reset to origin // Step 1: Reset to origin
modelWrapper.transform.position = Vector3.zero; modelWrapper.transform.position = Vector3.zero;
modelWrapper.transform.rotation = Quaternion.identity; modelWrapper.transform.rotation = Quaternion.identity;
// Step 2: Calculate initial dimensions using mesh vertices // Step 2: Calculate initial dimensions
Vector3 minPoint, maxPoint; Vector3 minPoint, maxPoint;
CalculateMeshDimensions(out minPoint, out maxPoint); CalculateMeshDimensions(modelWrapper, out minPoint, out maxPoint);
// Step 3: Rotate based on corner index // Step 3: Rotate based on corner index
Quaternion rotation = Quaternion.Euler(0, 90 * cornerIndex, 0); Quaternion rotation = Quaternion.Euler(0, 90 * cornerIndex, 0);
modelWrapper.transform.rotation = rotation; modelWrapper.transform.rotation = rotation;
// Step 4: Recalculate dimensions after rotation // Step 4: Recalculate dimensions after rotation
CalculateMeshDimensions(out minPoint, out maxPoint); CalculateMeshDimensions(modelWrapper, out minPoint, out maxPoint);
// Step 5: Move the most negative corner to origin // Step 5: Move the most negative corner to origin
Vector3 translation = -minPoint; Vector3 translation = -minPoint;
...@@ -87,12 +75,12 @@ public class AudioCameraPositioner : MonoBehaviour ...@@ -87,12 +75,12 @@ public class AudioCameraPositioner : MonoBehaviour
Debug.Log($"Room aligned to corner {cornerIndex}. Position: {modelWrapper.transform.position}, Rotation: {modelWrapper.transform.rotation.eulerAngles}"); Debug.Log($"Room aligned to corner {cornerIndex}. Position: {modelWrapper.transform.position}, Rotation: {modelWrapper.transform.rotation.eulerAngles}");
} }
private void CalculateMeshDimensions(out Vector3 minPoint, out Vector3 maxPoint) public static void CalculateMeshDimensions(GameObject obj, out Vector3 minPoint, out Vector3 maxPoint)
{ {
minPoint = Vector3.positiveInfinity; minPoint = Vector3.positiveInfinity;
maxPoint = Vector3.negativeInfinity; maxPoint = Vector3.negativeInfinity;
MeshFilter[] meshFilters = modelWrapper.GetComponentsInChildren<MeshFilter>(); MeshFilter[] meshFilters = obj.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter mf in meshFilters) foreach (MeshFilter mf in meshFilters)
{ {
Vector3[] vertices = mf.sharedMesh.vertices; Vector3[] vertices = mf.sharedMesh.vertices;
...@@ -103,18 +91,126 @@ public class AudioCameraPositioner : MonoBehaviour ...@@ -103,18 +91,126 @@ public class AudioCameraPositioner : MonoBehaviour
maxPoint = Vector3.Max(maxPoint, worldVertex); maxPoint = Vector3.Max(maxPoint, worldVertex);
} }
} }
}
}
roomSize = maxPoint - minPoint; // Original MonoBehaviour Component
roomCenter = (minPoint + maxPoint) / 2; public class AudioCameraPositioner : MonoBehaviour
roomMinPoint = minPoint; {
public Camera mainCamera;
public List<AudioSource> audioSources = new List<AudioSource>();
public GameObject modelWrapper;
public PositionSetting cameraPosition = new PositionSetting { name = "Camera" };
public List<PositionSetting> audioSourcePositions = new List<PositionSetting>();
Debug.Log($"Room size: {roomSize}"); public void PositionCamera()
Debug.Log($"Room center: {roomCenter}"); {
Debug.Log($"Room min point: {roomMinPoint}"); AudioCameraPositionerLogic.PositionCamera(mainCamera, cameraPosition.position);
} }
public void PositionAudioSources()
{
AudioCameraPositionerLogic.PositionAudioSources(audioSources, audioSourcePositions);
} }
#if UNITY_EDITOR public void AlignRoomCorner(int cornerIndex)
{
AudioCameraPositionerLogic.AlignRoomCorner(modelWrapper, cornerIndex);
}
}
// Editor Window
public class AudioCameraPositionerWindow : EditorWindow
{
private Camera mainCamera;
private List<AudioSource> audioSources = new List<AudioSource>();
private GameObject modelWrapper;
private PositionSetting cameraPosition = new PositionSetting { name = "Camera" };
private List<PositionSetting> audioSourcePositions = new List<PositionSetting>();
[MenuItem("AVVR/Audio Camera Positioner")]
public static void ShowWindow()
{
GetWindow<AudioCameraPositionerWindow>("Audio Camera Positioner");
}
private void OnGUI()
{
EditorGUILayout.Space(10);
// Camera Section
EditorGUILayout.LabelField("Camera Settings", EditorStyles.boldLabel);
mainCamera = (Camera)EditorGUILayout.ObjectField("Main Camera", mainCamera, typeof(Camera), true);
cameraPosition.position = EditorGUILayout.Vector3Field("Camera Position", cameraPosition.position);
EditorGUI.BeginDisabledGroup(mainCamera == null);
if (GUILayout.Button("Position Camera"))
{
AudioCameraPositionerLogic.PositionCamera(mainCamera, cameraPosition.position);
}
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space(10);
// Audio Section
EditorGUILayout.LabelField("Audio Settings", EditorStyles.boldLabel);
if (GUILayout.Button("Add Audio Source"))
{
audioSources.Add(null);
audioSourcePositions.Add(new PositionSetting { name = $"Audio Source {audioSources.Count}" });
}
for (int i = 0; i < audioSources.Count; i++)
{
EditorGUILayout.BeginHorizontal();
audioSources[i] = (AudioSource)EditorGUILayout.ObjectField(
audioSources[i], typeof(AudioSource), true
);
if (i < audioSourcePositions.Count)
{
audioSourcePositions[i].name = EditorGUILayout.TextField(audioSourcePositions[i].name, GUILayout.Width(100));
audioSourcePositions[i].position = EditorGUILayout.Vector3Field("", audioSourcePositions[i].position);
}
if (GUILayout.Button("X", GUILayout.Width(20)))
{
audioSources.RemoveAt(i);
audioSourcePositions.RemoveAt(i);
break;
}
EditorGUILayout.EndHorizontal();
}
if (GUILayout.Button("Position Audio Sources"))
{
AudioCameraPositionerLogic.PositionAudioSources(audioSources, audioSourcePositions);
}
EditorGUILayout.Space(10);
// Room Section
EditorGUILayout.LabelField("Room Settings", EditorStyles.boldLabel);
modelWrapper = (GameObject)EditorGUILayout.ObjectField(
"Model Wrapper", modelWrapper, typeof(GameObject), true
);
EditorGUI.BeginDisabledGroup(modelWrapper == null);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Align Corner 0")) AudioCameraPositionerLogic.AlignRoomCorner(modelWrapper, 0);
if (GUILayout.Button("Align Corner 1")) AudioCameraPositionerLogic.AlignRoomCorner(modelWrapper, 1);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Align Corner 2")) AudioCameraPositionerLogic.AlignRoomCorner(modelWrapper, 2);
if (GUILayout.Button("Align Corner 3")) AudioCameraPositionerLogic.AlignRoomCorner(modelWrapper, 3);
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();
}
}
// Inspector UI for the MonoBehaviour component
[CustomEditor(typeof(AudioCameraPositioner))] [CustomEditor(typeof(AudioCameraPositioner))]
public class AudioCameraPositionerEditor : Editor public class AudioCameraPositionerEditor : Editor
{ {
...@@ -163,11 +259,6 @@ public class AudioCameraPositionerEditor : Editor ...@@ -163,11 +259,6 @@ public class AudioCameraPositionerEditor : Editor
positioner.PositionAudioSources(); positioner.PositionAudioSources();
} }
if (GUILayout.Button("Position All"))
{
positioner.PositionAll();
}
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.LabelField("Room Alignment", EditorStyles.boldLabel); EditorGUILayout.LabelField("Room Alignment", EditorStyles.boldLabel);
......
...@@ -213,4 +213,168 @@ public class MeshDimensionCalculatorEditor : Editor ...@@ -213,4 +213,168 @@ public class MeshDimensionCalculatorEditor : Editor
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
} }
} }
public class MeshDimensionCalculatorWindow : EditorWindow
{
private GameObject targetObject;
private Vector3 dimensions;
private Vector3 center;
private Vector3 totalMin;
private Vector3 totalMax;
private Vector3 scaleFactors = Vector3.one;
private float uniformScaleFactor = 1f;
[MenuItem("AVVR/Mesh Dimension Calculator")]
public static void ShowWindow()
{
GetWindow<MeshDimensionCalculatorWindow>("Mesh Dimensions");
}
private void OnGUI()
{
GUILayout.Label("Mesh Dimension Calculator", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
targetObject = (GameObject)EditorGUILayout.ObjectField("ModelWrapper", targetObject, typeof(GameObject), true);
EditorGUI.BeginDisabledGroup(targetObject == null);
if (GUILayout.Button("Calculate Dimensions"))
{
CalculateDimensions();
}
if (GUILayout.Button("Reset to Origin (0,0,0)"))
{
ResetToOrigin();
}
if (GUILayout.Button("Reset Floor to Y = 0"))
{
ResetFloorToZero();
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Scaling Options", EditorStyles.boldLabel);
scaleFactors = EditorGUILayout.Vector3Field("Scale Factors (X, Y, Z)", scaleFactors);
if (GUILayout.Button("Apply Scale (X, Y, Z)"))
{
ScaleObject();
}
EditorGUILayout.Space();
uniformScaleFactor = EditorGUILayout.FloatField("Uniform Scale Factor", uniformScaleFactor);
if (GUILayout.Button("Apply Uniform Scale"))
{
ScaleObjectUniform();
}
EditorGUILayout.Space();
if (GUILayout.Button("Reset Scale to (1, 1, 1)"))
{
ResetScale();
}
EditorGUI.EndDisabledGroup();
if (targetObject != null && dimensions != Vector3.zero)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Results:", EditorStyles.boldLabel);
EditorGUILayout.Vector3Field("Dimensions", dimensions);
EditorGUILayout.Vector3Field("Center", center);
EditorGUILayout.FloatField("Floor Y Position", totalMin.y);
}
}
private void CalculateDimensions()
{
if (targetObject == null) return;
totalMin = Vector3.positiveInfinity;
totalMax = Vector3.negativeInfinity;
List<MeshFilter> meshFilters = new List<MeshFilter>();
CollectMeshFilters(targetObject.transform, meshFilters);
if (meshFilters.Count == 0)
{
EditorUtility.DisplayDialog("Error", "No meshes found in the target object's hierarchy!", "OK");
return;
}
foreach (MeshFilter meshFilter in meshFilters)
{
Mesh mesh = meshFilter.sharedMesh;
if (mesh == null) continue;
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
Vector3 worldVertex = meshFilter.transform.TransformPoint(vertices[i]);
totalMin = Vector3.Min(totalMin, worldVertex);
totalMax = Vector3.Max(totalMax, worldVertex);
}
}
dimensions = totalMax - totalMin;
center = (totalMin + totalMax) / 2;
Repaint();
}
private void ScaleObject()
{
if (targetObject == null) return;
Undo.RecordObject(targetObject.transform, "Scale Object");
targetObject.transform.localScale = Vector3.Scale(targetObject.transform.localScale, scaleFactors);
}
private void ScaleObjectUniform()
{
if (targetObject == null) return;
Undo.RecordObject(targetObject.transform, "Scale Object Uniform");
targetObject.transform.localScale *= uniformScaleFactor;
}
private void ResetScale()
{
if (targetObject == null) return;
Undo.RecordObject(targetObject.transform, "Reset Scale");
targetObject.transform.localScale = Vector3.one;
}
private void ResetToOrigin()
{
if (targetObject == null) return;
Undo.RecordObject(targetObject.transform, "Reset To Origin");
targetObject.transform.position = Vector3.zero;
}
private void ResetFloorToZero()
{
if (targetObject == null) return;
CalculateDimensions();
Undo.RecordObject(targetObject.transform, "Reset Floor To Zero");
Vector3 newPosition = targetObject.transform.position;
newPosition.y -= totalMin.y;
targetObject.transform.position = newPosition;
}
private void CollectMeshFilters(Transform parent, List<MeshFilter> meshFilters)
{
MeshFilter meshFilter = parent.GetComponent<MeshFilter>();
if (meshFilter != null)
{
meshFilters.Add(meshFilter);
}
for (int i = 0; i < parent.childCount; i++)
{
CollectMeshFilters(parent.GetChild(i), meshFilters);
}
}
}
#endif #endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment