Skip to content

Commit b670846

Browse files
committed
update
1 parent 64e54b0 commit b670846

9 files changed

Lines changed: 1924 additions & 115 deletions

File tree

MCPForUnity/Editor/Helpers/RenderPipelineUtility.cs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ internal enum VFXComponentType
2424
}
2525

2626
private static Dictionary<string, Material> s_DefaultVFXMaterials = new Dictionary<string, Material>();
27+
private static Dictionary<string, Material> s_DefaultSceneMaterials = new Dictionary<string, Material>();
2728

2829
private static readonly string[] BuiltInLitShaders = { "Standard", "Legacy Shaders/Diffuse" };
2930
private static readonly string[] BuiltInUnlitShaders = { "Unlit/Color", "Unlit/Texture" };
31+
private static readonly string[] BuiltInParticleShaders = { "Particles/Standard Unlit", "Particles/Alpha Blended", "Particles/Additive" };
3032
private static readonly string[] UrpLitShaders = { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit" };
3133
private static readonly string[] UrpUnlitShaders = { "Universal Render Pipeline/Unlit" };
34+
private static readonly string[] UrpParticleShaders = {
35+
"Universal Render Pipeline/Particles/Unlit",
36+
"Universal Render Pipeline/Particles/Simple Lit",
37+
"Universal Render Pipeline/Particles/Lit",
38+
};
3239
private static readonly string[] HdrpLitShaders = { "HDRP/Lit", "High Definition Render Pipeline/Lit" };
3340
private static readonly string[] HdrpUnlitShaders = { "HDRP/Unlit", "High Definition Render Pipeline/Unlit" };
3441

@@ -170,8 +177,8 @@ private static void WarnIfPipelineMismatch(string shaderName, PipelineKind activ
170177
var lowerName = shaderName.ToLowerInvariant();
171178
bool shaderLooksUrp = lowerName.Contains("universal render pipeline") || lowerName.Contains("urp/");
172179
bool shaderLooksHdrp = lowerName.Contains("high definition render pipeline") || lowerName.Contains("hdrp/");
173-
bool shaderLooksBuiltin = lowerName.Contains("standard") || lowerName.Contains("legacy shaders/");
174180
bool shaderLooksSrp = shaderLooksUrp || shaderLooksHdrp;
181+
bool shaderLooksBuiltin = LooksLikeBuiltInShader(lowerName, shaderLooksSrp);
175182

176183
switch (activePipeline)
177184
{
@@ -262,8 +269,8 @@ private static bool IsPipelineMismatch(string shaderName, PipelineKind activePip
262269
string lowerName = shaderName.ToLowerInvariant();
263270
bool shaderLooksUrp = lowerName.Contains("universal render pipeline") || lowerName.Contains("urp/");
264271
bool shaderLooksHdrp = lowerName.Contains("high definition render pipeline") || lowerName.Contains("hdrp/");
265-
bool shaderLooksBuiltin = lowerName.Contains("standard") || lowerName.Contains("legacy shaders/");
266272
bool shaderLooksSrp = shaderLooksUrp || shaderLooksHdrp;
273+
bool shaderLooksBuiltin = LooksLikeBuiltInShader(lowerName, shaderLooksSrp);
267274

268275
return activePipeline switch
269276
{
@@ -297,7 +304,7 @@ internal static Material GetOrCreateDefaultVFXMaterial(VFXComponentType componen
297304

298305
if (material == null)
299306
{
300-
Shader shader = ResolveDefaultUnlitShader(pipeline);
307+
Shader shader = ResolveDefaultVFXShader(pipeline, componentType);
301308
if (shader == null)
302309
{
303310
shader = Shader.Find("Unlit/Color");
@@ -350,5 +357,89 @@ internal static Material GetOrCreateDefaultVFXMaterial(VFXComponentType componen
350357

351358
return material;
352359
}
360+
361+
private static Shader ResolveDefaultVFXShader(PipelineKind pipeline, VFXComponentType componentType)
362+
{
363+
if (componentType == VFXComponentType.ParticleSystem)
364+
{
365+
return pipeline switch
366+
{
367+
PipelineKind.Universal => TryFindShader(UrpParticleShaders) ?? ResolveDefaultUnlitShader(pipeline),
368+
PipelineKind.HighDefinition => TryFindShader(HdrpUnlitShaders) ?? ResolveDefaultUnlitShader(pipeline),
369+
PipelineKind.BuiltIn => TryFindShader(BuiltInParticleShaders) ?? ResolveDefaultUnlitShader(pipeline),
370+
PipelineKind.Custom => TryFindShader(UrpParticleShaders)
371+
?? TryFindShader(BuiltInParticleShaders)
372+
?? TryFindShader(HdrpUnlitShaders)
373+
?? ResolveDefaultUnlitShader(pipeline),
374+
_ => ResolveDefaultUnlitShader(pipeline),
375+
};
376+
}
377+
378+
return ResolveDefaultUnlitShader(pipeline);
379+
}
380+
381+
private static bool LooksLikeBuiltInShader(string lowerName, bool shaderLooksSrp)
382+
{
383+
if (string.IsNullOrEmpty(lowerName))
384+
{
385+
return false;
386+
}
387+
388+
if (lowerName == "standard" ||
389+
lowerName.StartsWith("legacy shaders/", StringComparison.Ordinal) ||
390+
lowerName.StartsWith("mobile/", StringComparison.Ordinal))
391+
{
392+
return true;
393+
}
394+
395+
// Built-in non-SRP shader families commonly seen on particles/old content.
396+
if (!shaderLooksSrp &&
397+
(lowerName.StartsWith("particles/", StringComparison.Ordinal) ||
398+
lowerName.StartsWith("unlit/", StringComparison.Ordinal)))
399+
{
400+
return true;
401+
}
402+
403+
return false;
404+
}
405+
406+
internal static Material GetOrCreateDefaultSceneMaterial()
407+
{
408+
var pipeline = GetActivePipeline();
409+
string cacheKey = $"{pipeline}_scene";
410+
if (s_DefaultSceneMaterials.TryGetValue(cacheKey, out Material cached) && cached != null)
411+
{
412+
return cached;
413+
}
414+
415+
Material material = null;
416+
Shader shader = ResolveDefaultLitShader(pipeline) ?? ResolveDefaultUnlitShader(pipeline);
417+
if (shader == null)
418+
{
419+
shader = Shader.Find("Unlit/Color");
420+
}
421+
422+
if (shader != null)
423+
{
424+
material = new Material(shader);
425+
material.name = $"Auto_Default_Scene_{pipeline}";
426+
if (material.HasProperty("_Color"))
427+
{
428+
material.SetColor("_Color", Color.white);
429+
}
430+
if (material.HasProperty("_BaseColor"))
431+
{
432+
material.SetColor("_BaseColor", Color.white);
433+
}
434+
McpLog.Info($"[RenderPipelineUtility] Created default scene material using {shader.name}");
435+
}
436+
437+
if (material != null)
438+
{
439+
s_DefaultSceneMaterials[cacheKey] = material;
440+
}
441+
442+
return material;
443+
}
353444
}
354445
}

MCPForUnity/Editor/Helpers/RendererHelpers.cs

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,59 @@ namespace MCPForUnity.Editor.Helpers
1212
/// </summary>
1313
public static class RendererHelpers
1414
{
15+
public readonly struct EnsureMaterialResult
16+
{
17+
public EnsureMaterialResult(bool materialReplaced, string replacementReason)
18+
{
19+
MaterialReplaced = materialReplaced;
20+
ReplacementReason = replacementReason ?? string.Empty;
21+
}
22+
23+
public bool MaterialReplaced { get; }
24+
public string ReplacementReason { get; }
25+
}
26+
1527
/// <summary>
1628
/// Ensures a renderer has a material assigned. If not, auto-assigns a default material
1729
/// based on the render pipeline and component type.
1830
/// </summary>
1931
/// <param name="renderer">The renderer to check</param>
20-
public static void EnsureMaterial(Renderer renderer)
32+
public static EnsureMaterialResult EnsureMaterial(Renderer renderer)
2133
{
2234
if (renderer == null)
2335
{
24-
return;
36+
return new EnsureMaterialResult(false, "renderer_missing");
2537
}
2638

2739
var existingMaterial = renderer.sharedMaterial;
28-
if (IsUsableMaterial(existingMaterial))
40+
string replacementReason = string.Empty;
41+
bool pipelineInvalid = RenderPipelineUtility.IsMaterialInvalidForActivePipeline(existingMaterial, out string pipelineReason);
42+
if (existingMaterial != null && !pipelineInvalid && IsUsableMaterial(existingMaterial))
2943
{
30-
return;
44+
return new EnsureMaterialResult(false, string.Empty);
3145
}
3246

3347
if (existingMaterial != null)
3448
{
3549
var shaderName = existingMaterial.shader != null ? existingMaterial.shader.name : "(null)";
3650
McpLog.Warn($"[RendererHelpers] Replacing invalid VFX material '{existingMaterial.name}' (shader: {shaderName}).");
51+
replacementReason = !string.IsNullOrWhiteSpace(pipelineReason) ? pipelineReason : "invalid_material";
3752
}
38-
39-
RenderPipelineUtility.VFXComponentType? componentType = null;
40-
if (renderer is ParticleSystemRenderer)
41-
{
42-
componentType = RenderPipelineUtility.VFXComponentType.ParticleSystem;
43-
}
44-
else if (renderer is LineRenderer)
53+
else
4554
{
46-
componentType = RenderPipelineUtility.VFXComponentType.LineRenderer;
47-
}
48-
else if (renderer is TrailRenderer)
49-
{
50-
componentType = RenderPipelineUtility.VFXComponentType.TrailRenderer;
55+
replacementReason = "missing_material";
5156
}
5257

53-
if (componentType.HasValue)
58+
Material replacement = ResolveReplacementMaterial(renderer);
59+
if (replacement != null)
5460
{
55-
Material defaultMat = RenderPipelineUtility.GetOrCreateDefaultVFXMaterial(componentType.Value);
56-
if (defaultMat != null)
57-
{
58-
Undo.RecordObject(renderer, "Assign default VFX material");
59-
renderer.sharedMaterial = defaultMat;
60-
EditorUtility.SetDirty(renderer);
61-
}
61+
Undo.RecordObject(renderer, "Assign default renderer material");
62+
renderer.sharedMaterial = replacement;
63+
EditorUtility.SetDirty(renderer);
64+
return new EnsureMaterialResult(true, replacementReason);
6265
}
66+
67+
return new EnsureMaterialResult(false, replacementReason);
6368
}
6469

6570
private static bool IsUsableMaterial(Material material)
@@ -84,6 +89,23 @@ private static bool IsUsableMaterial(Material material)
8489
return shader.isSupported;
8590
}
8691

92+
private static Material ResolveReplacementMaterial(Renderer renderer)
93+
{
94+
if (renderer is ParticleSystemRenderer)
95+
{
96+
return RenderPipelineUtility.GetOrCreateDefaultVFXMaterial(RenderPipelineUtility.VFXComponentType.ParticleSystem);
97+
}
98+
if (renderer is LineRenderer)
99+
{
100+
return RenderPipelineUtility.GetOrCreateDefaultVFXMaterial(RenderPipelineUtility.VFXComponentType.LineRenderer);
101+
}
102+
if (renderer is TrailRenderer)
103+
{
104+
return RenderPipelineUtility.GetOrCreateDefaultVFXMaterial(RenderPipelineUtility.VFXComponentType.TrailRenderer);
105+
}
106+
return RenderPipelineUtility.GetOrCreateDefaultSceneMaterial();
107+
}
108+
87109
/// <summary>
88110
/// Applies common Renderer properties (shadows, lighting, probes, sorting, rendering layer).
89111
/// Used by ParticleSetRenderer, LineSetProperties, TrailSetProperties.

MCPForUnity/Editor/Tools/ManageMaterial.cs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ private static object SetRendererColor(JObject @params)
280280
return new ErrorResponse($"GameObject {go.name} has no Renderer component");
281281
}
282282

283+
RendererHelpers.EnsureMaterial(renderer);
284+
283285
if (mode == "property_block")
284286
{
285287
if (slot < 0 || slot >= renderer.sharedMaterials.Length)
@@ -293,12 +295,26 @@ private static object SetRendererColor(JObject @params)
293295
if (renderer.sharedMaterials[slot] != null)
294296
{
295297
Material mat = renderer.sharedMaterials[slot];
296-
if (mat.HasProperty("_BaseColor")) block.SetColor("_BaseColor", color);
297-
else if (mat.HasProperty("_Color")) block.SetColor("_Color", color);
298-
else block.SetColor("_Color", color);
298+
bool wroteAnyProperty = false;
299+
if (mat.HasProperty("_BaseColor"))
300+
{
301+
block.SetColor("_BaseColor", color);
302+
wroteAnyProperty = true;
303+
}
304+
if (mat.HasProperty("_Color"))
305+
{
306+
block.SetColor("_Color", color);
307+
wroteAnyProperty = true;
308+
}
309+
if (!wroteAnyProperty)
310+
{
311+
block.SetColor("_BaseColor", color);
312+
block.SetColor("_Color", color);
313+
}
299314
}
300315
else
301316
{
317+
block.SetColor("_BaseColor", color);
302318
block.SetColor("_Color", color);
303319
}
304320

@@ -316,8 +332,7 @@ private static object SetRendererColor(JObject @params)
316332
return new ErrorResponse($"No material in slot {slot}");
317333
}
318334
Undo.RecordObject(mat, "Set Material Color");
319-
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", color);
320-
else mat.SetColor("_Color", color);
335+
SetColorProperties(mat, color);
321336
EditorUtility.SetDirty(mat);
322337
return new SuccessResponse("Set shared material color");
323338
}
@@ -334,8 +349,7 @@ private static object SetRendererColor(JObject @params)
334349
}
335350
// Note: Undo cannot fully revert material instantiation
336351
Undo.RecordObject(mat, "Set Instance Material Color");
337-
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", color);
338-
else mat.SetColor("_Color", color);
352+
SetColorProperties(mat, color);
339353
return new SuccessResponse("Set instance material color", new { warning = "Material instance created; Undo cannot fully revert instantiation." });
340354
}
341355
return new ErrorResponse("Invalid slot");
@@ -344,6 +358,26 @@ private static object SetRendererColor(JObject @params)
344358
return new ErrorResponse($"Unknown mode: {mode}");
345359
}
346360

361+
private static void SetColorProperties(Material mat, Color color)
362+
{
363+
bool wrote = false;
364+
if (mat.HasProperty("_BaseColor"))
365+
{
366+
mat.SetColor("_BaseColor", color);
367+
wrote = true;
368+
}
369+
if (mat.HasProperty("_Color"))
370+
{
371+
mat.SetColor("_Color", color);
372+
wrote = true;
373+
}
374+
if (!wrote)
375+
{
376+
mat.SetColor("_BaseColor", color);
377+
mat.SetColor("_Color", color);
378+
}
379+
}
380+
347381
private static object GetMaterialInfo(JObject @params)
348382
{
349383
string materialPath = NormalizePath(@params["materialPath"]?.ToString());

0 commit comments

Comments
 (0)