Search Unity

How to reveal parts of a mesh with collider?

Discussion in 'General Graphics' started by FeastSC2, May 31, 2019.

  1. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I would like to only show the part of a mesh that's within a collider and the part that's outside of the collider would not be shown.

    How can I achieve this?

    Unity_2019-05-31_18-44-37.jpg
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    Not possible.

    Colliders are a CPU thing, and do not have themselves exist on the GPU in any real form.

    What you need to do is use a shader which you pass data about a sphere position and radius to using c#, and clip the shader based on if the position being rendered is within range of that point or not.
     
  3. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    Yes I did the shader part.
    Here's a way to do the shader if someone's interested: https://www.patreon.com/posts/19530112

    For the CPU/Collision: I'm using a sphere collider that triggers the ground to disable its collider.
    The radius of that I pass to the shader and in the radius of the sphere collider is the same.

    The ideal would be to have a boolean operation where the sphere collider gets subtracted to the ground collider but I don't even know that this is possible and it certainly would be costly. Too bad, the simple disable collider will have to do.

    My objective is to have the part of the ground that's revealed walkable and the part of the ground that is not revelead to be unwalkable. If that is somehow doable, I'm interested :)
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    The easiest way, is to scale collider accordingly, and offset its position.
     
    FeastSC2 likes this.
  5. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I ended up making a script that subdivides a box collider into mutliple smaller box colliders.
    This limits my shapes to box collider(s) but I'm ok with that.

    I will turn the boxcolliders on and off based on my trigger colliding with the small boxes.
    Thanks for the suggestions.

    upload_2019-6-28_17-49-58.png

    Code (CSharp):
    1. using Sirenix.OdinInspector;
    2. using UnityEngine;
    3.  
    4. public class SubdivideBoxCollider : MonoBehaviour
    5. {
    6.     public float GridSize = 1f;
    7.  
    8.     private BoxCollider BoxCollider;
    9.  
    10.     void Awake()
    11.     {
    12.         BoxCollider = GetComponent<BoxCollider>();
    13.         Subdivide();
    14.     }
    15.  
    16.     [Button("Subdivide")]
    17.     public void Subdivide()
    18.     {
    19.         var size = BoxCollider.size;
    20.  
    21.         int x = Mathf.RoundToInt(size.x / GridSize);
    22.         int y = Mathf.RoundToInt(size.y / GridSize);
    23.         int zHeight = Mathf.RoundToInt(size.z / GridSize);
    24.  
    25.         SubdivideOneGameObject(x,y, zHeight);
    26. //        SubdivideMultiGameObject(x, y, zHeight);
    27.     }
    28.  
    29.     GameObject SubdivideOneGameObject(int x, int y, int zHeight)
    30.     {
    31.         var offset = BoxCollider.size / 2f - (Vector3.one * GridSize / 2f) - BoxCollider.center;
    32.  
    33.         var subdivideObject = new GameObject("Subdivided boxes");
    34.         subdivideObject.transform.SetParent(this.transform);
    35.         subdivideObject.transform.localPosition = Vector3.zero;
    36.         for (int z = 0; z < zHeight; z++)
    37.         {
    38.             var height = z * GridSize;
    39.             CreateRow(x, y, Vector3.forward * height - offset, subdivideObject);
    40.         }
    41.  
    42.         return subdivideObject;
    43.     }
    44.  
    45.     void SubdivideMultiGameObject(int x, int y, int zHeight)
    46.     {
    47.         var offset = BoxCollider.size / 2f - (Vector3.one * GridSize / 2f) - BoxCollider.center;
    48.  
    49.         var subdivideObject = new GameObject("Subdivided boxes");
    50.         subdivideObject.transform.SetParent(this.transform);
    51.         subdivideObject.transform.localPosition = Vector3.zero;
    52.         for (int z = 0; z < zHeight; z++)
    53.         {
    54.             var height = z * GridSize;
    55.             CreateRow(x, y, Vector3.forward * height - offset, subdivideObject);
    56.         }
    57.     }
    58.  
    59.     void CreateRowOfBoxGameObjects(int xCubes, int yCubes, Vector3 _localPosition)
    60.     {
    61.         var boxSize = GridSize * Vector3.one;
    62.         for (int x = 0; x < xCubes; x++)
    63.         {
    64.             for (int y = 0; y < yCubes; y++)
    65.             {
    66.                 var go = new GameObject();
    67.                 go.transform.SetParent(this.transform);
    68.                 go.transform.localPosition = _localPosition + new Vector3(x * GridSize, y * GridSize);
    69.                 var box = go.AddComponent<BoxCollider>();
    70.                 box.size = boxSize;
    71. //                return;
    72.             }
    73.         }
    74.     }
    75.  
    76.     void CreateRow(int xCubes, int yCubes, Vector3 _localPosition, GameObject _subdivideObject)
    77.     {
    78.         var boxSize = GridSize * Vector3.one;
    79.  
    80.         for (int x = 0; x < xCubes; x++)
    81.         {
    82.             for (int y = 0; y < yCubes; y++)
    83.             {
    84.                 var box = _subdivideObject.AddComponent<BoxCollider>();
    85.                 box.center = _localPosition + new Vector3(x * GridSize, y * GridSize);
    86.                 box.size = boxSize;
    87.                 //                return;
    88.             }
    89.         }
    90.     }
    91. }