问题描述

人物在检测到跳跃事件后,给一个初始速度v0v_0v0​,根据重力加速度ggg和时间差ttt,计算出当前人物的速度为 v=v0−g∗tv= v_0 -g * tv=v0​−g∗t。在当前调用的△t\triangle t△t时间内,位移为△y=v∗△t\triangle y= v*\triangle t△y=v∗△t。
检测是否落地采用了Physics.CapsuleCast函数,判断人物是否与地面足够近,然后重新设置人物的坐标(根据hit.distance计算出的与地面的距离)。

但是,不知为何人物在落地时,总会高出地面0.25,后续跳跃就总是以此为平面了。

检测碰撞的代码如下:

// 判断是否落地
void GroundCheck()
{// Make sure that the ground check distance while already in air is very small, to prevent suddenly snapping to groundfloat groundCheckDistance = -m_JumpSpeed * Time.deltaTime;       float slopeLimit = 0.1f;        //  可落地地形角度// reset values before the ground checkVector3 m_GroundNormal = Vector3.up;Debug.Log(check_height);if (m_JumpSpeed <= 0){// if we're grounded, collect info about the ground normal with a downward capsule cast representing our character capsuleif (Physics.CapsuleCast(GetCapsuleBottomPoint(), GetCapsuleTopPoint(), m_CharaContr.radius, Vector3.down, out RaycastHit hit, 0.1f)){// storing the upward direction for the surface foundm_GroundNormal = hit.normal;// Only consider this a valid ground hit if the ground normal goes in the same direction as the character up// and if the slope angle is lower than the character controller's limitif (Vector3.Dot(hit.normal, transform.up) > 0f &&Vector3.Angle(transform.up, m_GroundNormal) <= slopeLimit){isJumping = false;m_Animator.SetBool("isJumping", isJumping);// handle snapping to the groundif (hit.distance > m_CharaContr.skinWidth){m_CharaContr.transform.Translate(Vector3.down * hit.distance);}}}}
}Vector3 GetCapsuleBottomPoint()
{return m_CharaContr.transform.position + m_CharaContr.center + Vector3.up * -m_CharaContr.height * 0.5F;
}Vector3 GetCapsuleTopPoint()
{return GetCapsuleBottomPoint() + Vector3.up * m_CharaContr.height;
}

通过一番排查,问题主要出在Physics.CapsuleCast部分,它在距离地面0.25f+hit.distance的时候就认为扫描到了碰撞体。此时,transform.position.y总在0.25附近,最终导致悬空。

至于出现这个问题的原因,还尚未清楚。


5/17
距离记录这个问题,已有一段时日,后续也并未找出碰撞检测的位置和坐标不一致的具体原因,最终采用了另一种方法来解决落地问题。
涉及到y轴的变化(跳跃行为,地形变化)时,必然要每帧检测与地面的距离以确保人物贴在地上,在上述诡异的情况下,我采用了CharacterController控件提供的isGrounded成员变量来作为是否落地的直接依据。同时采用CharacterController控件提供的Move函数来控制人物的移动,也能有效保证人物不会1)穿过带碰撞体的物体,2)穿过地面等情况。

因此,最终跳跃的整套解决方法流程如下:

  1. 人物正在正常的移动,检测到玩家按下空格键(跳跃键)。
  2. 人物的动画状态机切换到跳跃动画。人物产生y轴方向上的初始速度v0v_0v0​。
  3. 在每帧中更新人物的高度(也就是v0∗t−g∗t2/2v_0*t-g*t^2/2v0​∗t−g∗t2/2),同时检测是否与地面碰撞。
  4. 若检测到碰撞,则将动画状态机切换为落地动画等。但不改变垂直方向速度,让它继续落地。
  5. 若检测到isGrounded成员变量标志为False,那么增加垂直方向上的速度vt+1=vt+g∗△tv_{t+1} = v_t + g*\triangle tvt+1​=vt​+g∗△t和位移。
  6. 若检测到isGrounded成员变量标志为True,那么将垂直方向的速度设置为0,不再产生垂直方向上的位移。

重复步骤5和6,即使遇到地面凹陷情况,也可以准确的自由落体至掉进底部,效果还算可以。

注意点
在上述的步骤6中,当检测到isGroundedTrue时,由于某些神秘原因,会导致人物稍稍上移(大约在0.00000001左右),下一帧在Update函数中检测isGrounded时又会重新变成False,最终导致该部分反复在往下掉和向上弹的过程中反复波动。
解决这个问题的方式,我采用了判断是否悬空有两个条件:

  1. 就是isGrounded标志为False
  2. 另外,就是用一条射线向下检测,如果检测到hitdistance大于0.01就认为是已经悬空,开始制造垂直方向的加速度。

综合上述,就可以比较完美的实现跳跳乐了,甚至奇形怪状的地形,石头等,也可以安然落在上面。

示意代码如下所示:

void Update()
{m_PlayerMovement = m_PlayerMoveStat.GetPlayerMove() * moveSpeed * Time.deltaTime;m_PlayerMovement.y = GetVerticalHeight();m_CharaContr.Move(transform.rotation * m_PlayerMovement);   // 沿着人物的前方行走
}public void JumpStart()
{m_LastJumpedTime = Time.time;m_VerticalSpeed = jumpSpeed;
}float GetVerticalHeight()
{if (!isLanded())    // 未着陆状态{// 下面这个判断是为了处理,当前人物已着路,但离地面距离为0,此时,isGround被认定为false,需要进一步检测与地面距离if (Physics.Raycast(GetCapsuleBottomPoint(), Vector3.down, out RaycastHit hit, 777f) && hit.distance > 0.01f) {m_VerticalSpeed -= gravityForce * Time.deltaTime;m_VerticalSpeed = Mathf.Clamp(m_VerticalSpeed, -2*jumpSpeed, 2*jumpSpeed);// h = v0 * t - 1 / 2 * g * t^2}//Debug.Log(string.Format("unlanded: {0}", transform.position.y));return m_VerticalSpeed * Time.deltaTime;}else {//Debug.Log(string.Format("islanded: {0}", transform.position.y));m_VerticalSpeed = 0;return 0;}
}bool isLanded()
{// 判断是否着路//Debug.Log(m_CharaContr.isGrounded);return m_CharaContr.isGrounded;
}

