Unity: Life on the Edge

Hal Brooks
4 min readSep 19, 2021

Objective: Create a ledge grab system using Unity and Mixamo animation.

The ledge grab system consists of a detection cuboid on the Player, Ledge_Grab_Checker, another sensor cuboid on the ledge, Ledge_Checker, and the animation for holding onto the ledge. Begin by downloading the Hanging Idle animation from Mixamo, saving it as a FBX for Unity file. Drag the file into the FBX folder for Man_01, and change the Rig animation type to humanoid, as shown below.

Set Hanging Idle FBX file to humanoid.

Within the xbot@Hanging Idle, duplicate its Hanging Idle animation and move it to the Animation folder for Man_01 in the project Assets folder. Open this new copy, which is editable, and set it up to bake into pose the Root Transformation Rotation and Position (Y), shown below.

Hanging Idle animation.

Open the the Player_Animator_Controller and drag the Hanging_Idle animation into the Animator window. Create a transition from Any State to Hanging Idle animation, creating a trigger parameter called GrabLedge. Click the GrabLedge radio button to enable the Hanging Idle animation, which will be used to position the Ledge_Grab_Checker. The GrabLedge will be changed to a bool later and used to control animation.

Now create a cube on the Player and name it Ledge_Grab_Checker, with the components shown in the image below. Turn off the mesh renderer, the box collider has is trigger enabled and add a rigidbody with gravity disabled. The rigidbody is on this object because it moves and this single rigidbody used for multiple ledges. Tag the Ledge_Grab_Checker as LedgeGrab.

Adjust the transform position for Ledge_Grab_Checker as shown below.

Position for Ledge_Grab_Checker.

Now create a cube on the Platform_Ledge, and name it Ledge_Grab_Checker, with the components shown below. Turn off the mesh renderer, the box collider has is trigger enabled and add a C# script, LedgeChecker. Tag the Ledge_Checker as Ledge.

The position of the Ledger_Checker position is optimized to act as a trigger to snap the player onto the ledge, as shown below.

The LedgeChecker script contains two Vector3 variables one for the position when the player has grabbed the ledge, _ledgePos, and another for the position the player will stand once the ledge has been climbed, _idlePos, discussed in a later article. The Ledge position must be determined using the scene view until the Player is positioned as shown below.

Position for the _ledgePos variable.

The LedgeChecker checks for OnTriggerEnter by an object tagged LedgeGrab, shown below. LedgeChecker then accesses the Player script on the Ledge_Grab_Checkers parent object, i.e. the Player. The LedgeGrab method is called and passes the _ledgePos and _idlePos to the Player.

LedgeChecker script on Ledge_Checker game object.

The LedgeGrab method on the player is shown below. The Character Controller, i.e. _contoller, is disabled to prevent the Player from falling or moving. The Speed parameter on the animator, _i.e. _anim, is set to zero. The _anim.SetBool commands are used to turn on Hanging Idle animation, discussed below, and exit the Running Jump animation, i.e. Jump set to false. Transform.position snaps the Player to the ledge, passed from the LedgeChecker script. The _ledgePos position is also defined for later use when climbing.

Change the GrabLedge parameter on the Player_Controller_Animator from a trigger to a bool. Delete the transition from any state to Hanging Idle, and set up the animator to appear as below. For a ledge grab, create a transition from Running Jump to Hanging Idle.

Player_Controller_Animator

Configure the Running Jump -> Hanging Idle as shown below. Has exit time and fixed duration are unchecked. Transition duration is set to zero. Set the condition for this transition to GrabLedge bool true.

Running Jump -> Hanging Idle transition.

The player can now take a flying leap, and if timed correctly, grab a ledge.

--

--