Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Need advice on surface type system and impacts

Discussion in 'Scripting' started by Deleted User, Mar 19, 2018.

  1. Deleted User

    Deleted User

    Guest

    Hello, I'm revisiting my surface and impact system and starting to question if is optimal the way I'm doing and the limitations that comes with.

    Having modded id tech games in the past I took inspiration from id software games on this matter, specifically Doom 3. Basicly Doom 3 has surface info in the material and I thought is a good spot to have such info when playing appropriate effects on impact with the variosu surfaces. Problem was implementing it with unity.

    I have custom shaders for this purpose, is nothing complex, is the unity hsaders with an added property, an int called simply _SurfaceType, on impact it would check the renderer and get the property if is there to test against the int and play the appropriate effects on spot, but I'm not sure if is a good way to go about it. Here some code on how I detect the surface type.

    Every renderer that can receive impact data inherit from this component:

    Code (csharp):
    1.  
    2.     public abstract class RendererBehaviour : ComponentBehaviour
    3.     {
    4.  
    5.         public void SetShadowCastMode (ShadowCastingMode mode)
    6.         {
    7.             Renderer _r = GetComponent<Renderer> ();
    8.  
    9.             _r.shadowCastingMode = mode;
    10.         }
    11.  
    12.         public int GetSurfaceIndex (Collider col)
    13.         {
    14.             if (col != null)
    15.             {
    16.                 UnityEngine.Renderer _r = col.GetComponent<UnityEngine.Renderer> ();
    17.  
    18.                 if (_r.sharedMaterial.HasProperty ("_SurfaceType"))
    19.                     return _r.sharedMaterial.GetInt ("_SurfaceType");
    20.                 else
    21.                     return -1;
    22.             }
    23.             else
    24.                 return -1;
    25.         }
    26.     }
    27.  
    Returning -1 tells the impact data to not play anything at all. This gives some limitations, one beign not able to exclude certain effects from beign played, since impact data set has a decal sound and particle, but I'd like to exclude crtain effects without having too many instances of impact data. To do this I would need to put another property in the shader which I would like to avoid, I'm already unsure if having an unusued property in the shader is a good idea at all.

    Another way I was thinking was to use my own Material class, which I already have in place. Would add surface data in it and test against the material, this way I'd need to only retrieve the material name of the renderer and look there, and can add al lthe checks I want.

    Another way is to add an interface to components that should receive impact data and has the surface info in it, but I'm not sure an often called GetComponent for interfaces is a good idea, thats also the reason why I'm unsure with my initial approach as I bet checking the shader has some overhead, and in cases like shooting a wall the call would be very frequent.

    Whats your suggestion on how to approach this?

    Thanks.

    NOTE: I can't use tags for this purpose, I use them for other things and I'd like to avoid 3000 variants of tags for all purposes.
     
  2. CDMcGwire

    CDMcGwire

    Joined:
    Aug 30, 2014
    Posts:
    133
    Hmm... Based on my understanding of shaders and materials, I believe you're right in expecting there to be overhead on shader lookups. I couldn't say for certain without knowing how Unity implements them, but normally memory lookups between CPU and GPU components are very expensive, relatively speaking. Of course, that's assuming that the shader information is entirely in VRAM.

    Of course, looking at it from a simpler perspective, you're looking up a value based on a parsed string. So that right there could be made more higher performance, potentially.

    I do think it would be a good idea to try playing in the "materials" world. They likely touch GPU code at some point too, but I believe it is mostly a CPU interface. And there may already be structures in place to handle this behaviour. Or at least assist in it.
     
    Deleted User likes this.
  3. Deleted User

    Deleted User

    Guest

    Thanks for your reply, sure the above code bothers me a lot for the reasons you wrote.

    Forgot to mention, in my game everything is created at runtime, there is minimal use of unity editor and thats why I have my own material class for this purpose, which is just a container for a unity material plus other info in it.

    So the advantage of using my own material for this purpose would be that there won't be any shader lookup, but the surface itself stays in the material.

    To retrieve such info all I would need to do is a dictionary lookup on cached materials and get directly the int. The above function would be:

    Code (csharp):
    1.  
    2.         public int GetSurfaceIndex (Collider col)
    3.         {
    4.             if (col != null)
    5.             {
    6.                 UnityEngine.Renderer _r = col.GetComponent<UnityEngine.Renderer> ();
    7.  
    8.                 NM.Engine.Material _mat = CacheSystem.GetObjectDef<NM.Engine.Material> (_r.material.name);
    9.  
    10.                 return _mat.surfaceType;
    11.             }
    12.             else
    13.                 return -1;
    14.         }
    15.  
    No shader lookups, but just a dictionary search based on material name as id.
     
  4. CDMcGwire

    CDMcGwire

    Joined:
    Aug 30, 2014
    Posts:
    133
    Looks like a solid approach then. There might be limits, but until you can see a measurable impact on maintenance or performance, that seems like it will work. :D

    As someone who overthinks these on my own projects, I can say you'll either be happy with it and never lool at it again or figure out a better solution once a problem pops up.
     
    Deleted User likes this.
  5. Deleted User

    Deleted User

    Guest

    Hope to never look at it again. By the way thanks for your input it helped a lot.
     
  6. CDMcGwire

    CDMcGwire

    Joined:
    Aug 30, 2014
    Posts:
    133
    Hope it works out well for you. Glad I could help!