Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Check if HDRP is present in project (C#)

Discussion in 'Graphics Experimental Previews' started by dizzymediainc, Jul 10, 2020.

  1. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    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!
     
  2. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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:
    https://github.com/0lento/OcclusionProbes/blob/package/OcclusionProbes/OcclusionProbes.asmdef

    More info about asmdef's here: https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html
     
  3. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    The best way i found so far is this:


    Code (CSharp):
    1.            
    2.  
    3. using UnityEngine.Rendering;
    4.  
    5. if(GraphicsSettings.renderPipelineAsset == null){
    6.  
    7.    //do action
    8.  
    9. } else {
    10.          
    11.    //do action
    12.          
    13. }
     
    rz_0lento likes this.
  4. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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.
     
  5. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    Well you could just replace "null" with the value you're looking for (i.e URP, SRP, etc.) :)

    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.
     
    Last edited: Jul 13, 2020
  6. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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 :)

    edit-> found one way: https://forum.unity.com/threads/check-if-hdrp-is-present-in-project-c.928746/#post-6088551
     
    Last edited: Jul 14, 2020
    WSWhitehouse likes this.
  7. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    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
     
  8. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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).
     
  9. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    Nah, you can have those #if statements and using blah blah; references present without having those pipelines installed.
     
  10. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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:
    Code (csharp):
    1. if (GraphicsSettings.currentRenderPipeline)
    2. {
    3.    if (GraphicsSettings.currentRenderPipeline.GetType().ToString().Contains("HighDefinition"))
    4.    {
    5.       Debug.Log("HDRP active");
    6.    }
    7.    else
    8.    {
    9.       Debug.Log("URP active");
    10.    }
    11. }
    12. else
    13. {
    14.    Debug.Log("Built-in RP active");
    15. }
     
    cyoung2020 and dizzymediainc like this.
  11. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    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:

    Code (CSharp):
    1.     private void CheckPipeline(){
    2.  
    3.         if(GraphicsSettings.renderPipelineAsset) {
    4.  
    5.            if(GraphicsSettings.renderPipelineAsset.GetType().ToString().Contains("HDRenderPipelineAsset")) {
    6.    
    7.               Debug.Log("HDRP active");
    8.    
    9.            //HighDefinition
    10.            } else {
    11.    
    12.               Debug.Log("URP active");
    13.        
    14.            }//HighDefinition
    15.    
    16.         //renderPipelineAsset
    17.         } else {
    18.  
    19.            Debug.Log("Built-in RP active");
    20.  
    21.         }//renderPipelineAsset
    22.  
    23.     }//CheckPipeline
    And then accessing HDRP data ((int)renderPipeline can be anything but i'm using an enum):

    Code (CSharp):
    1.                        #if HDPipeline
    2.                  
    3.                         if((int)renderPipeline == 1){
    4.  
    5.                             lightsTemp.GetComponent<AdditionalShadowData>().shadowResolution = minShadow_Res;
    6.  
    7.                         }//renderPipeline == 1
    8.  
    9.                         #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 :)
     
    Last edited: Jul 16, 2020
  12. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    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.
     
  13. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    Actually it's because of the different value change, since there's no currentRenderPipeline for 2019.2
     
    PutridEx likes this.
  14. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    You really have to question everything, right? :D

    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.
     
    PutridEx likes this.
  15. dizzymediainc

    dizzymediainc

    Joined:
    Apr 6, 2014
    Posts:
    426
    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 ;)
     
  16. MUGIK

    MUGIK

    Joined:
    Jul 2, 2015
    Posts:
    476
    This also might be helpful.
    Put this script into 'Editor' folder:
    https://gist.github.com/cjaube/944b0d5221808c2a761d616f29deaf49

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using System.Linq;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Rendering;
    6.  
    7. [InitializeOnLoad]
    8. public class RenderingPipelineDefines
    9. {
    10.     enum PipelineType
    11.     {
    12.         Unsupported,
    13.         BuiltInPipeline,
    14.         UniversalPipeline,
    15.         HDPipeline
    16.     }
    17.  
    18.     static RenderingPipelineDefines()
    19.     {
    20.         UpdateDefines();
    21.     }
    22.  
    23.     /// <summary>
    24.     /// Update the unity pipeline defines for URP
    25.     /// </summary>
    26.     static void UpdateDefines()
    27.     {
    28.         var pipeline = GetPipeline();
    29.  
    30.         if (pipeline == PipelineType.UniversalPipeline)
    31.         {
    32.             AddDefine("UNITY_PIPELINE_URP");
    33.         }
    34.         else
    35.         {
    36.             RemoveDefine("UNITY_PIPELINE_URP");
    37.         }
    38.         if (pipeline == PipelineType.HDPipeline)
    39.         {
    40.             AddDefine("UNITY_PIPELINE_HDRP");
    41.         }
    42.         else
    43.         {
    44.             RemoveDefine("UNITY_PIPELINE_HDRP");
    45.         }
    46.     }
    47.  
    48.  
    49.     /// <summary>
    50.     /// Returns the type of renderpipeline that is currently running
    51.     /// </summary>
    52.     /// <returns></returns>
    53.     static PipelineType GetPipeline()
    54.     {
    55. #if UNITY_2019_1_OR_NEWER
    56.         if (GraphicsSettings.renderPipelineAsset != null)
    57.         {
    58.             // SRP
    59.             var srpType = GraphicsSettings.renderPipelineAsset.GetType().ToString();
    60.             if (srpType.Contains("HDRenderPipelineAsset"))
    61.             {
    62.                 return PipelineType.HDPipeline;
    63.             }
    64.             else if (srpType.Contains("UniversalRenderPipelineAsset") || srpType.Contains("LightweightRenderPipelineAsset"))
    65.             {
    66.                 return PipelineType.UniversalPipeline;
    67.             }
    68.             else return PipelineType.Unsupported;
    69.         }
    70. #elif UNITY_2017_1_OR_NEWER
    71.         if (GraphicsSettings.renderPipelineAsset != null) {
    72.             // SRP not supported before 2019
    73.             return PipelineType.Unsupported;
    74.         }
    75. #endif
    76.         // no SRP
    77.         return PipelineType.BuiltInPipeline;
    78.     }
    79.  
    80.     /// <summary>
    81.     /// Add a custom define
    82.     /// </summary>
    83.     /// <param name="define"></param>
    84.     /// <param name="buildTargetGroup"></param>
    85.     static void AddDefine(string define)
    86.     {
    87.         var definesList = GetDefines();
    88.         if (!definesList.Contains(define))
    89.         {
    90.             definesList.Add(define);
    91.             SetDefines(definesList);
    92.         }
    93.     }
    94.  
    95.     /// <summary>
    96.     /// Remove a custom define
    97.     /// </summary>
    98.     /// <param name="_define"></param>
    99.     /// <param name="_buildTargetGroup"></param>
    100.     public static void RemoveDefine(string define)
    101.     {
    102.         var definesList = GetDefines();
    103.         if (definesList.Contains(define))
    104.         {
    105.             definesList.Remove(define);
    106.             SetDefines(definesList);
    107.         }
    108.     }
    109.  
    110.     public static List<string> GetDefines()
    111.     {
    112.         var target = EditorUserBuildSettings.activeBuildTarget;
    113.         var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(target);
    114.         var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
    115.         return defines.Split(';').ToList();
    116.     }
    117.  
    118.     public static void SetDefines(List<string> definesList)
    119.     {
    120.         var target = EditorUserBuildSettings.activeBuildTarget;
    121.         var buildTargetGroup = BuildPipeline.GetBuildTargetGroup(target);
    122.         var defines = string.Join(";", definesList.ToArray());
    123.         PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
    124.     }
    125. }

    This code will set handy defines for your project. And you can use them like this:
    Code (CSharp):
    1. #if UNITY_PIPELINE_URP
    2. // code for URP
    3. #elif UNITY_PIPELINE_HDRP
    4. // code for HDRP
    5. #else
    6. // code for Stardard Pipeline
    7. #endif
     
    Ony, Radivarig, Threeyes and 3 others like this.