I switched back to collider/trigger setup for the ground check, and so far found this the best method. It depends though on the level geometry. If all is tiles, raycasts are probably better.
1 Make a holder game object that keeps most of the logic and none of the visuals.
2 Place it centre at the feet of your character, then parent the character under that holder.
3 Create a child game object, let's call it
Groundcheck, attach a circle collider (2D) to it, set it to trigger and then arrange it as you see in my picture.
Ground check logic
can be complicated. You need to capture a couple of different situations: jumping, running over the cliff, moving from one ground collider to the next without hitch and perhaps more.
You can do the logic either on the Holder or on the Groundcheck, I'm assuming you put it on the Holder. We first need to find the Groundcheck game object. Generally, you make a game object variable, check "inspector" to see it nicely on the FSM "front page" and then drag your Groundcheck game object into it (or do this in the variable tab). To learn a few good practices, let's add a
Game Object is Null action first into
Start. If the variable wasn't set, we want to ring the alarm. On the new state, right click and hit "Toggle Breakpoint". You can also use the Debug Log in the state.
Add a FINISH event to the
Start state by CTRL+LeftClick on it (the fastest way). CTRL+drag-drop from the finish state to make a new state. Make a setup like this:
I could start with Grounded, but it depends. These are two variants, see text below.Importantly, physics can be either 2D or default 3D. If you use a rigidbody 2D, you need to use 2D colliders, and 2D physics actions in Playmaker, e.g. Add Force 2d, Trigger 2d Event and so on.
VARIANT A) right click on Grounded > Global Events Transition > System Event > On Trigger Enter 2D. Add a second one, with On Trigger Stay 2D. And on the other state, Not Grounded, add On Trigger Exit 2D. This method does not care about specific tags, though. In the states you can now add a Send Event, target to Game Object, owner, send to children, and thereby let all FSMs on the holder know about whether we're grounded or not. If you only want to check specific game objects for ground, see variant B:
VARIANT B) rather than with global events, you can also add Trigger2DEvent actions into the state. In Ground, you want to check for exit, and in Not Grounded you want to check for enter and stay.
Refining: you likely run into some glitches when switching the ground object. To mitigate this, you can turn this into four states. The two new states go in between and are passed through. The state towards Ground state, you send off the event, but you don't do it in the Ground state itself. The state when you leave Ground state and go to Not Grounded acts as a small buffer. It looks identical to Not Grounded, but doesn't send off the event, and has a small wait on top (0.2s). That means, when you leave Ground state, for 0.2 seconds check whether there's a ground, if so, go back to Ground. If not go to Not Grounded for real (and send off the events).