首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity-黑暗之魂复刻-跳跃功能

Unity-黑暗之魂复刻-跳跃功能

作者头像
祝你万事顺利
发布2019-05-29 17:02:18
1.3K0
发布2019-05-29 17:02:18
举报
trigger once signal

使用触发来实现跳跃逻辑

//2.trigger once signal
    public bool jump;
    private bool lastJump = false;
bool newJump = Input.GetKey(keyB);
        if(newJump != lastJump && newJump == true)
        {
            print("I jump");
            jump = true;
        }
        else
        {
            jump = false;
        }
        lastJump = newJump;

我们添加新的状态Jump 通过Trigger来触发跳跃的动画 这里会遇到Unity中存在的一个问题,当我们连续按跳跃的时候,Trigger会记录两次按键,动画就会播放两次。 通过FSMClearSignals添加到ground的状态中的Behavior中我们来修复这个问题。 我们重写OnStateEnter这个方法,当进入当前状态的时候,清空Trigger的记录。这样我们就避免了连续输入动画会播放两次的问题。

 // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        foreach (var item in clearTriggerAtEnter)
        {
            animator.ResetTrigger(item);
        }
    }
再优化

为了减少在动画状态机中添加代码,我们将Behavior套接出去。 我们在Jump的动画状态中添加一个FSMOnEnter的Behavior继承自StateMachineBehaviour

public string[] message;
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.gameObject.SendMessage("OnJump");
    }

由于我们的代码并不在animator的gameObject上 我们的Input相关和角色Controller相关代码都在PlayerHandle中,ybot中只有Animator组件

PlayerHandle.PNG

所以我们改编代码,向父物体SendMessage

animator.gameObject.SendMessageUpwards("OnJump");
在空中的时候锁死当前的平面速度向量

1.首先在Jump的State中AddBehaviour,一个进入状态一个退出状态 2.如上面代码,我们在ActorController中编写进入和退出状态触发的方法。

private void OnJumpEnter()
    {
        pi.enabled = false;
        lockPlanar = true;
        //print("Jump!!!!!");
    }
    private void OnJumpExit()
    {
        pi.enabled = true;
        lockPlanar = false;
        //print("JumpEX!!!!!");
    }

我们进入状态的时候锁死玩家输入同时,让玩家当前的移动速度不再变化。

if(lockPlanar == false)
        {
            planarVec = pi.Dmag * model.transform.forward * walkSpeed * ((pi.run) ? runMultiplier : 1.0f);
        }

这样角色再空中仍然会保持跳跃时的速度向量。

卡在墙上bug

由于我们让角色在空中保持了跳跃时的速度向量,会出现角色在空中的时候卡在墙上,这时摩擦力大于重力,角色不会下落,我们要改进就要给角色修改摩擦力。 制作两个physics.material,将他们的DynamicFriction和StaticFriction分别设置为1和0,当玩家在离开ground时,我们将zero的physics.material设置给player的collider.material,这样玩家在空中的摩擦力就会为零,在ground上时,我们再设置回去。

落地相关

1.给Jump添加新的Transition到fall,在jump进行状态转换的时候先判断到fall。 2.添加落地检测器,使用Physics中的OverLapCapsule进行检测。这个API适用于粗略的广泛的判断,它会返回检测到的全部碰撞体。 3.给地面设置新的Layer,将地面的Layer设置为Ground 4.我们让玩家跳跃完播放fall的动画而不是ground,在fall动画播放的时候,如果OverLapCapsule检测到地面,立刻将状态设置为ground。我们使用bool值控制在jump后是转换到ground还是fall。

        point1 = transform.position + transform.up * (radius - offset);
        point2 = transform.position + transform.up * (capol.height-offset) - transform.up * radius;

        Collider[] colliders = Physics.OverlapCapsule(point1, point2, radius,LayerMask.GetMask("Ground"));
        if(colliders.Length != 0)
        {
            SendMessageUpwards("IsGround");
        }
        else
        {
            SendMessageUpwards("IsNotGround");
        }

落地的时候去调用父物体中的IsGround,IsGround将设置动画的状态。

    public void IsGround()
    {
        anim.SetBool("isGround", true);
    }
    public void IsNotGround()
    {
        anim.SetBool("isGround", false);
    }

5.失速问题,在fall的时候水平速度没有了,我们在Jump状态结束的时候将玩家输入清零,这是导致问题的原因。我们将JumpOnExit砍掉,换成在ground状态进入的时候,开放锁死。 6.在我们Jump转换到fall(正在转换)的时候,IsGround的条件满足了,我们仍然会将状态先转换到fall而不是立刻中断去进行转换ground状态。解决这个问题我们在jump状态transition到fall的setting中将Interruption Source(中断)设置为CurrentState。 在官方文档中,状态转换中断(Transition Interruption)中描述,使用中断源与有序中断属性控制转换如何被中断,中断提供效果,概念的讲,好像转换是序列的之后从第一个转换到最后一个转换逐一解析。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.05.08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • trigger once signal
  • 再优化
  • 在空中的时候锁死当前的平面速度向量
  • 卡在墙上bug
  • 落地相关
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档