Unity3d 人物跳跃后落地悬空问题相关推荐

  1. Unity3D打包后日志文件输出目录

    Unity3D打包后日志文件输出目录,包括日志文件和崩溃时记录文件 C:\Users\Administrator\AppData\LocalLow\长沙迪迈科股份有限公司\镍矿探秘 其中". ...

  2. 【Unity项目优化宝典】Unity3d打包后移动端启动黑屏时间太久

    欢迎加入Unity业内qq交流群:956187480 qq扫描二维码加群,行业纵横颇多,每个人精通领域各异,旨在交流, .公司性质使然,经手很多小项目.在美术资源少,代码框架简单的情况下一般不会考虑到 ...

  3. 倒手一套房,还贷款后落地400万!我打算离开上海了~

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  4. cpc卡内计费信息异常包括_抖音信息流落地页直达广告怎么做?

    据数据显示,抖音用户60%以上是90后用户,70%以上的用户来自一二线城市,男女比例基本持平,抖音广告适合以中年轻群体为目标用户的企业投放.抖音广告可以直接点击跳转到指定的落地页,那么,抖音官方信息流 ...

  5. Unity3D游戏开发介绍

    Unity3D游戏开发介绍 Unity3D Unity是实时3D互动内容创作和运营平台.包括游戏开发.美术.建筑.汽车设计.影视在内的所有创作者,借助Unity将创意变成现实. Unity平台提供一整 ...

  6. Unity3D 与 3DMax 结合开发

    unity3D 用3DMax 做的模型时需要注意几点 1:方向问题 2:模型尺寸问题 3:模型所占资源大小问题 3DMax 做的东西导入到 Unity3D 中,在 Unity3D 引擎中 X 会被反向 ...

  7. Qunar 云原生容器化落地实践

    作者|邹晟 去哪儿网基础平台技术专家 背景 近几年,云原生和容器技术非常火爆,且日趋成熟,众多企业慢慢开始容器化建设,并在云原生技术方向上不断的探索和实践.基于这个大的趋势, 2020 年底 Quna ...

  8. android自动化测试unity,基于Unity3D引擎的UI自动化测试方案

    一.基本思路 熟悉Unity3D开发后就会发现,游戏的每个场景都有一个UI树,而通过这个UI树的根节点可以遍历整个UI树的所有UI对象.而Unity3D是通过挂载脚本的方式来控制游戏逻辑的,因此我们可 ...

  9. 云原生|Qunar 云原生容器化落地实践

    背景 近几年,云原生和容器技术非常火爆,且日趋成熟,众多企业慢慢开始容器化建设,并在云原生技术方向上不断的探索和实践.基于这个大的趋势, 2020 年底 Qunar 也向云原生迈出了第一步--容器化. ...

  10. 为什么90后不鸟管理者,却愿意被大神虐?

    为什么90后不鸟管理者,却愿意被大神虐? 赞赏小侠 环球人力资源智库 5天前 来 源丨笔记侠 ID:Notesman讲 者丨韩庆峰,leo叔叔关系学堂创始人 大家好,我是Leo,一个与90后待了差不多 ...

最新文章

  1. 去耦电容和旁路电容详解
  2. python下载安装教程mac-mac上如何安装python3
  3. linux 交叉编译 静态库,从Linux为Windows开发交叉编译静态库
  4. 写一个 panic blame 机器人
  5. c# char unsigned_c – unsigned char和char指针之间的区别
  6. Python实战应用-Clumper库函数全解析
  7. java.util.IdentityHashMap.entrySet()方法实例
  8. 为什么调用支付宝接口后返回是错误页面!
  9. 文件内容快速搜索工具(BBdoc、Everything、Listary、DocFetcher)
  10. 网络电视接口 php,【小白教程】智能电视背后这些接口怎么用?
  11. SaaS的收入模型有哪些?终于有人讲明白了
  12. CRM客户管理系统有哪三大功能
  13. VMware ESXI虚拟机修改MAC地址的方法
  14. 如何入门Python之Python基础教程详解
  15. EndNote 使用教程
  16. 《男孩别哭》海龟先生
  17. 51单片机4位数码管按键显示
  18. python切片步长为负数_Python切片知识解析
  19. 基于多项式螺旋曲线的轨迹优化
  20. [Excel常用函数] var var.p var.s函数

热门文章

  1. ALTER TABLE 语句
  2. 服务器无线网络禁用启用无效,无线网络卡一直被禁用,无法启用
  3. python计算均线斜率_一根20日均线闯天下——量化回测“压箱底指标”,值得读十遍!...
  4. IAR for ARM下载、安装、注册,并搭建stm32工程(胎教版)
  5. 李飞飞宣布辞职后首次演讲!提出AI三原则;BAT大佬上海打假人工智能
  6. [业务流程图]与[数据流程图]的比较
  7. 统计小写英文字母的个数 c语言,输入一行字符,统计英文字母,空格,和其他字符的个数...
  8. 代码在线运行工具(PHP、Python、Java等)
  9. 数据结构 与游戏背包的设计
  10. 互联网行业哪个职业比较有前途?