当前位置: 首页 > news >正文

Unity地面检测、跳跃

首先,如果不做跳跃、不需要人物从高处坠落时做出坠落动作,就并不一定要写地面检测。人物坠落时保持在地面上的动作,可以在空中跑步,如果对效果要求不高就问题不大。

地面检测

碰撞检测方案

判定离地的代码写在OnCollisionExit(),在地面上的代码写在了OnCollisionStay(),不能写在OnCollisionEnter(),因为人物如果先接触另一块地面,再离开这一块地面,OnCollisionExit()的效果覆盖了OnCollisionEnter(),人物被判断为离地。如果写在OnCollisionStay(),离开一块地面时OnCollisionExit()执行一次,而OnCollisionStay()一直执行,人物还被判断为在地面上。坠落伤害的代码则可以放OnCollisionEnter()。

但是这样写还有严重的问题:下坡的时候先靠animator水平移动,再靠重力下落贴紧斜面,onGround会不停变成false导致人物做出坠落姿势或不能跳跃。

void OnCollisionStay(Collision collision){if(CheckIsGround(collision.gameObject)){//地面检测在Stay里,时时都要检测myCharacter.animator.SetBool(MyCharacter.onGroundPara,true);}}void OnTriggerExit(Collider other){if(CheckIsGround(other.gameObject)){//检测离地myCharacter.animator.SetBool(MyCharacter.onGroundPara,false);rigidbody.velocity=myCharacter.animator.velocity;}}static int speedToHurt=9,fallHurtDamage=40,speedToDeath=15,fallDeathDamage=120;//固定跌落伤害void OnCollisionEnter(Collision collision){if(CheckIsGround(collision.gameObject)){if(collision.relativeVelocity.magnitude>speedToDeath){myCharacter.TakeDamage(fallDeathDamage,MyGameManager.fallHint);}else{if(collision.relativeVelocity.magnitude>speedToHurt){//跌落伤害myCharacter.TakeDamage(fallHurtDamage,MyGameManager.fallHint);}}}}

补救方法:在人物碰撞体下端套一个稍大的触发器碰撞体,这个碰撞体离地时才判定离地。地面检测触发器为了和碰撞体区分开,要么就挂在其他节点上。这样让做一个人物的流程更复杂了。

7f7071d6c0184e40a1969371aa592e3d.png

在判断开始坠落时要执行

rigidbody.velocity=myCharacter.animator.velocity;

在坠落中继承人物的水平速度。而在落地后这个刚体速度不用设0,刚体会由于摩擦自动停下。

速度检测方案

现实世界中人类对坠落的反应好像并不是因为脚离地,而是因为下落的加速度达到了一定值。比如在加速下落的电梯里人的脚着地,但是会感觉到在下落。rigidbody没有加速度字段,但是可以通过rigidbody.velocity.y达到一定值来判断。

float fallSpeedLastFrame;
public float fallSpeedThreshold=-3;
void Update(){if(fallSpeedLastFrame>=fallSpeedThreshold&&myCharacter._rigidbody.velocity.y<fallSpeedThreshold){myCharacter.animator.SetBool(MyCharacter.onGroundPara,false);myCharacter._rigidbody.velocity=new Vector3(myCharacter.animator.velocity.x,myCharacter._rigidbody.velocity.y,myCharacter.animator.velocity.z);}fallSpeedLastFrame=myCharacter._rigidbody.velocity.y;}

物理效果

如果角色挂有RigidBody,可以通过rigidBody.velocity=jumpSpeed*Vector3.up实现。如果角色使用Animator的Root Motion移动,可以通过

rigidbody.velocity=new Vector3(_animator.velocity.x,jumpSpeed,_animator.velocity.z);

实现移动中跳跃,跳跃中保持起跳的速度。

动画效果

简单的跳跃只需要滞空动画。如果想做得更逼真,可以添加起跳和落地动画。我这里做滞空和落地动画。落地动画因为本身属于过渡动画,为了避免自动过渡出现不想要的效果,应该把滞空到落地、落地到站立的过渡设置尽量短。

9f62a74fafb14e60996a7c3e4fa480a1.png8bba5e4170f3405f8b4fcd4e755db386.png

程序判定

满足玩家输入跳跃&&人物在地面上就跳跃。定义一个bool onGround记录是否在地上,可以在脚本里或动画参数。

问题记录

跑步中跳跃有一定概率出现在空中跑步,看状态机显示进入跳跃状态后立刻退出进入了跑步状态。跳跃状态的退出条件是onGround==true,也就是说进入跳跃状态后立刻满足了退出的条件。

2a7d31be8f5a384719e001c76c151f10.png

解决方法:稍微增加了跑步到跳跃状态过渡的时长。

bc04d63c7a9f2d713990d670f1a0d2b4.png


http://www.mrgr.cn/news/55776.html

相关文章:

  • 云原生后端(Cloud-Native Backend)
  • 【exceljs】纯前端如何实现Excel导出下载和上传解析?
  • VideoCLIP-XL:推进视频CLIP模型对长描述的理解
  • Git 总结
  • 解决IntelliJ IDEA启动失败的完整指南
  • 接口测试(四)jmeter——文件上传
  • 低功耗4G模组的小秘密:RSA算法示例驾到,通通闪开...
  • 一分钟运行DBT入门示例项目(Jaffle Shop)
  • 新的类Rufus应用可带来简单的Windows 11 24H2安装旁路
  • 【07】z检验
  • Redis在实践的关键点
  • autMan框架对接飞书机器人
  • Golang | Leetcode Golang题解之第500题键盘行
  • Flutter Container容器组件实战案例
  • 精选录屏软件下载工具:记录精彩每一刻
  • 基于leaflet-polygon.fillPattern的面状对象图片填充实现
  • SQL CHECK 约束:确保数据完整性的关键
  • 【星闪技术】WS63E模块实时显示当前环境温湿度
  • ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)
  • AI学习指南深度学习篇-对比学习(Contrastive Learning)简介
  • 用malloc申请空间的开辟和free空间的释放
  • 计算机网络基本命令
  • 《深度学习》 了解YOLO基本知识
  • Java全栈经典面试题剖析2】JavaSE面向对象1
  • 复盘秋招22场面试(四)形势重新评估与后续措施
  • 【论文学习与撰写】,论文word文档中出现乱码的情况,文档中显示的乱码,都是英文字母之类的,但打印预览是正常的