Unity Animation Rigging procedural walking

Unity Animation Rigging procedural walking

Why Procedural Walking

When making Unity’s walking animation, if you only use the traditional animation system, it is often impossible to achieve a perfect fit with the terrain. For example, when going uphill, when you step on a stone, the effect is not very good. At this point, you can consider procedural walking.

effect video

Unity Animation Rigging procedural walking

principle

First of all, you must understand IK, that is, inverse kinematics. In fact, it is to calculate the movement position and orientation of each joint of the skeletal system according to the position of the target, so as to achieve the goal of getting as close to the target as possible. For example, if you want to pick up an apple on the table, the human brain will instantly calculate, control the movement of shoulders, elbows, wrists and other key points, and finally make the hand touch the apple. This process is IK. Then, procedural walking is based on IK, which requires reverse thinking. In fact, procedural walking is not the legs that support the body, but in fact, what we control is the body, and then judge the body according to the current coordinate position. Match the foothold of the next step, and finally use IK to reverse calculate the joints of the legs.
insert image description here
The simplest case: using the body coordinates as a reference, give each leg an appropriate offset (the position of the red ball in the picture above), and then shoot a ray towards the ground to detect the foothold, and then you can know hit.pointthe The ground height of the foothold is set, and then set the IK target point of the legs to this point, and the rest is handed over to the Unity engine. Unity will base on the position of the target point and various constraints of IK (for example, some joints will Constrain the angle of rotation, such as human knees, which can never bend forward), to automatically calculate the posture of the legs.
Then it's as simple as:

/* --------------------
 * 此代码挂在脚上
 * --------------------*/
private void Update()
{
    
    
    // lerp表示上一步落脚点到下一步落脚点的行进进度(0-1)
    if (lerp < 1)
    {
    
    
        lerp += walkerBody.StepSpeed * Time.deltaTime;
        if (lerp >= 1)
        {
    
    
            // 如果已经踩到新的落脚点
            transform.position = targetPos;
            oldPosition = targetPos;
            walkerBody.OnStepDone(this);
        }
        else
        {
    
    
            // 正在迈步,通过高度上增加Sin函数,则可以让脚步的位置有弧线变化。
            Vector3 pos = Vector3.Lerp(oldPosition, targetPos, lerp);
            pos.y += Mathf.Sin(lerp * Mathf.PI) * walkerBody.StepHight;
            transform.position = pos;
        }
    }
    else
    {
    
    
        // 不管身体位置如何变化,IK目标点总是设置到落脚点上
        transform.position = oldPosition;

        // 判断身体的位置移动,是否超过步长,超过就要迈步。
        if (Physics.Raycast(walkerBody.transform.position + stepOffset, Vector3.down, out RaycastHit hit,
            stepOffset.y * 2, walkerBody.GroundLayerMask))
        {
    
    
            // 左脚和右脚不能同时迈步,这里判断一下不能同时迈步的其他脚是否正在迈步。
            if (CantSimultaneous != null && CantSimultaneous.Any(other => other.IsWalking))
                return;
            if (Vector3.Distance(hit.point, oldPosition) > walkerBody.StepDistance)
            {
    
    
                lerp = 0;
                targetPos = hit.point;
            }
        }
    }
}

The above code is modified based on the official example, but some imperfections are that the **stepping action is too passive. ** Often the body has moved half a step before the feet start to take a step, as if the legs were broken and pulled behind.
insert image description here
Later, when detecting the foothold, an offset in the direction of travel was added, which is equivalent to judging the foothold a little earlier in the direction of the body movement before the body takes a step, and then the whole animation is very comfortable. And the mechanism of stepping is moved from "feet" to "body".

/* --------------------
 * 此代码挂在身体上
 * --------------------*/
private void Update()
{
    
    
    Vector3 dir = new(Input.GetAxis("Vertical"), 0, -Input.GetAxis("Horizontal"));
    if (dir.sqrMagnitude > 0.25f)
    {
    
    
        Vector3 realdir = transform.TransformDirection(dir).normalized;
        Controller.SimpleMove(realdir * MoveSpeed);

        if (IsMoving)
        {
    
    
            Vector3 offset = transform.position - oldPosition;
            if (offset.magnitude > StepDistance)
                NextStep(realdir);
        }
        else
        {
    
    
            IsMoving = true;
            NextStep(realdir);
        }
    }
    else
    {
    
    
        IsMoving = false;
    }
}

Finally, a 2-legged robot effect:

Unity Animation Rigging procedural walking

continue to improve

In fact, there are still many things that can be improved, such as adding IK constraints on the basis of traditional walking animations, predicting the shape of obstacles, and using different flipping animations to cross obstacles.

Guess you like

Origin blog.csdn.net/sdhexu/article/details/127164136