Broken RUntime
This commit is contained in:
@@ -1,38 +1,49 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using SplashEdit.RuntimeCode;
|
||||
using System.Linq;
|
||||
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom inspector for PSXSceneExporter.
|
||||
/// When the component is selected and fog is enabled, activates a Unity scene-view
|
||||
/// fog preview that approximates the PS1 linear fog distances.
|
||||
///
|
||||
/// Fog distance mapping:
|
||||
/// fogFarSZ = 8000 / FogDensity (GTE SZ units)
|
||||
/// fogNearSZ = fogFarSZ / 3
|
||||
/// SZ is 20.12 fixed-point: SZ = (unityCoord / GTEScaling) * 4096
|
||||
/// => unityDist = SZ * GTEScaling / 4096
|
||||
/// => Unity fog near = (8000 / (FogDensity * 3)) * GTEScaling / 4096
|
||||
/// => Unity fog far = (8000 / FogDensity) * GTEScaling / 4096
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(PSXSceneExporter))]
|
||||
public class PSXSceneExporterEditor : UnityEditor.Editor
|
||||
{
|
||||
// Saved RenderSettings state so we can restore it on deselect.
|
||||
private SerializedProperty gteScalingProp;
|
||||
private SerializedProperty sceneLuaProp;
|
||||
private SerializedProperty fogEnabledProp;
|
||||
private SerializedProperty fogColorProp;
|
||||
private SerializedProperty fogDensityProp;
|
||||
private SerializedProperty sceneTypeProp;
|
||||
private SerializedProperty cutscenesProp;
|
||||
private SerializedProperty loadingScreenProp;
|
||||
private SerializedProperty previewBVHProp;
|
||||
private SerializedProperty bvhDepthProp;
|
||||
|
||||
private bool _savedFog;
|
||||
private Color _savedFogColor;
|
||||
private FogMode _savedFogMode;
|
||||
private float _savedFogStart;
|
||||
private float _savedFogEnd;
|
||||
|
||||
private bool _previewActive = false;
|
||||
|
||||
private bool showFog = true;
|
||||
private bool showCutscenes = true;
|
||||
private bool showDebug = false;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
gteScalingProp = serializedObject.FindProperty("GTEScaling");
|
||||
sceneLuaProp = serializedObject.FindProperty("SceneLuaFile");
|
||||
fogEnabledProp = serializedObject.FindProperty("FogEnabled");
|
||||
fogColorProp = serializedObject.FindProperty("FogColor");
|
||||
fogDensityProp = serializedObject.FindProperty("FogDensity");
|
||||
sceneTypeProp = serializedObject.FindProperty("SceneType");
|
||||
cutscenesProp = serializedObject.FindProperty("Cutscenes");
|
||||
loadingScreenProp = serializedObject.FindProperty("LoadingScreenPrefab");
|
||||
previewBVHProp = serializedObject.FindProperty("PreviewBVH");
|
||||
bvhDepthProp = serializedObject.FindProperty("BVHPreviewDepth");
|
||||
|
||||
SaveAndApplyFogPreview();
|
||||
// Re-apply whenever the scene is repainted (handles inspector value changes).
|
||||
EditorApplication.update += OnEditorUpdate;
|
||||
}
|
||||
|
||||
@@ -44,11 +55,155 @@ namespace SplashEdit.EditorCode
|
||||
|
||||
private void OnEditorUpdate()
|
||||
{
|
||||
// Keep the preview in sync when the user tweaks values in the inspector.
|
||||
if (_previewActive)
|
||||
ApplyFogPreview();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
var exporter = (PSXSceneExporter)target;
|
||||
|
||||
DrawHeader();
|
||||
EditorGUILayout.Space(4);
|
||||
|
||||
DrawSceneSettings();
|
||||
PSXEditorStyles.DrawSeparator(6, 6);
|
||||
DrawFogSection(exporter);
|
||||
PSXEditorStyles.DrawSeparator(6, 6);
|
||||
DrawCutscenesSection();
|
||||
PSXEditorStyles.DrawSeparator(6, 6);
|
||||
DrawLoadingSection();
|
||||
PSXEditorStyles.DrawSeparator(6, 6);
|
||||
DrawDebugSection();
|
||||
PSXEditorStyles.DrawSeparator(6, 6);
|
||||
DrawSceneStats();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void DrawHeader()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(PSXEditorStyles.CardStyle);
|
||||
EditorGUILayout.LabelField("Scene Exporter", PSXEditorStyles.CardHeaderStyle);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawSceneSettings()
|
||||
{
|
||||
EditorGUILayout.PropertyField(sceneTypeProp, new GUIContent("Scene Type"));
|
||||
|
||||
bool isInterior = (PSXSceneType)sceneTypeProp.enumValueIndex == PSXSceneType.Interior;
|
||||
EditorGUILayout.LabelField(
|
||||
isInterior
|
||||
? "<color=#88aaff>Room/portal occlusion culling.</color>"
|
||||
: "<color=#88cc88>BVH frustum culling.</color>",
|
||||
PSXEditorStyles.RichLabel);
|
||||
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.PropertyField(gteScalingProp, new GUIContent("GTE Scaling"));
|
||||
EditorGUILayout.PropertyField(sceneLuaProp, new GUIContent("Scene Lua"));
|
||||
|
||||
if (sceneLuaProp.objectReferenceValue != null)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.Space(EditorGUI.indentLevel * 15);
|
||||
if (GUILayout.Button("Edit", EditorStyles.miniButtonLeft, GUILayout.Width(50)))
|
||||
AssetDatabase.OpenAsset(sceneLuaProp.objectReferenceValue);
|
||||
if (GUILayout.Button("Clear", EditorStyles.miniButtonRight, GUILayout.Width(50)))
|
||||
sceneLuaProp.objectReferenceValue = null;
|
||||
GUILayout.FlexibleSpace();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFogSection(PSXSceneExporter exporter)
|
||||
{
|
||||
showFog = EditorGUILayout.Foldout(showFog, "Fog", true, PSXEditorStyles.FoldoutHeader);
|
||||
if (!showFog) return;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.PropertyField(fogEnabledProp, new GUIContent("Enabled"));
|
||||
|
||||
if (fogEnabledProp.boolValue)
|
||||
{
|
||||
EditorGUILayout.PropertyField(fogColorProp, new GUIContent("Color"));
|
||||
EditorGUILayout.PropertyField(fogDensityProp, new GUIContent("Density"));
|
||||
|
||||
float gteScale = exporter.GTEScaling;
|
||||
int density = Mathf.Clamp(exporter.FogDensity, 1, 10);
|
||||
float fogFarUnity = (8000f / density) * gteScale / 4096f;
|
||||
float fogNearUnity = fogFarUnity / 3f;
|
||||
|
||||
EditorGUILayout.Space(2);
|
||||
EditorGUILayout.LabelField(
|
||||
$"<color=#aaaaaa>Preview: {fogNearUnity:F1} – {fogFarUnity:F1} units | " +
|
||||
$"GTE: {8000f / (density * 3f):F0} – {8000f / density:F0} SZ</color>",
|
||||
PSXEditorStyles.RichLabel);
|
||||
|
||||
ApplyFogPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderSettings.fog = false;
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
private void DrawCutscenesSection()
|
||||
{
|
||||
showCutscenes = EditorGUILayout.Foldout(showCutscenes, "Cutscenes", true, PSXEditorStyles.FoldoutHeader);
|
||||
if (!showCutscenes) return;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(cutscenesProp, new GUIContent("Clips"), true);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
private void DrawLoadingSection()
|
||||
{
|
||||
EditorGUILayout.PropertyField(loadingScreenProp, new GUIContent("Loading Screen Prefab"));
|
||||
if (loadingScreenProp.objectReferenceValue != null)
|
||||
{
|
||||
var go = loadingScreenProp.objectReferenceValue as GameObject;
|
||||
if (go != null && go.GetComponentInChildren<PSXCanvas>() == null)
|
||||
{
|
||||
EditorGUILayout.LabelField(
|
||||
"<color=#ffaa44>Prefab has no PSXCanvas component.</color>",
|
||||
PSXEditorStyles.RichLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDebugSection()
|
||||
{
|
||||
showDebug = EditorGUILayout.Foldout(showDebug, "Debug", true, PSXEditorStyles.FoldoutHeader);
|
||||
if (!showDebug) return;
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(previewBVHProp, new GUIContent("Preview BVH"));
|
||||
if (previewBVHProp.boolValue)
|
||||
EditorGUILayout.PropertyField(bvhDepthProp, new GUIContent("BVH Depth"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
private void DrawSceneStats()
|
||||
{
|
||||
var exporters = FindObjectsOfType<PSXObjectExporter>();
|
||||
int total = exporters.Length;
|
||||
int active = exporters.Count(e => e.IsActive);
|
||||
int withCollision = exporters.Count(e => e.CollisionType != PSXCollisionType.None);
|
||||
int staticCol = exporters.Count(e => e.StaticCollider && e.CollisionType != PSXCollisionType.None);
|
||||
|
||||
EditorGUILayout.BeginVertical(PSXEditorStyles.CardStyle);
|
||||
EditorGUILayout.LabelField(
|
||||
$"<b>{active}</b>/{total} objects | <b>{withCollision}</b> colliders ({staticCol} static)",
|
||||
PSXEditorStyles.RichLabel);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void SaveAndApplyFogPreview()
|
||||
{
|
||||
_savedFog = RenderSettings.fog;
|
||||
@@ -56,7 +211,6 @@ namespace SplashEdit.EditorCode
|
||||
_savedFogMode = RenderSettings.fogMode;
|
||||
_savedFogStart = RenderSettings.fogStartDistance;
|
||||
_savedFogEnd = RenderSettings.fogEndDistance;
|
||||
|
||||
_previewActive = true;
|
||||
ApplyFogPreview();
|
||||
}
|
||||
@@ -68,76 +222,31 @@ namespace SplashEdit.EditorCode
|
||||
|
||||
if (!exporter.FogEnabled)
|
||||
{
|
||||
// Fog disabled on the component - turn off the preview.
|
||||
RenderSettings.fog = false;
|
||||
return;
|
||||
}
|
||||
|
||||
float gteScale = exporter.GTEScaling;
|
||||
int density = Mathf.Clamp(exporter.FogDensity, 1, 10);
|
||||
|
||||
// fogFarSZ in GTE SZ units (20.12 fp); convert to Unity world-space.
|
||||
// SZ = (unityDist / GTEScaling) * 4096, so unityDist = SZ * GTEScaling / 4096
|
||||
float fogFarSZ = 8000f / density;
|
||||
float fogNearSZ = fogFarSZ / 3f;
|
||||
|
||||
float fogFarUnity = fogFarSZ * gteScale / 4096f;
|
||||
float fogNearUnity = fogNearSZ * gteScale / 4096f;
|
||||
|
||||
RenderSettings.fog = true;
|
||||
RenderSettings.fogColor = exporter.FogColor;
|
||||
RenderSettings.fogMode = FogMode.Linear;
|
||||
RenderSettings.fogStartDistance = fogNearUnity;
|
||||
RenderSettings.fogEndDistance = fogFarUnity;
|
||||
RenderSettings.fogStartDistance = fogNearSZ * gteScale / 4096f;
|
||||
RenderSettings.fogEndDistance = fogFarSZ * gteScale / 4096f;
|
||||
}
|
||||
|
||||
private void RestoreFog()
|
||||
{
|
||||
if (!_previewActive) return;
|
||||
_previewActive = false;
|
||||
|
||||
RenderSettings.fog = _savedFog;
|
||||
RenderSettings.fogColor = _savedFogColor;
|
||||
RenderSettings.fogMode = _savedFogMode;
|
||||
RenderSettings.fogStartDistance = _savedFogStart;
|
||||
RenderSettings.fogEndDistance = _savedFogEnd;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
DrawDefaultInspector();
|
||||
|
||||
// Show computed fog distances when fog is enabled, so the user
|
||||
// can see exactly what range the preview represents.
|
||||
var exporter = (PSXSceneExporter)target;
|
||||
if (exporter.FogEnabled)
|
||||
{
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
GUILayout.Label("Fog Preview (active in Scene view)", EditorStyles.boldLabel);
|
||||
|
||||
float gteScale = exporter.GTEScaling;
|
||||
int density = Mathf.Clamp(exporter.FogDensity, 1, 10);
|
||||
float fogFarUnity = (8000f / density) * gteScale / 4096f;
|
||||
float fogNearUnity = fogFarUnity / 3f;
|
||||
|
||||
EditorGUILayout.LabelField("Near distance", $"{fogNearUnity:F1} Unity units");
|
||||
EditorGUILayout.LabelField("Far distance", $"{fogFarUnity:F1} Unity units");
|
||||
EditorGUILayout.LabelField("(PS1 SZ range)", $"{8000f / (density * 3f):F0} - {8000f / density:F0} GTE units");
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
// Keep preview applied as values may have changed.
|
||||
ApplyFogPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure preview is off when fog is disabled.
|
||||
RenderSettings.fog = false;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user