1
\$\begingroup\$

So I've posted here before regarding a Spider-Man like game that I'm working on. I'm facing another dilemma now. I want to rotate the player around the edges of walls.

So far, I've implemented a component for edge detection and attached it to two cubes on either side of my Player holder object. Both cubes fire raycasts to detect if I'm at the corner of a wall (suggestions on how I can improve edge detection will be greatly appreciated as well)

enter image description here

These cubes return true if they detect an edge like so:

enter image description here

Here's my Edge/Corner detection class:

[SerializeField] private float raycastRange;
[SerializeField] private LayerMask climbableLayer;
[SerializeField] private Vector3 raycastDirection;

public bool AtCorner;
RaycastHit _hit;

private void Update()
{
    AtCorner = Physics.Raycast(origin: transform.position,
                               direction: transform.TransformDirection(raycastDirection),
                               hitInfo: out _hit,
                               maxDistance: raycastRange,
                               layerMask: climbableLayer);

    if (AtCorner)
    {
        Debug.Log($"{name} -- Corner Detected"); 
    }
}

A snippet of code from my ClimbingState class:

            if (playerStateMachine.InputReader.VerticalInput > 0)
            {
                playerStateMachine.SwitchState(new PlayerWallVaultState(playerStateMachine));
                return;
            }

            else if (playerStateMachine.InputReader.HorizontalInput != 0)
            {
                // TODO: turn corner

                if (playerStateMachine.RightCornerDetector.AtCorner)
                {
                    // TODO: turn right corner
                }

                else if (playerStateMachine.LeftCornerDetector.AtCorner)
                {
                    // TODO: turn left corner
                }
            }

Here's where I've hit a wall and will appreciate the help provided. Thank you.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ We have some old Q&A about doing this in 2D, and some of the techniques can generalize to 3D, so you may find that has some useful inspirations. \$\endgroup\$
    – DMGregory
    Commented May 16 at 10:52
  • \$\begingroup\$ I suppose an important question would be do you need the character to retain some character control during the rotation (EG moving up/down whilst taking a sideways corner) or are they "locked in" to rotating around the corner from start to finish? \$\endgroup\$ Commented May 20 at 8:41

1 Answer 1

0
\$\begingroup\$

The way I would implement this would be to cast the rays from your "detector cubes" slightly inwards so that the two rays would technically meet, say 1 meter in front of the character. The reason for this is I don't want to detect the edge, I want to detect the wall that I need to grab onto next.

We are already attached to the current wall, so for both walls we have:

  • The normal of the wall.
  • A point on the wall (current attachment point and point the ray intersects the next wall)

Having a point and a normal is the definition of a plane - so we really have two planes, theoretically we need to intersect the two planes to find the equation for the line of intersection of both planes.

However the math for that gets unnecessary complex, instead if we assume that the walls are roughly vertical we can intersect three planes (the two we have plus the horizontal (XZ) plane at the height(Y) of the player, giving us a single point.

We can measure our distance from the point, once it drops below a certain value we can start a rotation around the line to place us onto the other wall and lock our up Vector to the new walls normal.

You are going to need to play with the numbers, where do you start rotating / can you overshoot to make things look right? However the critical point is when you reach the 1/2 way point on the rotation (45 degrees for a right angle) you switch which wall you are attached to.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .