Check if HDRP is present in project (C#)

So I am writing this custom script that allows you to use either standard or HDRP pipelines through my custom editor, however when importing the script into a project without HDRP in Unity 2019, i get the error below:

The type or namespace name ‘HDPipeline’ does not exist in the namespace ‘UnityEngine.Experimental.Rendering’ (are you missing an assembly reference?)

I need a way to check around the using blah blah; calls at the top, such as when checking if using certain unity version. I.e if_unity_5, etc.

Any thoughts on this would be really helpful, thanks!

You can make Unity make custom defines via assembly definition file if there’s some specific package installed. I’m not sure how robust this is as I’ve heard one user saying it didn’t work for him but could have been also something that user did differently.

Here’s what I’ve used to check if there’s SRP core package >= v5.0 installed:

More info about asmdef’s here: Unity - Manual: Assembly definitions

The best way i found so far is this:

using UnityEngine.Rendering;

if(GraphicsSettings.renderPipelineAsset == null){

   //do action

} else {
          
   //do action
          
}
1 Like

Your example would have worked in my use case (I only needed to know if there’s SRP present or not), but it wouldn’t really work if you need to depend on HDRP specifically, you’d get that else triggered also if there’s URP Asset assigned.

Well you could just replace “null” with the value you’re looking for (i.e URP, SRP, etc.) :slight_smile:

In my case i just needed to know if the HDRP pipeline is active/assigned or not and if not, then de-active certain features for my editor script.

I don’t really see how this is possible without having URP or HDRP package installed as afaik you’d need these packages installed to get the SRP specific compare for it, meaning it would still fail if one didn’t have any SRP installed to the project.

But if you don’t really need the specifics if the SRP is URP or HDRP, what you have there would be perfectly fine :slight_smile:

edit-> found one way: Check if HDRP is present in project (C#) - Unity Engine - Unity Discussions

1 Like

You could just use the #if statements (i.e #if HDPipeline) to check for

using UnityEngine.Experimental.Rendering.HDPipeline; (or whatever pipeline you want to use)

Then in the actual functions you’d use what i mentioned above, if anything you can always search for the pipeline files in and if found, check a bool or something. Of course referencing them manually would be more ideal, then calling to see if those values are null but for something more robust like an editor window/extension, yea finding it on the fly is a bit more complex :3

And for this you’d need the workaround I mentioned on the first response here (and then you could just use that directly unless you really need runtime branching).

Nah, you can have those #if statements and using blah blah; references present without having those pipelines installed.

I looked into GraphicsSettings.currentRenderPipeline and you could essentially detect the installed SRP type from it’s GetType but you can only compare the string as otherwise you’ll bring in dependency that requires you to have the package installed.

So basically you could have something like:

if (GraphicsSettings.currentRenderPipeline)
{
   if (GraphicsSettings.currentRenderPipeline.GetType().ToString().Contains("HighDefinition"))
   {
      Debug.Log("HDRP active");
   }
   else
   {
      Debug.Log("URP active");
   }
}
else
{
   Debug.Log("Built-in RP active");
}
2 Likes

Ok i’ve played with this some more and there’s a few things:

  1. currentRenderPipeline is only available in 2019.4, for 2019.2 you’d use renderPipelineAsset
  2. After contains() for currentRenderPipeline it would be “HighDefinition” but for renderPipelineAsset it would be “HDRenderPipelineAsset”

Here’s what i came up with changing your code slightly:

    private void CheckPipeline(){
 
        if(GraphicsSettings.renderPipelineAsset) {
 
           if(GraphicsSettings.renderPipelineAsset.GetType().ToString().Contains("HDRenderPipelineAsset")) {
    
              Debug.Log("HDRP active");
    
           //HighDefinition
           } else {
    
              Debug.Log("URP active");
       
           }//HighDefinition
    
        //renderPipelineAsset
        } else {
 
           Debug.Log("Built-in RP active");
 
        }//renderPipelineAsset

    }//CheckPipeline

And then accessing HDRP data ((int)renderPipeline can be anything but i’m using an enum):

                       #if HDPipeline
                  
                        if((int)renderPipeline == 1){

                            lightsTemp.GetComponent<AdditionalShadowData>().shadowResolution = minShadow_Res;

                        }//renderPipeline == 1

                        #endif

So utilizing the #if statements, if HDRP is not present, then it will simply not utilize that part of the code and will not throw errors :slight_smile:

This is likely from the namespace change on 2019.3 for HDRP. They changed that just prior to release so it wouldn’t exist on 2019.2 yet.

Actually it’s because of the different value change, since there’s no currentRenderPipeline for 2019.2

1 Like

You really have to question everything, right? :smile:

The difference here is that you are now comparing the last part of the string where my original script compared the actual rendering namespace. They changed this in jump from 2019.2 → 2019.3 when they moved the namespace out of experimental.

Just for clarity. Both currentRenderPipeline and renderPipelineAsset return same object which is always RenderPipelineAsset type, there’s no difference on the result or naming your get between these two.

For 2019.3+ the GetType for HDRP asset would be:
UnityEngine.Rendering.HighDefinition.HDRenderPipelineAsset

2019.2 and earlier would return something like:
UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipelineAsset

If you need the script to be compatible on HDRP pre-release versions like 2019.2, then you can check if the string has HDRenderPipelineAsset, I just didn’t account people would use 2019.2 anymore as it’s 100% unsupported by Unity now.

1 Like

Actually what i’m pointing out is that there’s a value change and the best approach for various 2019 versions would be to use renderPipelineAsset instead of currentRenderPipeline, as currentRenderPipeline is only available after 2019.2.

So obviously to utilize this script across multiple versions, renderPipelineAsset is the value we want to use.

No renderPipelineAsset does not return the same value as currentRenderPipeline as they call different functions and return back different values.

However what works best for you is up to you, i’ve already finished coding my system and found the script i provided above to work exactly as intended :wink:

This also might be helpful.
Put this script into ‘Editor’ folder:

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;

[InitializeOnLoad]
public class RenderingPipelineDefines
{
    enum PipelineType
    {
        Unsupported,
        BuiltInPipeline,
        UniversalPipeline,
        HDPipeline
    }

    static RenderingPipelineDefines()
    {
        UpdateDefines();
    }

    /// <summary>
    /// Update the unity pipeline defines for URP
    /// </summary>
    static void UpdateDefines()
    {
        var pipeline = GetPipeline();

        if (pipeline == PipelineType.UniversalPipeline)
        {
            AddDefine("UNITY_PIPELINE_URP");
        }
        else
        {
            RemoveDefine("UNITY_PIPELINE_URP");
        }
        if (pipeline == PipelineType.HDPipeline)
        {
            AddDefine("UNITY_PIPELINE_HDRP");
        }
        else
        {
            RemoveDefine("UNITY_PIPELINE_HDRP");
        }
    }


    /// <summary>
    /// Returns the type of renderpipeline that is currently running
    /// </summary>
    /// <returns></returns>
    static PipelineType GetPipeline()
    {
#if UNITY_2019_1_OR_NEWER
        if (GraphicsSettings.renderPipelineAsset != null)
        {
            // SRP
            var srpType = GraphicsSettings.renderPipelineAsset.GetType().ToString();
            if (srpType.Contains("HDRenderPipelineAsset"))
            {
                return PipelineType.HDPipeline;
            }
            else if (srpType.Contains("UniversalRenderPipelineAsset") || srpType.Contains("LightweightRenderPipelineAsset"))
            {
                return PipelineType.UniversalPipeline;
            }
            else return PipelineType.Unsupported;
        }
#elif UNITY_2017_1_OR_NEWER
        if (GraphicsSettings.renderPipelineAsset != null) {
            // SRP not supported before 2019
            return PipelineType.Unsupported;
        }
#endif
        // no SRP
        return PipelineType.BuiltInPipeline;
    }

    /// <summary>
    /// Add a custom define
    /// </summary>
    /// <param name="define"></param>
    /// <param name="buildTargetGroup"></param>
    static void AddDefine(string define)
    {
        var definesList = GetDefines();
        if (!definesList.Contains(define))
        {
            definesList.Add(define);
            SetDefines(definesList);
        }
    }

    /// <summary>
    /// Remove a custom define
    /// </summary>
    /// <param name="_define"></param>
    /// <param name="_buildTargetGroup"></param>
    public static void RemoveDefine(string define)
    {
        var definesList = GetDefines();
        if (definesList.Contains(define))
        {
            definesList.Remove(define);
            SetDefines(definesList);
        }
    }

    public static List<string> GetDefines()
    {
        var target = EditorUserBuildSettings.activeBuildTarget;
        var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(target);
        var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
        return defines.Split(';').ToList();
    }

    public static void SetDefines(List<string> definesList)
    {
        var target = EditorUserBuildSettings.activeBuildTarget;
        var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(target);
        var defines = string.Join(";", definesList.ToArray());
        PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
    }
}

This code will set handy defines for your project. And you can use them like this:

#if UNITY_PIPELINE_URP
// code for URP
#elif UNITY_PIPELINE_HDRP
// code for HDRP
#else
// code for Stardard Pipeline
#endif
6 Likes