38
\$\begingroup\$

I am trying to get a character to move like a spider: Given a rising slope which a ball would normally not be able to roll up, the spider would slowly crawl up.

Similarly, given a mid-air rectangular platform, instead of falling down when reaching the edge, the spider would continue, wrapping over the edge and continue down the side and then underside of the platform (eventually walking around the perimeter of the platform).

I've looked into various Unity 2D components, with little success. :(

Most of my world's collision boundaries are marked by Collider 2D components (which work great with a simple ball affected by gravity, but less so with this spider character).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ That game : youtube.com/watch?v=ga4Zqq1tXa8 ("Spider" on PS1 , i played it long time ago) might be a source of inspiration. \$\endgroup\$
    – tigrou
    Commented Mar 9, 2014 at 11:45
  • \$\begingroup\$ idk if you are still active but how did it work out with the rays? also doing a spider game and having problems using the rays \$\endgroup\$
    – Xxy
    Commented Feb 24, 2021 at 19:55

2 Answers 2

48
\$\begingroup\$

I was about to post a link to the Asteroid Base blog on the Walker enemy when I noticed karmington already linked to the Gamasutra article in a comment (unfortunately, the images in that version are now broken, but the content is identical to the blog post above which still works as of 2024).

It's probably worth giving this a bit more visibility and explanation as an answer in its own right though.

I'm walkin' on rayshine, o-oh!

The trick is raycasts. These let your code scan along a line for a collision.

To get the Walker to align nicely to surfaces, they fire two rays down at the terrain, one from the Walker's left side and one from its right (red and yellow lines above).

From each RaycastHit2D object, you can get a normal vector pointing perpendicular to the surface (magenta and green lines). By averaging the normals from the two hits, you get a suitable orientation for your character that's reasonably reflective of the underlying terrain (cyan line).

You can apply a force down along this orientation line to keep the character stuck to the terrain (though this may cause some sliding if the friction is low), or manually position the character at the average ray intersection point as is done with the Walker.

You'll want to blend the character's orientation gradually to keep your character from vibrating or looking robotic (see how the normal changes sharply when the Walker crosses the corner, but the body moves smoothly).

If you have sharp corners in your terrain, you'll probably want to angle these rays inward slightly - so that if the spider walks past the edge of a 90-degree cliff, the overhanging ray will hit the cliff face.

The Asteroid Base team also shoot a short ray in the direction of the Walker's motion (not shown), which overrides the ray on that side if it hits terrain. That ensures the walker doesn't get stuck when walking into a 90-degree concave corner.

According to the docs, the 2D raycast differs from the 3D one in that it detects colliders within which the ray starts. That sounds fishy to me, but if your testing confirms this you'll want to use a layerMask to limit the rays to only detect climbable terrain colliders.

\$\endgroup\$
1
  • \$\begingroup\$ I can confirm that 2D raycasts will detect colliders which contain the raycast's starting point. This can easily be filtered, though, as that first detection is always returned with a distance of 0 and a normal opposite of the raycast's direction. \$\endgroup\$ Commented Jun 27, 2018 at 17:10
3
\$\begingroup\$

You will need custom code for this.

Basically you need to know what the closest object is, like the platform in question, and then find the closest edge, and the closest point on that edge, and then work out the spider's position and rotation from there.

It won't be easy to make it really nice, but it should be a good challenge to get it working at all.

\$\endgroup\$
1

You must log in to answer this question.

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