关于unity:黑魂复刻游戏的玩家控制器降落落地检测Unity随手记

明天实现的内容:
退出起飞动画
起飞产生在跳跃之后,所以网络游戏角色起飞动画要紧接着跳跃动画播放,动画机如下。

这两条Transition都has exit time,并且jump到fall的优先级高于jump到ground,因为目前为止这两个转换都没有条件。

在图示地位调整优先级。

落地检测的实现及相干动画使用
要实现落地检测,须要应用Physics.Overlap里的货色,应用Physics.Overlap能够找到某个形态范畴内有重合的所有碰撞体。比方咱们要用到的Physics.OverlapCapsule就是在一个给定的胶囊体内失去所有与胶囊体有重合的特定layer的碰撞体,Overlap只能失去有哪些碰撞体重合,而不晓得其它信息(先后,远近等等)。

咱们新建落地检测器脚本OnGroundSensor,挂载到PlayerController游戏对象的子物体sensor下,sensor对象将专门因为各种检测器的挂载。

OnGroundSensor代码如下。通过SendMessage来通知PlayerController以后是否正在高空。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 落地检测器
public class OnGroundSensor : MonoBehaviour
{
    // 用于援用PlayerController游戏对象上的CapsuleCollider
    public CapsuleCollider capCol;

    // 用于绘制胶囊检测器的两个点
    private Vector3 point1;
    private Vector3 point2;
    // 用于绘制胶囊检测器的半径
    private float radius;


    void Awake()
    {
        radius = capCol.radius;
    }

    void FixedUpdate()
    {
        // 更新检测器的地位
        point1 = transform.position + transform.up * radius;
        point2 = transform.position + transform.up * (capCol.height - radius);
        // 检测高空碰撞
        Collider[] outputCols = 
            Physics.OverlapCapsule(point1, point2, radius, LayerMask.GetMask("Ground"));
        // 判断是否撞到高空 并向父物体发送对应音讯
        if(outputCols.Length != 0)
        {
            // 在高空
            SendMessageUpwards("IsGround");
        }
        else
        {
            // 不在高空
            SendMessageUpwards("IsNotGround");
        }
    }
}

接下来要做的就是,在PlayerController中实现音讯接管。

// 在高空时执行的办法 通过OnGroundSensor中的SendMessage调用
    public void IsGround()
    {
        m_anim.SetBool("isGround", true);
    }

    // 不在高空时执行的办法 通过OnGroundSensor中的SendMessage调用
    public void IsNotGround()
    {
        m_anim.SetBool("isGround", false);
    }

在动画机中增加新参数isGround,用于PlayerController进行管制。

好的,当初调回先前的jump转换优先级,将jump到ground和fall到ground的转换条件设置为isGround为true。


到目前为止,落地检测的实现及相干动画使用根本实现。

落地检测器优化
倡议改小检测器的半径以及略微将检测器向下挪动一点。来失去更好的检测后果。

    // 检测器偏移量
    public float offset = 0.1f;

    void Awake()
    {
        m_radius = capCol.radius * 0.6f;
    }

    void FixedUpdate()
    {
        // 更新检测器的地位
        m_point1 = transform.position + transform.up * (m_radius - offset);
        m_point2 = transform.position + transform.up * (capCol.height - m_radius - offset);
        
        // ...
    }

失足掉落
因为咱们的掉落动画只有在跳跃的前提下能力触发,所以特此退出失足掉落的设置。这样一来,只有来到高空就会播放,而不是来到高空仍旧和在高空没有两样(在没有跳起来来到高空的状况下)。是的,咱们在没有起跳的状况下来到高空和在高空没有区别,仍然能够失常操作。
首先是动画机的设置,间接拉一条transition从ground到fall就行,条件为isGround为false。

接下来,在掉落时要和跳跃一样锁死操作。当初就当一次笨蛋,在进入fall状态时发送音讯给PlayerController(更好的办法是在来到ground时发送音讯,这样还能够省掉进入跳跃时发送音讯这个操作)。

    // 进入掉落时执行的办法 通过PlayerController动画机中的fall节点上挂载的FSMOnEnter中的SendMessage调用
    public void OnFallEnter()
    {
        // 敞开输出并且锁定立体挪动
        DisableInput_LockPlanar();
    }

    // 敞开输出并且锁定立体挪动
    private void DisableInput_LockPlanar()
    {
        // 敞开输出模块
        pi.inputEnabled = false;
        // 锁死平台挪动计算
        m_lockPlanar = true;
    }

动画的优化及改良
除了jump到fall,其它所有的transition都不要勾选has exit time,这样能带来更晦涩的动画成果。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理