Player Collision Detection

Hi, I’m using Udon Sharp with the most recent build of the VRC SDK.

I’m currently trying to fire an event when the player collides/steps on a terrain object. I have yet to find any resources or direction on how to do this, and the only useful information I’ve found suggests that it’s not possible given how VRC implements the Unity player controller, or something like that.

I’ve been able to get a box and the terrain to fire a collision event, which suggests that it’s possible to do what I want. But, from where I stand, it seems like the only way to do this would be to add a collision box to the player themselves that can interact with the terrain in a similar was as the box, which raises a bunch of other questions that feel like they would raise their own problems.

Is what I want possible without getting too janky? As a last resort I can probably just check the player’s position/IsPlayerGrounded() in update() and then determine if the surface they are standing on is the one I am looking for, but that feels like it would be pretty inelegant and possibly have a significant overhead cost.

Thanks for the help!

Yes this is perfectly possible and there are lots of ways to do it. The most effective and performant way is probably to use a trigger collider and fire an event in OnPlayerTriggerEnter()

You’ll probably want to filter the player argument for VRCPlayerApi.isLocal, but that depends on what you’re trying to do. The local player’s collision boundary is a capsule shape that starts at their feet and extends something like 2 meters up. Remote players’ collision boundary is actually a 1m sphere that extends above and below their feet.

1 Like

I looked into the various colliders, but I didn’t find any great way to accomplish what I want. I may just be too inexperienced in unity, so could I ask you to point me in the right direction?

I was able to accomplish my project using a 3d volume as the trigger area. Specifically, I used the ProBuilder Icososphere as the base shape and then checked the “convex” and “is trigger” parameters on the Mesh Collider component on it. This made it intangible and also allowed me to implement the OnPlayerTriggerEnter() and friends methods just fine.

What I am having trouble with is accomplishing the same thing but using a 2d surface as the trigger instead of a 3d volume. By what you say it sounds like this should still be possible, but I’d like to find a way that works with any arbitrary terrain I want to use. The terrain may have an erratic height map and I want to make sure that it will behave the same way regardless of where you contact the surface, without needing to make gross custom shape collider geometry by hand.

For example, how could I fire one of the events to set the player’s walk speed to 0 when the player steps on the terrain?

1 Like

Right, I found that, but I’m not sure how to actually set the events to trigger when they collide. I’m aware of all the collision events I have available within UdonSharp, the github had a great list of them. What I’m not sure about is why OnCollisionEnter() in the script is recognizing the collision between the box and the terrain, but none of OnCollisionEnter, OnPlayerCollisionEnter, OnTriggerEnter, or OnPlayerTriggerEnter are recognizing when I step on the terrain.

Can you post the code you’re using and maybe some screenshots of how your colliders are set up?

When I drop the test box onto the terrain, OnCollisionEnter() fires and I see “3” in the debug log in VRC.

Nothing else fires.

Try messing around with the Physics Debug screen while running CyanEmu (or ClientSim).

That should help you visualize the boundaries of your colliders.

1 Like