URP / Volume.cs - how to access the override settings at runtime via script?

I’m using 2019.3.0f5 with URP (2D pixel perfect renderer) and volume.cs for adding post-processing effects to my scene.

How can I access the override settings of the PP-profile at runtime via script?
I have searched everywhere for documentation, and while there is quite a bit on volume-layers and LWRP, I cannot find the correct procedures using URP with volume.cs.

Let’s say I want to change the bloom intensity at runtime every time the player takes damage.
Any ideas? Thanks.

1 Like

I’ve been looking all over for this too and was just about to make a similar post. If anyone can provide some guidance it would be great!

1 Like

Personally I’m using the following approach.

I get a reference to the Volume component either in runtime or by assigning it in editor.
Once I have a reference, to the volume component I can simply use the following code to get a reference to a VolumeComponent.

UnityEngine.Rendering.VolumeProfile volumeProfile = GetComponent<UnityEngine.Rendering.Volume>()?.profile;
if(!volumeProfile) throw new System.NullReferenceException(nameof(UnityEngine.Rendering.VolumeProfile));

// You can leave this variable out of your function, so you can reuse it throughout your class.
UnityEngine.Rendering.Universal.Vignette vignette;

if(!volumeProfile.TryGet(out vignette)) throw new System.NullReferenceException(nameof(vignette));

vignette.intensity.Override(0.5f);

You can cache the VolumeComponent, so you only need to retrieve it once (for example in your Awake).

Edit: Added the appropriate namespaces to VolumeProfile and Volume. Also added a comment for a bit more clarity.

37 Likes

Wonderful solution, works like a charm. Many thanks!

Cheers Arfus!

For anyone who ran into a similar issue, I was using “UnityEngine.Rendering.PostProcessing” instead of “UnityEngine.Rendering.Universal” for effects like Vignette, hence volumeProfile.TryGet() wasn’t working. I needed to use the latter for URP, as Arfus’ answer shows.

4 Likes

Np! And yes, my exact solution was an implementation for URP. That’s the implementation I gave as that’s the title of the original post :wink:

Edit: Although, if I recall correctly, the approach for the Post Processing Stack V2 is quite similar to this. But I do not have a code sample for that.

Ah, I wasn’t clear, the URP solution is what I was looking for. I didn’t know that UnityEngine.Rendering.PostProcessing didn’t work with URP post-processing until I saw your answer. Thanks for clearly pointing out the correct namespace in your answer!

2 Likes

Np, glad it works for you :slight_smile:

1 Like

I can’t find my profile and it throws all those null reference errors, can you help?
Edit: i meant that the script isn’t accessing my profile (maybe because i have multiple) so in the first line itself is there an elaborative way i can access it?

You need to attach the component you created containing my code, onto the SAME gameobject as the Volume component. If you read the code, you can see I make use of GetComponent. This only works when attached onto the same gameobject.

This worked great, thank you!

Thank you! Finally found something that works

I’ve been searching everywhere for this solution! Finally something that actually works! Thank you!!!

This was a godsend, I was accessing it completely wrongly, but now that I know how it’s trivial! Gonna put this to good use on the options screen.

I am trying to modify the Weight value of the volume and I’ve tried this approach, but it only works to affect the profiles within. do you know how to access just the Weight value in the volume?
It seems simple, but there doesn’t seem to be a Weight value inside the Volume (despite the documentation saying it does) and it’s driving me nuts @_@

var volume = gameObject.GetComponent<Volume>();

volume.weight(<<<this weight does not exist!!!)

Thank you!!

Is there any way to modify postExposure value on Volume in runtime?

Thanks for this, Arfus! I, like many others, have been searching all over for this.

I’m wondering if you can help me though. I’m only able to grab the Override at Start(), but somehow lose the reference when I need it later on. In my case, I’m grabbing the LensDistortion Override. I test it at Start() and can see it works. But when the Coroutine is called where I actually manipulate the LensDistortion, I get a Null reference exception.
I tested all three: I’m getting Null Ref Exceptions for the LensDistortion, the VolumeProfile, all the way back to the Volume itself…even though the Inspector acknowledges the reference to the correct GameObject.

public UnityEngine.Rendering.Volume volume;         //just using this for testing
    public UnityEngine.Rendering.VolumeProfile volumeProfile;
    public UnityEngine.Rendering.Universal.LensDistortion lensDistortion;

    void Start()
    {
        volume = GetComponent<Volume>();
        if (!volume) throw new System.NullReferenceException(nameof(UnityEngine.Rendering.Volume));

        volumeProfile = GetComponent<UnityEngine.Rendering.Volume>()?.profile;
        if (!volumeProfile) throw new System.NullReferenceException(nameof(UnityEngine.Rendering.VolumeProfile));

        if (!volumeProfile.TryGet(out lensDistortion)) throw new System.NullReferenceException(nameof(lensDistortion));
       
        lensDistortion.intensity.Override(0.5f);
    }

    public IEnumerator TimeWarpRoutine()
    {
        lensDistortion.intensity.Override(0.0f);

FIX: I finally figured this out.

A quick recap: I was using Post-Processing to set up a few effects. I decided to add URP, which renders Post-Processing useless. I still had a Post-Processing GameObject (that was turned off) in case URP wasn’t going to work for me. And then I was running into the above problems (hindsight is 20/20)…

I considered other comments / threads’ suggestions of removing Post-Processing and URP and reinstalling URP. In my case, I noticed a warning (not error) in my Console that something was trying to access my Post-Processing Volume but couldn’t find it. There was no specific stack-trace to follow so I did a solution-wide search for the term “Post-Processing” and couldn’t find any of my scripts trying to access that Post-Processing Volume. This is when I determined something on the Unity side might be trying to access my post-processing volume based on default settings when it was originally installed. I relented that I may have to remove both packages and re-install URP; though I was worried about having to set up the Global Volume again and make sure it was all done correctly, because clearly that side of it was working at Start() but somehow I was losing the reference to the Global Volume sometime during Runtime.

This is what I actually did: I removed the Post-Processing Volume. That’s it. I tested it again and it worked. Clearly, Unity was still trying to access it based on default settings. I didn’t have to remove and reinstall URP. That was my case. I hope this helps somebody who was having additional issues like I was.

Thanks again to Arfus for the original solution for accessing Overrides while using URP.

THAKN YOU so much!!! Dont know the principle yet, but adding “.Override” took effect!!! Searching for hours and finally resolved I’m soooo happy…