2
\$\begingroup\$

After reading through this site, I began to think on how could I remove the colliders of vertexes with a transparent texture on it? I had read a suggestion (forgot where it was) to disable the whole terrain collider, but I also have NPC's, so having them plumet through the map wouldn't go over well.

\$\endgroup\$
1
\$\begingroup\$

You can't remove a part of it, but you can get it out of your way.

One approach to doing this would be to set the terrain heights in the hole region absurdly low, allowing objects to fall into the hole. But that might have unpleasant visual artifacts at the edges of your terrain (especially as it drops to lower LODs, which might cause the hole to erode its surroundings) and only allows you to make pits, not caves/tunnels that travel laterally.

The other thing you can do is to leave the collider where it is, but ignore it.

Set up a trigger collider (or more than one) to completely encompass the aperture of your hole. Then add this script to the GameObject containing these triggers.

public class TerrainHole : MonoBehaviour {

    // Assign the collider you want to tunnel through.
    public Collider terrain;

    // This lets us keep track of objects 
    // in one of our (possibly many) colliders.
    Dictionary<Rigidbody, int> _containment 
                      = new Dictionary<Rigidbody, int>();

    // When a new body enters one of our triggers,
    // make it start ignoring the terrain's collision.
    private void OnTriggerEnter(Collider other) {
        Rigidbody body = other.GetComponent<Rigidbody>();

        if (_containment.ContainsKey(body)) {
            // The body is in the intersection of more than one
            // of our triggers. Keep a count so we know 
            // when it's exited completely.
            _containment[body]++;
        } else {
            _containment.Add(body, 1);
            Physics.IgnoreCollision(other, terrain);
        }
    }

    // Once a body has exited all of our triggers,
    // tell it to pay attention to the terrain again.
    private void OnTriggerExit(Collider other) {
        Rigidbody body = other.GetComponent<Rigidbody>();

        int depth;
        if(_containment.TryGetValue(body, out depth)) {
            depth--;
            if (depth <= 0) {
                // The body has left the hole's vicinity.
                // Re-enable collisions and forget about it.
                Physics.IgnoreCollision(other, terrain, false);
                _containment.Remove(body);
            } else {
                _containment[body] = depth;
            }
        }       
    }
}

This isn't guaranteed to give sensible results if an object enters/exits the hole while in close contact with / intersecting the terrain. Usually you'll want to have some other geometry skirting around the hole, both visually and in its collision, to keep the player from seeing or interacting with the raw edge, so this should keep us out of those cases.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.