Custom CharacterClass Collision Bug


I am creating my own CharacterController class for a 3D environment in three.js. I am attempting to calculate my own collision detection but am running into a strange bug that I cannot put my finger on. Because in my use case the only other objects in the scene are cubes, I am using a simple rectangle hit test using each cube’s x and z in comparison with the x and z of my character to determine if a collision has occurred.

I am then determining the direction of the collision using some simple vector math (applying some conditionals to a direction vector calculated by comparing the difference between the center of the collided object and the center of my character).

Next I am using that direction data to limit my character’s movement in the direction of the wall. Collisions are detected correctly in all cases however movement is only limited when my character’s/camera’s direction (rotation) is perpendicular to the faces of the cubes that are parallel to the x-axis. And vice versa, when my character’s direction is facing parallel to the cubes faces that are parallel to the z-axis.

All of this code is occurring inside of my update() function. Once the character is instantiated the update() function runs in a three.js continuous animation() loop.

The code for my CharacterController class is here.



I think part of the problem is that during collision testing you only allow EITHER xlimits OR zlimits and not both. Depending on which way you are pointing, you may actually need to limit both x AND z movements.

I would suggest a different approach. Rather than simply setting these flags, I’d return a list of references to the colliders and make your x / z adjustments based on the position of those actual walls. In some cases (i.e. lim pos Δt → ∞ ) time you may not actually want to completely set your position to the pre-collision state. Rather you might want to apply some of that movement. This is similar to issues around extremely fast objects (e.g. i.e. lim pos Δt → 0 ). This is discussed under the “bullet” section of the box2d documentation:

Anyway, the bottom line is that you need to allow your character to have its position constrained based on the collider normal and the character collision normal resulting from the character’s position and heading (aka yangle). You just need some maths to do this.


You know what, that makes perfect sense! What exactly do you mean by “collider normal” and “character normal”? Also what does this expression refer to Δt →? Thanks so much for the help!


Ahhhhhhhhhh too many triangles!


The lim X(t) Δt → 0 style notation is used calculus (and numerical analysis) to describe what happens as functions approach certain interesting limits. In the case of the above lim X(t) Δt → 0 would be read “the limit of X of t as delta t goes to zero”. That, in particular is an arbitrary example. See the this article for a more thorough discussion.

In my case, I was trying to describe the situation of what happens to your position vector as a function of time P(t). In your current way of working you take the step (no matter how big) and then test it. If it fails, then you negate the step. In reality, if you have a high velocity (or if your Δt – i.e. as Δt approaches ∞) it becomes more important for you to take a more measured approach – that is, you may not want to completely cancel your last movement or else you could get into a situation where you never allow yourself to move at all (say you backed yourself into a corner with three walls surrounding you). Instead, you need to back off just enough to prevent the collision, but not so much that you made no progress toward the wall at all. This becomes especially important if you wall material has any physical properties (springiness, etc). This is outside of the scope of your current project though.


also, why are you checking y values here:


ping @brannondorsey did you get this figured out?


Not yet, but also haven’t made another attempt since last night. I am going to try again today. Will you be oLab? RE: using y values, Vector2s don’t have a z property so I am passing in a z as the y and then referring to it as a y for the remainder of my Vector2 maths. Thanks so much for the continuing help!


Fancy … and confusing to read … :smile: I probably won’t be in the oLab today, but I watch this forum like a :trollface: