Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Make an object visible only within another object?

Discussion in 'Scripting' started by Desprez, Jul 11, 2014.

  1. Desprez

    Desprez

    Joined:
    Aug 31, 2012
    Posts:
    302
    I guess I'll try asking this another way.

    How can I get sprites/objects to render only when they are within another invisible object (or bounds)?
    Alternately,
    How can I get sprites/objects to become masked when they are within another invisible object (or bounds)?

    In both cases, only specific sprites/objects should be affected.

    For clarity, I'm not looking to enable/disable the whole object - portions that are still showing/hidden should be affected accordingly.

    The solution cannot rely on multiple cameras.
     
  2. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    Do you want the parts to slowly become invisible (Gradient).
    Or just disable them when the camera is inside it? Õ 3 Õ
     
  3. Desprez

    Desprez

    Joined:
    Aug 31, 2012
    Posts:
    302
    Neither.
    Here's an example image of what I want to do.
    See how part of the top and bottom pitch ladder lines get cut off when they fall outside of the HUD?

    In this case, I've accomplished this by having invisible boxes around the edges of the HUD that use a depth mask to mask off the sprites when they enter the masking objects.
    It appeared that this solution was working properly until I added a skybox. For some reason, the skybox gets masked as well, even though other geometry, like the buildings, ground, and cockpit are just fine.

     
  4. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    Wouldn't this be a shader problem?
     
  5. Recon03

    Recon03

    Joined:
    Aug 5, 2013
    Posts:
    838
    Did you try using a different camera for the HUD, and use different layers? I do a lot of UI, I use a camera for my ui elements and use layers and only allow the camera to render those layers. So if your sky boxed messed it up, It may have to do with your camera settings.

    How many cameras and layers are you using?
     
  6. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
     
  7. Desprez

    Desprez

    Joined:
    Aug 31, 2012
    Posts:
    302
    @Recon03 - It's just the main camera.

    The HUD glass is on its own layer, but that's just to raycast the velocity vector into the glass without it colliding on anything else.

    I don't see anyway to use multiple cameras for this - unless you mean to make a the glass dynamic texture of the camera render - but that's only for unity pro.
    Overlaying a camera image on the player's screen won't work. For one, the HUD area isn't rectangular once your head starts moving and turning. Second, as the HUD starts to leave the screen, the overlaied camera can't follow off the edge.

    As far as UI elements - I don't have any experience working with them yet (still a Unity noob, here). But I was under the impression that they are flat on the screen, and aren't attached to game objects. (so they wouldn't obey perspective, distance, etc.) If I'm wrong about that, it might open up a solution.

    @Magiichan - Maybe it's a shader problem, but I didn't get any responses there. (Though I did word the problem differently.)
    But I'm open to other solutions - as long as they can get the result I'm after.
     
    Last edited: Jul 12, 2014
  8. Desprez

    Desprez

    Joined:
    Aug 31, 2012
    Posts:
    302
    Here's what it looks like when there is a skybox:

    The blue area is where the masking boxes are positioned around the HUD.
     
  9. Desprez

    Desprez

    Joined:
    Aug 31, 2012
    Posts:
    302
    Whoops.
    Well, maybe there IS a multi-camera solution.

    It looks like I can have 2 cameras in exactly the same position and that both render the whole area.
    One renders the skybox only. The other renders depth only.
    This appears to work - though I don't know if I'm introducing any major performance hits by doing so, or if this is going to cause some other problems down the line.

    Still, I'd RATHER go about this whole thing by having HUD elements only show when WITHIN an objects instead of the other way around.

    Any other fundamentally different ideas for how to make a virtual HUD?
    Or is this pretty much how it has to be done?
     
  10. theLittleSettler

    theLittleSettler

    Joined:
    Jul 14, 2012
    Posts:
    36
    I suspect that's how its done normally.

    You can use textured quads for the skybox instead if you like.
     
  11. maxizrin

    maxizrin

    Joined:
    Apr 13, 2015
    Posts:
    17
    For anyone who stumbles on this, it can be solved with a "slice" shader.
    As follows:
    Code (CSharp):
    1. Shader "Custom/SlicedGlobal"
    2. {
    3.     Properties
    4.     {
    5.        
    6.         _VisibilityDistance("Visibility Distance",float) = 1
    7.         _Origin("Origin",Vector) = (0,0,0,1)
    8.         _Color ("Color", Color) = (1,1,1,1)
    9.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    10.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    11.         _Metallic ("Metallic", Range(0,1)) = 0.0
    12.     }
    13.     SubShader
    14.     {
    15.         Tags { "RenderType"="Opaque" }
    16.         LOD 200
    17.  
    18.         CGPROGRAM
    19.         // Physically based Standard lighting model, and enable shadows on all light types
    20.         #pragma surface surf Standard fullforwardshadows
    21.  
    22.         // Use shader model 3.0 target, to get nicer looking lighting
    23.         #pragma target 3.0
    24.  
    25.         sampler2D _MainTex;
    26.  
    27.         struct Input
    28.         {
    29.             float2 uv_MainTex;          
    30.             float3 worldPos;
    31.         };
    32.  
    33.         half _Glossiness;
    34.         half _Metallic;
    35.         fixed4 _Color;
    36.         float3 _Origin;
    37.         float _VisibilityDistance;
    38.  
    39.         // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    40.         // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    41.         // #pragma instancing_options assumeuniformscaling
    42.         UNITY_INSTANCING_BUFFER_START(Props)
    43.         // put more per-instance properties here
    44.         UNITY_INSTANCING_BUFFER_END(Props)
    45.  
    46.         void surf (Input IN, inout SurfaceOutputStandard o)
    47.         {
    48.             // Albedo comes from a texture tinted by color
    49.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    50.             o.Albedo = c.rgb;
    51.             // Metallic and smoothness come from slider variables
    52.             o.Metallic = _Metallic;
    53.             o.Smoothness = _Glossiness;
    54.             o.Alpha = c.a;
    55.             // float3 localPos = IN.worldPos -  mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
    56.             // clip (frac((IN.worldPos.y+IN.worldPos.z*0.1) * 5) - 0.5);
    57.             clip (_VisibilityDistance * _VisibilityDistance - ((IN.worldPos.x - _Origin.x) * (IN.worldPos.x - _Origin.x) + (IN.worldPos.z - _Origin.z) * (IN.worldPos.z - _Origin.z)));
    58.         }
    59.         ENDCG
    60.     }
    61.     FallBack "Diffuse"
    62. }
    63.