mirror of
https://github.com/DeMuenu/MoonlightVRC.git
synced 2025-12-13 11:33:54 +00:00
Initial commit
This commit is contained in:
8
EditorPreview/Editor.meta
Normal file
8
EditorPreview/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ee398d1bd8711f4e9424187553d2877
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
159
EditorPreview/Editor/PlayerPositionsToShaderPreview.cs
Normal file
159
EditorPreview/Editor/PlayerPositionsToShaderPreview.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
// Assets/Editor/PlayerPositionsToShaderPreview.cs
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class PlayerPositionsToShaderPreview
|
||||
{
|
||||
const double kTickInterval = 0.1; // seconds
|
||||
static double _nextTick;
|
||||
static readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock();
|
||||
static readonly Dictionary<PlayerPositionsToShader, Cache> _cache = new Dictionary<PlayerPositionsToShader, Cache>();
|
||||
|
||||
struct Cache
|
||||
{
|
||||
public Vector4[] positions;
|
||||
public Vector4[] colors;
|
||||
public Vector4[] directions;
|
||||
public float[] types;
|
||||
public int size;
|
||||
}
|
||||
|
||||
static PlayerPositionsToShaderPreview()
|
||||
{
|
||||
EditorApplication.update += Update;
|
||||
EditorApplication.hierarchyChanged += ForceTick;
|
||||
Undo.undoRedoPerformed += ForceTick;
|
||||
Selection.selectionChanged += ForceTick;
|
||||
}
|
||||
|
||||
public static void ForceTick() => _nextTick = 0;
|
||||
|
||||
static void Update()
|
||||
{
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
|
||||
#else
|
||||
if (EditorApplication.isPlaying) return;
|
||||
#endif
|
||||
double now = EditorApplication.timeSinceStartup;
|
||||
if (now < _nextTick) return;
|
||||
_nextTick = now + kTickInterval;
|
||||
|
||||
var behaviours = FindAllInScene();
|
||||
foreach (var b in behaviours)
|
||||
{
|
||||
if (b == null || !b.isActiveAndEnabled) continue;
|
||||
if (EditorUtility.IsPersistent(b)) continue; // skip assets
|
||||
PushFromUdonBehaviour(b);
|
||||
}
|
||||
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
static PlayerPositionsToShader[] FindAllInScene()
|
||||
{
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
return Object.FindObjectsByType<PlayerPositionsToShader>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
|
||||
#elif UNITY_2020_1_OR_NEWER
|
||||
return Object.FindObjectsOfType<PlayerPositionsToShader>(true);
|
||||
#else
|
||||
return Resources.FindObjectsOfTypeAll<PlayerPositionsToShader>();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void EnsureArrays(PlayerPositionsToShader src, int required)
|
||||
{
|
||||
if (!_cache.TryGetValue(src, out var c) ||
|
||||
c.positions == null || c.colors == null || c.directions == null || c.types == null ||
|
||||
c.size != required)
|
||||
{
|
||||
c = new Cache
|
||||
{
|
||||
positions = new Vector4[required],
|
||||
colors = new Vector4[required],
|
||||
directions = new Vector4[required],
|
||||
types = new float[required],
|
||||
size = required
|
||||
};
|
||||
_cache[src] = c;
|
||||
}
|
||||
}
|
||||
|
||||
static void PushFromUdonBehaviour(PlayerPositionsToShader src)
|
||||
{
|
||||
int max = Mathf.Max(1, src.maxLights);
|
||||
EnsureArrays(src, max);
|
||||
|
||||
var c = _cache[src];
|
||||
var positions = c.positions;
|
||||
var colors = c.colors;
|
||||
var directions = c.directions;
|
||||
var types = c.types;
|
||||
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
positions[i] = Vector4.zero;
|
||||
colors[i] = Vector4.zero;
|
||||
directions[i] = Vector4.zero;
|
||||
types[i] = 0f;
|
||||
}
|
||||
|
||||
// 🔗 Use the Editor-side function defined on the partial class
|
||||
int count = 0;
|
||||
try
|
||||
{
|
||||
src.Editor_BuildPreview(out positions, out colors, out directions, out types, out count);
|
||||
// replace cache arrays if sizes changed
|
||||
if (positions.Length != c.size) EnsureArrays(src, positions.Length);
|
||||
_cache[src] = new Cache { positions = positions, colors = colors, directions = directions, types = types, size = positions.Length };
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ultra-safe fallback: nothing to push if the method signature changes unexpectedly
|
||||
count = 0;
|
||||
}
|
||||
|
||||
var rds = src.targets ?? System.Array.Empty<Renderer>();
|
||||
for (int r = 0; r < rds.Length; r++)
|
||||
{
|
||||
var rd = rds[r];
|
||||
if (rd == null) continue;
|
||||
|
||||
rd.GetPropertyBlock(_mpb);
|
||||
|
||||
if (!string.IsNullOrEmpty(src.positionsProperty)) _mpb.SetVectorArray(src.positionsProperty, positions);
|
||||
if (!string.IsNullOrEmpty(src.colorProperty)) _mpb.SetVectorArray(src.colorProperty, colors);
|
||||
if (!string.IsNullOrEmpty(src.directionsProperty)) _mpb.SetVectorArray(src.directionsProperty, directions);
|
||||
if (!string.IsNullOrEmpty(src.typeProperty)) _mpb.SetFloatArray (src.typeProperty, types);
|
||||
if (!string.IsNullOrEmpty(src.countProperty)) _mpb.SetFloat (src.countProperty, count);
|
||||
|
||||
rd.SetPropertyBlock(_mpb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(PlayerPositionsToShader))]
|
||||
public class PlayerPositionsToShaderInspector : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DrawDefaultInspector();
|
||||
GUILayout.Space(6);
|
||||
using (new EditorGUI.DisabledScope(true))
|
||||
{
|
||||
EditorGUILayout.LabelField("Edit-Mode Preview", EditorStyles.boldLabel);
|
||||
EditorGUILayout.LabelField("Updates ~10×/s using \"Other Transforms\" as emitters.");
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Refresh Now"))
|
||||
{
|
||||
PlayerPositionsToShaderPreview.ForceTick();
|
||||
EditorApplication.QueuePlayerLoopUpdate();
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
EditorPreview/Editor/PlayerPositionsToShaderPreview.cs.meta
Normal file
11
EditorPreview/Editor/PlayerPositionsToShaderPreview.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2eac5e5df0d18524e84022a091ada4f5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
53
EditorPreview/PlayerPositionsToShader.Editor.cs
Normal file
53
EditorPreview/PlayerPositionsToShader.Editor.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
// Assets/Lighting/Scripts/PlayerPositionsToShader.Editor.cs
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
public partial class PlayerPositionsToShader
|
||||
{
|
||||
public void Editor_BuildPreview(
|
||||
out Vector4[] positions,
|
||||
out Vector4[] colors,
|
||||
out Vector4[] directions,
|
||||
out float[] types,
|
||||
out int count)
|
||||
{
|
||||
int max = Mathf.Max(1, maxLights);
|
||||
|
||||
positions = new Vector4[max];
|
||||
colors = new Vector4[max];
|
||||
directions = new Vector4[max];
|
||||
types = new float[max];
|
||||
count = 0;
|
||||
|
||||
// ✅ Avoid Array.Empty<T>(); just guard the loop
|
||||
if (otherLightSources != null)
|
||||
{
|
||||
for (int i = 0; i < otherLightSources.Length && count < max; i++)
|
||||
{
|
||||
Transform t = otherLightSources[i];
|
||||
if (t == null || !t.gameObject.activeInHierarchy) continue;
|
||||
|
||||
LightdataStorage data = t.GetComponent<LightdataStorage>();
|
||||
|
||||
Vector3 pos = t.position;
|
||||
float range = (data != null) ? data.range * t.localScale.x : t.localScale.x;
|
||||
Vector4 col = (data != null) ? data.GetFinalColor() : new Vector4(1f, 1f, 1f, 1f);
|
||||
float intens = (data != null) ? data.intensity * t.localScale.x : 1f;
|
||||
float cosHalf = (data != null) ? data.GetCosHalfAngle() : 1f;
|
||||
int typeId = (data != null) ? data.GetTypeId() : 0;
|
||||
|
||||
|
||||
Quaternion rot = t.rotation;
|
||||
Vector3 fwd = rot * Vector3.down;
|
||||
|
||||
positions[count] = new Vector4(pos.x, pos.y, pos.z, range);
|
||||
colors[count] = new Vector4(col.x, col.y, col.z, intens);
|
||||
directions[count] = new Vector4(fwd.x, fwd.y, fwd.z, data.spotAngleDeg);
|
||||
types[count] = (float)typeId;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
11
EditorPreview/PlayerPositionsToShader.Editor.cs.meta
Normal file
11
EditorPreview/PlayerPositionsToShader.Editor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93398d31d2739524dad37ec5e916b222
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user