Flatkit 추가 및 설정
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
#if !UNITY_2022_3_OR_NEWER
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace FlatKit {
|
||||
internal class BlitTexturePass : ScriptableRenderPass {
|
||||
public static readonly string CopyEffectShaderName = "Hidden/FlatKit/CopyTexture";
|
||||
|
||||
private readonly ProfilingSampler _profilingSampler;
|
||||
private readonly Material _effectMaterial;
|
||||
private readonly ScriptableRenderPassInput _passInput;
|
||||
private readonly Material _copyMaterial;
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
private RTHandle _temporaryColorTexture;
|
||||
#else
|
||||
private RenderTargetHandle _temporaryColorTexture;
|
||||
#endif
|
||||
|
||||
public BlitTexturePass(Material effectMaterial, bool useDepth, bool useNormals, bool useColor) {
|
||||
_effectMaterial = effectMaterial;
|
||||
var name = effectMaterial.name.Substring(effectMaterial.name.LastIndexOf('/') + 1);
|
||||
_profilingSampler = new ProfilingSampler($"Blit {name}");
|
||||
_passInput = (useColor ? ScriptableRenderPassInput.Color : ScriptableRenderPassInput.None) |
|
||||
(useDepth ? ScriptableRenderPassInput.Depth : ScriptableRenderPassInput.None) |
|
||||
(useNormals ? ScriptableRenderPassInput.Normal : ScriptableRenderPassInput.None);
|
||||
|
||||
#if !UNITY_2022_1_OR_NEWER
|
||||
_copyMaterial = CoreUtils.CreateEngineMaterial(CopyEffectShaderName);
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) {
|
||||
ConfigureInput(_passInput);
|
||||
base.Configure(cmd, cameraTextureDescriptor);
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) {
|
||||
#if !UNITY_2022_1_OR_NEWER
|
||||
ConfigureTarget(new RenderTargetIdentifier(renderingData.cameraData.renderer.cameraColorTarget, 0,
|
||||
CubemapFace.Unknown, -1));
|
||||
_temporaryColorTexture.Init("_EffectTexture");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Setup(RenderingData renderingData) {
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.depthBufferBits = 0;
|
||||
RenderingUtils.ReAllocateIfNeeded(ref _temporaryColorTexture, descriptor, wrapMode: TextureWrapMode.Clamp,
|
||||
name: "_EffectTexture");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
_temporaryColorTexture?.Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
|
||||
if (_effectMaterial == null) return;
|
||||
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, _profilingSampler)) {
|
||||
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
descriptor.depthBufferBits = 0;
|
||||
SetSourceSize(cmd, descriptor);
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
var cameraTargetHandle = renderingData.cameraData.renderer.cameraColorTargetHandle;
|
||||
// cmd.GetTemporaryRT(Shader.PropertyToID(_temporaryColorTexture.name), descriptor);
|
||||
#else
|
||||
var cameraTargetHandle = renderingData.cameraData.renderer.cameraColorTarget;
|
||||
cmd.GetTemporaryRT(_temporaryColorTexture.id, descriptor);
|
||||
#endif
|
||||
|
||||
// Also seen as `renderingData.cameraData.xr.enabled` and `#if ENABLE_VR && ENABLE_XR_MODULE`.
|
||||
if (renderingData.cameraData.xrRendering) {
|
||||
_effectMaterial.EnableKeyword("_USE_DRAW_PROCEDURAL"); // `UniversalRenderPipelineCore.cs`.
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
#pragma warning disable CS0618
|
||||
cmd.SetRenderTarget(_temporaryColorTexture);
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _effectMaterial, 0, 0);
|
||||
cmd.SetGlobalTexture("_EffectTexture", _temporaryColorTexture);
|
||||
cmd.SetRenderTarget(new RenderTargetIdentifier(cameraTargetHandle, 0, CubemapFace.Unknown, -1));
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _copyMaterial, 0, 0);
|
||||
#else
|
||||
cmd.SetRenderTarget(_temporaryColorTexture.Identifier());
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _effectMaterial, 0, 0);
|
||||
cmd.SetGlobalTexture("_EffectTexture", _temporaryColorTexture.Identifier());
|
||||
cmd.SetRenderTarget(new RenderTargetIdentifier(cameraTargetHandle, 0, CubemapFace.Unknown, -1));
|
||||
cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, _copyMaterial, 0, 0);
|
||||
#endif
|
||||
} else {
|
||||
_effectMaterial.DisableKeyword("_USE_DRAW_PROCEDURAL");
|
||||
// Note: `FinalBlitPass` has `cmd.SetRenderTarget` at this point, but it's unclear what that does.
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
cmd.Blit(cameraTargetHandle, _temporaryColorTexture, _effectMaterial, 0);
|
||||
cmd.Blit(_temporaryColorTexture, cameraTargetHandle);
|
||||
#else
|
||||
cmd.Blit(cameraTargetHandle, _temporaryColorTexture.Identifier(), _effectMaterial, 0);
|
||||
cmd.Blit(_temporaryColorTexture.Identifier(), cameraTargetHandle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
cmd.Clear();
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
// Copied from `PostProcessUtils.cs`.
|
||||
private static void SetSourceSize(CommandBuffer cmd, RenderTextureDescriptor desc) {
|
||||
float width = desc.width;
|
||||
float height = desc.height;
|
||||
if (desc.useDynamicScale) {
|
||||
width *= ScalableBufferManager.widthScaleFactor;
|
||||
height *= ScalableBufferManager.heightScaleFactor;
|
||||
}
|
||||
|
||||
cmd.SetGlobalVector("_SourceSize", new Vector4(width, height, 1.0f / width, 1.0f / height));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5985b630931f0e846b661c4bbc4d0a25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace FlatKit {
|
||||
public static class RendererFeatureUtils {
|
||||
public static void SetKeyword(Material material, string keyword, bool enabled) {
|
||||
if (material == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
if (material.shader != null) {
|
||||
// Unity 2021.2+ lets us query the shader's keyword space; only call SetKeyword when the symbol is actually declared
|
||||
// to avoid "keyword doesn't exist" errors on Unity 6.3.
|
||||
var keywordSpace = material.shader.keywordSpace;
|
||||
LocalKeyword localKeyword = keywordSpace.FindKeyword(keyword);
|
||||
if (localKeyword.isValid) {
|
||||
material.SetKeyword(localKeyword, enabled);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (enabled) {
|
||||
material.EnableKeyword(keyword);
|
||||
} else {
|
||||
material.DisableKeyword(keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a43bf53130f412f88de25122442bade
|
||||
timeCreated: 1720407925
|
||||
@@ -0,0 +1,251 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
using System;
|
||||
using UnityEngine.Rendering.RenderGraphModule;
|
||||
#endif
|
||||
|
||||
public class ScreenRenderPass : ScriptableRenderPass {
|
||||
private Material _passMaterial;
|
||||
private bool _requiresColor;
|
||||
private bool _isBeforeTransparents;
|
||||
private PassData _passData;
|
||||
private ProfilingSampler _profilingSampler;
|
||||
private RTHandle _copiedColor;
|
||||
|
||||
private static readonly Vector4 BlitScaleBias = new(1f, 1f, 0f, 0f);
|
||||
private static readonly MaterialPropertyBlock SharedPropertyBlock = new();
|
||||
private const string TexName = "_BlitTexture";
|
||||
private static readonly int BlitTextureShaderID = Shader.PropertyToID(TexName);
|
||||
private static readonly int BlitScaleBiasID = Shader.PropertyToID("_BlitScaleBias");
|
||||
|
||||
public void Setup(Material mat, bool requiresColor, bool isBeforeTransparents, string featureName,
|
||||
in RenderingData renderingData) {
|
||||
_passMaterial = mat;
|
||||
_requiresColor = requiresColor;
|
||||
_isBeforeTransparents = isBeforeTransparents;
|
||||
_profilingSampler ??= new ProfilingSampler(featureName);
|
||||
|
||||
var colorCopyDescriptor = renderingData.cameraData.cameraTargetDescriptor;
|
||||
colorCopyDescriptor.depthBufferBits = (int)DepthBits.None;
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
requiresIntermediateTexture = _requiresColor && !_isBeforeTransparents;
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref _copiedColor, colorCopyDescriptor, FilterMode.Point,
|
||||
TextureWrapMode.Clamp, name: "_FullscreenPassColorCopy");
|
||||
#elif UNITY_2022_3_OR_NEWER
|
||||
RenderingUtils.ReAllocateIfNeeded(ref _copiedColor, colorCopyDescriptor, name: "_FullscreenPassColorCopy");
|
||||
#endif
|
||||
|
||||
_passData ??= new PassData();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
_copiedColor?.Release();
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) {
|
||||
var resourceData = frameData.Get<UniversalResourceData>();
|
||||
var cameraData = frameData.Get<UniversalCameraData>();
|
||||
|
||||
if (_passMaterial == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resourceData.activeColorTexture.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_requiresColor && resourceData.isActiveTargetBackBuffer) {
|
||||
Debug.LogWarning("[Flat Kit] ScreenRenderPass requires sampling the active color buffer, but the renderer " +
|
||||
"is currently writing directly to the backbuffer. Enable an intermediate color target " +
|
||||
"(Renderer > Rendering > Intermediate Texture Mode = Always) or move the feature to an " +
|
||||
"earlier render event.");
|
||||
return;
|
||||
}
|
||||
|
||||
TextureHandle copySource = TextureHandle.nullHandle;
|
||||
|
||||
if (_requiresColor) {
|
||||
TextureDesc descriptor;
|
||||
if (resourceData.cameraColor.IsValid()) {
|
||||
descriptor = renderGraph.GetTextureDesc(resourceData.cameraColor);
|
||||
} else {
|
||||
descriptor = renderGraph.GetTextureDesc(resourceData.activeColorTexture);
|
||||
}
|
||||
|
||||
descriptor.name = "_FlatKit_FullScreenCopy";
|
||||
descriptor.clearBuffer = false;
|
||||
|
||||
TextureHandle copiedColor = renderGraph.CreateTexture(descriptor);
|
||||
|
||||
using (var builder = renderGraph.AddRasterRenderPass<CopyPassData>("FlatKit Copy Color", out var passData,
|
||||
_profilingSampler)) {
|
||||
passData.source = resourceData.activeColorTexture;
|
||||
builder.UseTexture(passData.source, AccessFlags.Read);
|
||||
builder.SetRenderAttachment(copiedColor, 0, AccessFlags.Write);
|
||||
builder.SetRenderFunc((CopyPassData data, RasterGraphContext ctx) => {
|
||||
Blitter.BlitTexture(ctx.cmd, data.source, BlitScaleBias, 0, false);
|
||||
});
|
||||
}
|
||||
|
||||
copySource = copiedColor;
|
||||
}
|
||||
|
||||
using (var builder = renderGraph.AddRasterRenderPass<MainPassData>(_profilingSampler.name, out var passData,
|
||||
_profilingSampler)) {
|
||||
passData.material = _passMaterial;
|
||||
passData.source = copySource;
|
||||
|
||||
if (passData.source.IsValid()) {
|
||||
builder.UseTexture(passData.source, AccessFlags.Read);
|
||||
}
|
||||
|
||||
var passInput = input;
|
||||
bool needsColor = (passInput & ScriptableRenderPassInput.Color) != ScriptableRenderPassInput.None;
|
||||
bool needsDepth = (passInput & ScriptableRenderPassInput.Depth) != ScriptableRenderPassInput.None;
|
||||
bool needsNormals = (passInput & ScriptableRenderPassInput.Normal) != ScriptableRenderPassInput.None;
|
||||
bool needsMotion = (passInput & ScriptableRenderPassInput.Motion) != ScriptableRenderPassInput.None;
|
||||
|
||||
if (needsColor && resourceData.cameraOpaqueTexture.IsValid()) {
|
||||
builder.UseTexture(resourceData.cameraOpaqueTexture);
|
||||
}
|
||||
|
||||
if (needsDepth && resourceData.cameraDepthTexture.IsValid()) {
|
||||
builder.UseTexture(resourceData.cameraDepthTexture);
|
||||
}
|
||||
|
||||
if (needsNormals && resourceData.cameraNormalsTexture.IsValid()) {
|
||||
builder.UseTexture(resourceData.cameraNormalsTexture);
|
||||
}
|
||||
|
||||
if (needsMotion && cameraData.renderer.SupportsMotionVectors()) {
|
||||
if (resourceData.motionVectorColor.IsValid()) {
|
||||
builder.UseTexture(resourceData.motionVectorColor);
|
||||
}
|
||||
|
||||
if (resourceData.motionVectorDepth.IsValid()) {
|
||||
builder.UseTexture(resourceData.motionVectorDepth);
|
||||
}
|
||||
}
|
||||
|
||||
builder.SetRenderAttachment(resourceData.activeColorTexture, 0, AccessFlags.Write);
|
||||
|
||||
builder.SetRenderFunc((MainPassData data, RasterGraphContext ctx) => {
|
||||
SharedPropertyBlock.Clear();
|
||||
|
||||
if (data.source.IsValid()) {
|
||||
SharedPropertyBlock.SetTexture(BlitTextureShaderID, data.source);
|
||||
}
|
||||
|
||||
SharedPropertyBlock.SetVector(BlitScaleBiasID, BlitScaleBias);
|
||||
|
||||
ctx.cmd.DrawProcedural(Matrix4x4.identity, data.material, 0, MeshTopology.Triangles, 3, 1,
|
||||
SharedPropertyBlock);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("This rendering path is for compatibility mode only (when Render Graph is disabled).", false)]
|
||||
#endif
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
|
||||
_passData.effectMaterial = _passMaterial;
|
||||
_passData.requiresColor = _requiresColor;
|
||||
_passData.isBeforeTransparents = _isBeforeTransparents;
|
||||
_passData.profilingSampler = _profilingSampler;
|
||||
_passData.copiedColor = _copiedColor;
|
||||
|
||||
ExecutePass(_passData, ref renderingData, ref context);
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
[Obsolete("This rendering path is for compatibility mode only (when Render Graph is disabled).", false)]
|
||||
#endif
|
||||
private static void ExecutePass(PassData passData, ref RenderingData renderingData,
|
||||
ref ScriptableRenderContext context) {
|
||||
var passMaterial = passData.effectMaterial;
|
||||
var requiresColor = passData.requiresColor;
|
||||
var copiedColor = passData.copiedColor;
|
||||
var profilingSampler = passData.profilingSampler;
|
||||
|
||||
if (passMaterial == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (renderingData.cameraData.isPreviewCamera) {
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBuffer cmd;
|
||||
bool releaseCommandBuffer;
|
||||
// Unity 6.3+ no longer exposes RenderingData.commandBuffer outside URP, so rely on pooled buffers there (and on pre-2022.3).
|
||||
|
||||
#if UNITY_6000_3_OR_NEWER
|
||||
cmd = CommandBufferPool.Get();
|
||||
releaseCommandBuffer = true;
|
||||
#elif UNITY_2022_3_OR_NEWER && !UNITY_6000_3_OR_NEWER
|
||||
cmd = renderingData.commandBuffer;
|
||||
releaseCommandBuffer = false;
|
||||
#else
|
||||
cmd = CommandBufferPool.Get();
|
||||
releaseCommandBuffer = true;
|
||||
#endif
|
||||
var cameraData = renderingData.cameraData;
|
||||
|
||||
using (new ProfilingScope(cmd, profilingSampler)) {
|
||||
if (requiresColor) {
|
||||
#if UNITY_6000_3_OR_NEWER
|
||||
RTHandle source = cameraData.renderer.cameraColorTargetHandle;
|
||||
Blitter.BlitCameraTexture(cmd, source, copiedColor);
|
||||
#elif UNITY_2022_3_OR_NEWER && !UNITY_6000_3_OR_NEWER
|
||||
RTHandle source = passData.isBeforeTransparents
|
||||
? cameraData.renderer.GetCameraColorBackBuffer(cmd)
|
||||
: cameraData.renderer.cameraColorTargetHandle;
|
||||
Blitter.BlitCameraTexture(cmd, source, copiedColor);
|
||||
#else
|
||||
RenderTargetIdentifier source = cameraData.renderer.cameraColorTarget;
|
||||
cmd.Blit(source, copiedColor);
|
||||
#endif
|
||||
|
||||
passMaterial.SetTexture(BlitTextureShaderID, copiedColor);
|
||||
}
|
||||
|
||||
#if UNITY_6000_3_OR_NEWER
|
||||
CoreUtils.SetRenderTarget(cmd, cameraData.renderer.cameraColorTargetHandle);
|
||||
#elif UNITY_2022_3_OR_NEWER && !UNITY_6000_3_OR_NEWER
|
||||
CoreUtils.SetRenderTarget(cmd, cameraData.renderer.GetCameraColorBackBuffer(cmd));
|
||||
#else
|
||||
CoreUtils.SetRenderTarget(cmd, cameraData.renderer.cameraColorTarget);
|
||||
#endif
|
||||
CoreUtils.DrawFullScreen(cmd, passMaterial);
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
|
||||
if (releaseCommandBuffer) {
|
||||
CommandBufferPool.Release(cmd);
|
||||
} else {
|
||||
cmd.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PassData {
|
||||
internal Material effectMaterial;
|
||||
internal bool requiresColor;
|
||||
internal bool isBeforeTransparents;
|
||||
public ProfilingSampler profilingSampler;
|
||||
public RTHandle copiedColor;
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
private class CopyPassData {
|
||||
internal TextureHandle source;
|
||||
}
|
||||
|
||||
private class MainPassData {
|
||||
internal TextureHandle source;
|
||||
internal Material material;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4352bba7c98b4f53bdc3856f0edf40f4
|
||||
timeCreated: 1691382047
|
||||
@@ -0,0 +1,71 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace FlatKit {
|
||||
public static class SubAssetMaterial {
|
||||
public static Material GetOrCreate(Object settings, string shaderName) {
|
||||
// Return if called from OnValidate.
|
||||
{
|
||||
var stackTrace = new System.Diagnostics.StackTrace();
|
||||
var frames = stackTrace.GetFrames();
|
||||
if (frames != null) {
|
||||
if (frames.Select(frame => frame.GetMethod())
|
||||
.Any(method => method != null && method.Name == "OnValidate")) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var settingsPath = AssetDatabase.GetAssetPath(settings);
|
||||
var subAssets = AssetDatabase.LoadAllAssetsAtPath(settingsPath);
|
||||
const string subAssetName = "Effect Material";
|
||||
var existingMaterial = subAssets.FirstOrDefault(o => o.name == subAssetName) as Material;
|
||||
if (existingMaterial != null) return existingMaterial;
|
||||
|
||||
var shader = Shader.Find(shaderName);
|
||||
if (shader == null) return null;
|
||||
|
||||
var newMaterial = new Material(shader) { name = subAssetName };
|
||||
try {
|
||||
AssetDatabase.AddObjectToAsset(newMaterial, settings);
|
||||
AssetDatabase.ImportAsset(settingsPath);
|
||||
}
|
||||
catch {
|
||||
// ignored
|
||||
}
|
||||
|
||||
return newMaterial;
|
||||
}
|
||||
|
||||
public static void AlwaysInclude(string shaderName) {
|
||||
var shader = Shader.Find(shaderName);
|
||||
if (shader == null) return;
|
||||
var graphicsSettingsObj =
|
||||
AssetDatabase.LoadAssetAtPath<GraphicsSettings>("ProjectSettings/GraphicsSettings.asset");
|
||||
if (graphicsSettingsObj == null) return;
|
||||
var serializedObject = new SerializedObject(graphicsSettingsObj);
|
||||
var arrayProp = serializedObject.FindProperty("m_AlwaysIncludedShaders");
|
||||
bool hasShader = false;
|
||||
for (int i = 0; i < arrayProp.arraySize; ++i) {
|
||||
var arrayElem = arrayProp.GetArrayElementAtIndex(i);
|
||||
if (shader == arrayElem.objectReferenceValue) {
|
||||
hasShader = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasShader) {
|
||||
int arrayIndex = arrayProp.arraySize;
|
||||
arrayProp.InsertArrayElementAtIndex(arrayIndex);
|
||||
var arrayElem = arrayProp.GetArrayElementAtIndex(arrayIndex);
|
||||
arrayElem.objectReferenceValue = shader;
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57832b6c4cbc426896f2230d92a1f228
|
||||
timeCreated: 1669323534
|
||||
Reference in New Issue
Block a user