专栏首页Unity游戏开发Unity-黑暗之魂复刻-跳跃功能

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

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)中描述,使用中断源与有序中断属性控制转换如何被中断,中断提供效果,概念的讲,好像转换是序列的之后从第一个转换到最后一个转换逐一解析。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 游戏AI-个体AI角色的操控行为(2)

    我们希望场景中有随机移动的单位,如巡逻的士兵 吃草的牛羊,往往我们在场景中设置几个点让单位在几个点中随机移动,这样会出现一种情况,单位突然掉头,Craig Re...

    祝你万事顺利
  • 1.2D小游戏开发实记-群英争霸

    4.清空Trigger 在idle状态中AddBehavior,进入idle状态重置atk的trigger

    祝你万事顺利
  • Shader-透明效果-透明度混合

    透明度混合相较于透明度测试更加复杂一些,透明度混合可以得到真正的半透明效果,使用当前片元和透明度作为混合因子,与已经存储在颜色缓冲区的颜色值进行混合,得到新的颜...

    祝你万事顺利
  • 2018年,10个开源技术的发展趋势

    技术总是在不断地革新与发展。诸如OpenStack,Progressive Web Apps,Rust,R,认知云,人工智能(AI),物联网等新的技术的发展正把...

    全球资讯翻译官
  • 设计模式之状态模式 总结篇

    通过对象内部状态发生改变进而来改变对象的行为,对象看起来好像是被修改了一样。如,没有糖果的时候(是一个状态),糖果机就不能运行了,有糖果之后(另一个状态),投币...

    凯哥Java
  • nginx 能做的事

    反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理(Reverse Proxy)方式是指以代理服务器来接受 int...

    用户5807183
  • Nginx主要功能及使用

    反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理(Reverse Proxy)方式是指以代理服务器来接受 int...

    林老师带你学编程
  • Nginx 到底可以做什么?看完这篇你就懂了!

    本文只针对Nginx在不加载第三方模块的情况能处理哪些事情,由于第三方模块太多所以也介绍不完,当然本文本身也可能介绍的不完整,毕竟只是我个人使用过和了解到过得,...

    用户1257393
  • 【性能】688- 前端性能优化——从 10 多秒到 1.05 秒

    关于 性能优化 是个大的面,这篇文章主要涉及到 前端 的几个点,如 前端性能优化 的流程、常见技术手段、工具等。

    pingan8787
  • AutoML将深度学习最难一环自动化,AGI技术基础已开始铺设

    【新智元导读】谷歌在 I/O 大会上新发布的 AutoML 旨在自动化设计深度学习软件最难的部分之一——为神经网络选择正确的架构。包括 Facebook 的 A...

    新智元

扫码关注云+社区

领取腾讯云代金券