Skip to content

Commit

Permalink
feat(Utility): add pipeline material applier component
Browse files Browse the repository at this point in the history
The PipelineMaterialApplier will set the Materials on a given Renderer
based on the current render pipeline being used. It gets the materials
to apply from a given list of materials that has a string group name
that matches the desired render pipeline name.

If no render pipeline is provided then the matched name will be:

* `default`

There is also an editor menu item that will attempt to find all
PipelineMaterialApplier components in the scene and run them to
ensure all materials on the renderers are updated to match the current
render pipeline.
  • Loading branch information
thestonefox committed Apr 3, 2023
1 parent 4b98f48 commit bf82afb
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Editor/Utility/ScenePipelineMaterialApplier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Zinnia.Utility
{
#if UNITY_2019_2_OR_NEWER
using UnityEditor;
#endif
using UnityEngine;

public class ScenePipelineMaterialApplier : ScriptableObject
{
#if UNITY_2019_2_OR_NEWER
[MenuItem("Window/Zinnia/Apply Pipeline Materials", false, 51)]
private static void AddSpatialTargetsDispatcher()
{
foreach (PipelineMaterialApplier current in FindObjectsOfType<PipelineMaterialApplier>(true))
{
current.ApplyMaterialsToRenderer();
}
}
#endif
}
}
11 changes: 11 additions & 0 deletions Editor/Utility/ScenePipelineMaterialApplier.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

124 changes: 124 additions & 0 deletions Runtime/Utility/PipelineMaterialApplier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
namespace Zinnia.Utility
{
using System;
using System.Text.RegularExpressions;
using UnityEngine;
#if UNITY_2019_1_OR_NEWER
using UnityEngine.Rendering;
#endif

[ExecuteInEditMode]
/// <summary>
/// Applies the relevant <see cref="Material"/> collection to the specified <see cref="Renderer"/> based on the render pipeline being used by the project.
/// </summary>
/// <remarks>
/// This is automatically run in the Unity editor when the script is awoken in the editor window. It does not run automatically during play mode.
/// </remarks>
public class PipelineMaterialApplier : MonoBehaviour
{
[Serializable]
public class PipelineMaterials
{
[Tooltip("The name of the pipeline to match the Material collection to.")]
[SerializeField]
private string pipelineName = "";
/// <summary>
/// The name of the pipeline to match the <see cref="Material"/> collection to.
/// </summary>
public string PipelineName
{
get
{
return pipelineName;
}
set
{
pipelineName = value;
}
}

[Tooltip("The Material collection to set the Renderer materials to if using this render pipeline.")]
[SerializeField]
private Material[] materials = new Material[0];
/// <summary>
/// The <see cref="Material"/> collection to set the <see cref="Renderer"/> materials to if using this render pipeline.
/// </summary>
public Material[] Materials
{
get
{
return materials;
}
set
{
materials = value;
}
}
}

[Tooltip("The Renderer to update the materials on.")]
[SerializeField]
private Renderer target;
/// <summary>
/// The <see cref="Renderer"/> to update the materials on.
/// </summary>
public Renderer Target
{
get
{
return target;
}
set
{
target = value;
}
}

[Tooltip("The collection of PipelineMaterials to apply if the current element Pipeline Name matches the currently used render pipeline.")]
[SerializeField]
private PipelineMaterials[] pipelines = new PipelineMaterials[0];
/// <summary>
/// The collection of <see cref="PipelineMaterials"/> to apply if the current element Pipeline Name matches the currently used render pipeline.
/// </summary>
public PipelineMaterials[] Pipelines
{
get
{
return pipelines;
}
set
{
pipelines = value;
}
}

/// <summary>
/// Applies the relevant pipeline <see cref="Material"/> collection to the <see cref="Target"/>.
/// </summary>
public virtual void ApplyMaterialsToRenderer()
{
if (Target == null)
{
return;
}

#if UNITY_2019_1_OR_NEWER && !ZINNIA_IGNORE_PIPELINE_MATERIALS
foreach (PipelineMaterials pipeline in Pipelines)
{
if (Regex.IsMatch(GraphicsSettings.currentRenderPipeline != null ? GraphicsSettings.currentRenderPipeline.name : "default", pipeline.PipelineName))
{
Target.sharedMaterials = pipeline.Materials;
break;
}
}
#endif
}

protected virtual void Awake()
{
#if UNITY_EDITOR
ApplyMaterialsToRenderer();
#endif
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Utility/PipelineMaterialApplier.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bf82afb

Please sign in to comment.