c# - 在运行时更改颜色查找纹理

标签 c# unity-game-engine graphics post-processing urp

我正在尝试更改 URP 中后处理堆栈的颜色查找模块的纹理和贡献。

最初我尝试简单地修改该值,如下所示:

private void SetTheme(int index)
{
    if (index > 0 && ThemeColorLookups.Length > index)
    {
        if (_globalVolume.profile.TryGet(out ColorLookup cl))
        {
            cl.texture = new TextureParameter(ThemeColorLookups[index], true);
        }
    }
    else
    {
        if (_globalVolume.profile.TryGet(out ColorLookup cl))
        {
            cl.texture = new TextureParameter(null, true);
        }
    }
}

private void SetThemeIntensity(int value)
{
    if (_globalVolume.profile.TryGet(out ColorLookup cl))
    {
        cl.contribution = new ClampedFloatParameter(value / 100f, 0, 1, true);
    }
}

这确实改变了在编辑器中检查体积时的值,但是游戏或场景 View 中没有反射(reflect)任何变化。

我还尝试将 Color Lookup 实例完全替换为新实例,这或多或少会导致与前一种方法相同的行为。

private int _currentThemeIndex;
private float _currentThemeIntensity;

private void SetTheme(int index)
{
    if (index > 0 && ThemeColorLookups.Length > index)
    {
        _globalVolume.profile.Remove<ColorLookup>();

        var cl = _globalVolume.profile.Add<ColorLookup>();
        cl.contribution = new ClampedFloatParameter(_currentThemeIntensity, 0, 1, true);
        cl.texture = new TextureParameter(ThemeColorLookups[index], true);

        _currentThemeIndex = index;
    }
    else
    {
        _currentThemeIndex = 0;
        _globalVolume.profile.Remove<ColorLookup>();
    }
}

private void SetThemeIntensity(int value)
{
    _currentThemeIntensity = value / 100f;

    if (_currentThemeIndex == 0) { return; }

    _globalVolume.profile.Remove<ColorLookup>();

    var cl = _globalVolume.profile.Add<ColorLookup>();
    cl.contribution = new ClampedFloatParameter(value/100f, 0, 1, true);
    cl.texture = new TextureParameter(ThemeColorLookups[_currentThemeIndex], true);
}

为什么这些变化没有及时反射(reflect)出来?如果我在运行时手动修改这些值,则会显示正确的纹理和贡献,但是对代码执行“相同”操作只会产生编辑器更改。

值得注意的是,在执行这段代码后,每当您拖动 UI slider 时都会发生这种情况,即使我尝试通过编辑器手动修改值,也不会发生任何事情(显然检查器更新除外)。所以在我重放场景之前它基本上会变砖。此时我可以再次手动修改这些值,但是这在我的情况下是不可取的。我想通过代码完全控制这两个公开的属性。

Unity 版本 - 使用 URP 的 2021.2.19f1

最佳答案

虽然Merijn Kersten的答案是有一种更好的方法可以在运行时更改纹理。

在您提供的代码中,您尝试修改 _globalVolume 对象上的 ColorLookup 组件,但在运行时修改对象上的值不会自动更新场景中的对象。

修改值后,您可以在 _globalVolume 对象上使用 SetDirty 方法。这将告诉 Unity 保存更改并更新场景中的对象。

{
    if (index > 0 && ThemeColorLookups.Length > index)
    {
        if (_globalVolume.profile.TryGet(out ColorLookup cl))
        {
            cl.texture = new TextureParameter(ThemeColorLookups[index], true);
            _globalVolume.SetDirty();
        }
    }
    else
    {
        if (_globalVolume.profile.TryGet(out ColorLookup cl))
        {
            cl.texture = new TextureParameter(null, true);
            _globalVolume.SetDirty();
        }
    }
}

private void SetThemeIntensity(int value)
{
    if (_globalVolume.profile.TryGet(out ColorLookup cl))
    {
        cl.contribution = new ClampedFloatParameter(value / 100f, 0, 1, true);
        _globalVolume.SetDirty();
    }
}

Merijn Kersten的解决方案之所以有效,是因为他直接将 Texture 对象分配给 texture.value 属性,这意味着他正在修改作为其一部分的现有 TextureParameter 对象ColorLookup 组件的。 Unity 将自动更新它,因为场景中存在该对象。

关于c# - 在运行时更改颜色查找纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74710469/

相关文章:

iphone - 需要 iPhone 应用程序的指针,其中图形对象会跟随您的手指

Java AWT 故障排除

c# - 如何调试从 BackgroundWorker 调用的代码中未处理的异常?

c# - 私有(private) WPF 依赖属性

c# - 在 iPhone 上运行时,RestSharp 与 Unity3d 一起崩溃

c# - 移植Android时如何处理高分辨率设备?

c# - 未找到类型或命名空间名称

c# - 从 C# 中的键/值集合中读取特定的 HTTP header 值

c# - 如何使用 c# MongoCursor 获取不同的值?

java - 单击鼠标后绘制椭圆