人物移动控制是单机和网游中比较重要的部分,但前单机游戏使用动力学以及IK动画等已经达到了非常逼真的地步,在大型网络游戏中这样的物理模拟同步是很实现的,因此在目前多数网游中仍旧是采取使用一个包围体(盒子或者胶囊)来模拟人物。一个好的移动系统是很重要的,平滑的贴墙滑动以及下滑,跳跃等会带给玩家顺畅的手感否则则会有种奇怪的感觉,本文具体介绍了一下碰撞反应,包括贴墙滑动等的具体实现细节。包括一个demo实例 。

目前物理引擎里面大多自带独立于刚体的人物角色控制,但是物理引擎需要特定的物理模型命名以及比较大的物理模拟开销度。如果需要定制自己的特别功能或者需要简化计算(同时模拟多个延迟或者玩家的反应)。就必须自己完成人物碰撞反应控制的代码。

要完成人物发生碰撞以后的行为控制,需要碰撞检测系统提供以下的碰撞信息,对于每一个碰撞:

1.   碰撞发生的时间

2.   碰撞的法向量

3.   碰撞点

对于基本的人物碰撞控制反应来说,以上点是必须的,有时还需要提供和包围体发生碰撞的具体三角形信息。 这里我采用胶囊来模拟人物的包围盒,之所以采用胶囊是因为使用这一类曲面包围体来模拟人物当发生碰撞时能够产生更加平滑的法向量,这对于后面的碰撞后行为能带来很大好处使得模拟更加平滑。

对于场景上的物体首先使用胶囊所在的包围盒AABB或者OBB和场景中的碰撞体包围盒作层次碰撞裁减,至于具体怎么组织可以任意,比如可以采用AABB或者OBB树,也可以采用简单的球树。但碰撞进行到树的叶子节点后开始检测人物的AABB盒和该AABB盒所包围的OBJECT的碰撞情况。如果发现这2个AABB(OBB)盒将会发生碰撞,那么开始使用人物的胶囊体和景物所带的三角面片进行精确到polygon soup级别的比较。这时候仍旧可以优化,比如说我还做了一步把一个Object中的三角形面片打成BSP树的形式存储起来,这样可以大大减少胶囊和三角形碰撞检测的次数,因为这种动态检测是十分耗时的。有关胶囊和三角形面片的比较可以参考:http://dev.gameres.com/Program/Abstract/Arithmetic/capsule.mht中的方法。  对于BSP的划分以及AABB碰撞检测就不用多说了~到处都可以找到文章。

对于地形而言,也是采用同样的方法,只不过对于地形而言三角形信息不用额外存储,只需要使用和渲染相同的三角形(对于景物来说一般不会使用渲染用的三角形而会使用更加简化数量更少的简化网格碰撞模型)。这里可以有很多优化的技巧,因为地形本身是规则的cell一个地形是由若干个patch(一般是16X16)组成的,而每个patch是由若干cell(一般是16X16)组成的。对于patch来说一般已经组织到了一颗QUADTREE中了因为视棱锥裁减也需要这种结构,因此碰撞检测中的AABB-AABB阶段使用这颗已经存在的QUADTREE就可以快速的完成层次碰撞检测了。但发现某个patch中的AABB和人物的AABB发生碰撞后需要检测每一个CELL所在的AABB和人物AABB盒的碰撞,这里可以使用点小技巧比如说首先将AABB盒投影到CELL所在的XY平面上,找出被投影覆盖的那些CELL然后再检测这些CELL的AABB盒是否和人物的发生碰撞。一但确定了某个CELL和人物发生碰撞那么就可以将该CELL中的三角形取出(一般为2个)依次和人物所在的胶囊进行三角形-胶囊的碰撞检测。

这样当碰撞检测系统完成任务以后我们将会获得一个碰撞信息的数组:

class CollideInFo{

public:

GFVECTOR_3D  m_worldcdnorm;//碰撞法向量

GFPOINT_3D  m_worldpoint;//碰撞点

float       m_cdtime;//碰撞时间

};

CollideInFo collidearray[];

然后使用这个数组就可以进行碰撞后的处理了包括,沿墙滑动下滑等等。在具体说明整个人物移动控制算法之前,首先说下动态碰撞检测和静态碰撞检测的区别,动态碰撞检测是指物体A以速度V前进了T时间,在这期间第一次和物体B发生碰撞的时间。这样的碰撞检测必须返回第一次2个物体发生碰撞的时间。而静态检测是指2个不动的物体是否互相相交对于这种检测是不需要返回时间的。动态检测算法比静态的复杂而且也耗用更多的时间。一个完善的碰撞系统需要解决以上2种碰撞检测,如果你不想自己写检测代码,目前比较流行的有OPCODE,SOLID库等检测库 。你可以直接使用他们提供的功能,这里我采用的是自己写检测代码的方法,目前只用到三角形-胶囊,AABB-AABB,OBB-OBB的碰撞检测。

完成了包围体(用的是胶囊)和三角形的碰撞,胶囊和BSP,地形的碰撞检测之后,拥有了碰撞的信息 1。碰撞时间。2。碰撞法向量。3。碰撞点。接着就可以处理人物在碰撞后的反应了。

首先人物的一次移动分2个阶段,第一个是初始阶段,使用静态碰撞检测获得该阶段的速度(具体做法在后面说)。第2阶段使用该速度去做动态碰撞检测得到碰撞信息,根据这些碰撞信息去处理碰撞后的反应。

先来看第一阶段,过程对于一个胶囊我们需要获取他周围的临近面片的信息,以决定这个胶囊目前所处平面的倾斜度,是否贴着不可通过的墙等等。我采用的方法是将胶囊体略为膨胀一些,然后调用静态碰撞检测的代码获取和该膨胀后的胶囊体相交的三角形面片碰撞信息如图:

棕色的是原始的胶囊体,红色的表示将胶囊半径略为增加以后的胶囊体,蓝色的2个地形是将胶囊膨胀以后所发生相交的2个三角形,而如果不采用膨胀的话该胶囊是不和任何三角形相交的,具体膨胀数值可以设为胶囊下落的最小高度,比如你设定胶囊离底部物体超过0.6单位属于腾空状态的话你就将膨胀数值设为0.6。在这个例子中我们将会检测到2个碰撞(蓝色部分)这2个碰撞法向量正好是这2个三角面的法向量(在很多情况下也可能不是这个看你的碰撞代码中法向量是如何计算的了)。其中底部的那个是可行走平面,另外一个是不可行走平面,有了这2个碰撞平面就很简单了,如果用户输入的速度和那个不可行走的平面相反(也就是撞向那个不可行走平面),那么那个不可行走平面是有效的,这样他和底部那个可行走的平面所组成的交线就是人物的初始速度,如果用户输入的速度和那个不可行走的平面法向量相同,那么这个不可行走平面没有作用人物最终的速度就是把用户速度投影到该可行走平面上的速度。

具体计算是否能够水平移动以及移动速度的算法:当给出M个不可行走平面和N个可行走平面时:

1首先将速度在N个可行走平面上分解,检查这些分解的速度是否有效(如何判断速度有效下面会说道)

2如果在1的时候存在一个有效的速度直接返回该速度

3没有有效速度,这时检查NXM个平面的交线,将速度在上面分解同时检查是否存在有效速度

4如果存在有效速度返回该速度

5否则检查MXM条交线的,将速度在上面分解同时检查是否存在有效速度
    6如果存在有效速度返回该速度
    7否则返回0速度

那么如何判定速度是否有效呢,首先我们知道了所有碰撞的信息,给定一个速度,如果该速度和所有碰撞的法向量的夹角都是小于90度那么这就是个有效速度,(说明该分解后速度不会引起和这些碰撞面的在一次碰撞,因为该速度是将物体拉下远离该平面的方向的)。如果只要有一个夹角大于90度那么该速度就是非有效速度,同时在移动时还要判断该速度的倾斜角是否大于最大下滑倾斜角。注意 5是很重要的因为2个不可行走的平面所形成的交线仍旧可能是可以行走的,甚至是水平的。

以上的部分是检查是否能够水平移动的,如果不能水平移动那么该物体会下滑,1如果没有检测到碰撞平面说明物体处于腾空状态,这时候给物体加上重力加速度,产生一个往下的速度和原来的水平速度结合起来(如果存在)。

如图棕色是原始状态胶囊经过上一帧移动后到达蓝色的位置这时通过上诉算法可以检测到胶囊腾空,这时他的速度为水平速度(红色)+下滑速度(绿色)。

2如果检测到碰撞平面但是平面以及它们的交线都是不可行走的(倾斜角大于可行走角度)那么依次将当前速度在碰撞平面分解,以及检测每一条可能下滑的交线。得出速度后检测是否是有效速度具体过程和前面检查水平速度时的方法一样,只是将速度投影到平面上的方法不一样具体方法可以根据程序需要,我这里采用首先去掉原始速度在碰撞平面法线的分量,然后将速度分解为2个速度一个是贴着平面水平移动的速度另外一个是贴着平面下滑的速度。注意如果上一帧更新后物体处于下滑状态那么当前速度就因该是该下滑速度,否则则是用户输入的速度。

如果用户输入的速度是跳跃也就是带Z分量的速度那么,计算初始速度这一步需要略过直接输入给下一阶段用户起跳的速度。

阶段2计算初始速度引起的碰撞

对于多数情况来说,计算完初始速度就不会再发生碰撞了,一旦发生,那么我们依旧传入碰撞面的那些法向量,碰撞点的信息,同样采用前面计算初始速度时所采用的方法,计算出碰撞后的调整速度。

整个处理过程基本上就是这样的,其中可能还会出现一些小问题比如说误差控制等。总结一条就是人物行走要么研着平面分解速度要么沿着2个平面的交线行走或者下滑。这个是Demo示例画面(由于没有人帮我做动画。。所以demo中目前只有行走动画,没有起跳,下落等动画。。)

Shi ruo yu(fishboy)

本文Demo地址

http://www.cnblogs.com/Files/fishboy82/demosry.rar (原站链接)

http://dev.gameres.com/Program/Visual/3D/demosry.rar (GameRes链接)

3D网游中人物的碰撞后反应控制相关推荐

  1. Unity 3d网游画面的3d效果

    玩家选择某款游戏,第一要素是什么?优质的场景画面和良好的视觉效果,绝对是关键.近年来,但凡是画面上乘的网游,多半会被冠以大作的称号,而这也是能够实现优质画面的游戏引擎备受国内厂商推崇的原因. 就如当前 ...

  2. 从画面质量看国产3D网游的技术性崛起

    http://lichufan.blog.sohu.com/70214695.html 国产网游近年来的发展速度有目共睹,无论是在质量还是数量上都有了长足的进展.其中不少游戏在引擎程序.画面美工和设计 ...

  3. 浅谈3D网游引擎变迁史 看国产游戏引擎趋势

    玩家们在享受游戏带来的快乐时,其实很少想到游戏引擎到底发挥了多么重要的作用.无论是2D游戏还是3D游戏,游戏引擎都充当着游戏骨架的角色,没有游戏引擎就无法做出一款真正的游戏,通过游戏引擎制作者可以把画 ...

  4. 扎实走来的2D网游与突飞猛进的3D网游

    扎实走来的2D网游与突飞猛进的3D网游 从文字MUD到以画面形式表现的2D图形网游,我们经历了网络游戏的两个时代.随后出现的<奇迹>.<仙境传说>等2D+3D的混合模式即2.5 ...

  5. 网游中的网络编程系列1:UDP vs. TCP

    原文:UDP vs. TCP,作者是Glenn Fiedler,专注于游戏网络编程相关工作多年. 目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网 ...

  6. 奇幻3D网游《魔咒Online》完整源码

    魔咒Online全套源码,vc++开发,包含全套引擎源码.数据库和一些文档,解压后700多MB,本人未做编译测试,本人绝对没有做任何删减或修改,拿到什么样就是什么样,说这话的原因是本人实在是害怕了,以 ...

  7. 网游中针对网络延迟的优化

    在网络游戏中,由于延迟或者网络状况的抖动,可能会将客户端效果产生一定的扭曲和卡顿.影响玩家体验以及进一步的操作.要降低因为延迟带来的体验问题,有两种策略,一种为客户端预测,一种为延迟补偿. 1.客户端 ...

  8. Adobe Unity大战3D网游市场

    供稿/ IIEEG 假如分析师的判断无误,整个游戏行业未来五年的市场规模将达870亿美元,在线和移动游戏的份额将占据半壁江山,那么问题就来了:拿什么去抢占这块市场蛋糕? 支持开发3D浏览器游戏的先进技 ...

  9. 《教你10分钟制作3D网游》视频吐槽

    源自GAMERES社区的MGE引擎(也即神秘游戏引擎),近期曝光了第一份制作游戏的带演示视频,透过视频我们发现,这不仅是一份演示或教程,更是一个略带心酸的故事. 视频刚开始,在悲伤的气氛下介绍了作者从 ...

最新文章

  1. 关于ListView顶部和底部滚(拖)动出现阴影解决方案
  2. javaweb mooc在线系统案例实战-张晨光-专题视频课程
  3. 《C++ Primer 第五版》(第6.3~6.7节)——返回指向数组/函数的指针,函数重载,默认形参、inline函数和constexpr函数
  4. knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案
  5. Ubuntu 14.10 下安装java反编译工具 jd-gui
  6. C中的预编译宏定义-转
  7. 参数调整 新部署rac_CDH5部署三部曲之三:问题总结
  8. 【融云分析】 IM 即时通讯之链路保活
  9. C++中的set(STL的应用部分)
  10. winpe修复计算机无法启动,pe系统windows启动修复工具怎么使用
  11. easyrecovery15新版绿色序列号数据恢复软件
  12. java日期函数_java常用日期函数总结
  13. 利用学生身份“白嫖”-教育优惠
  14. 网易163邮箱模拟登录
  15. c语言vt指令,VT系列一:VT简述
  16. 为了防止女朋友怼我,我就先用python爬了3600个怼人表情包等她来战!
  17. leetcode 笨阶乘
  18. scala中下划线的几种含义
  19. 【ceph】ceph osd blacklist cep黑名单|MDS问题分析
  20. MATLAB中simulink的SIL测试

热门文章

  1. CODING 敏捷实战系列课第三讲:可视化业务分析
  2. Marvolo Gaunt's Ring 【CodeForces 855B】
  3. ringbuff进阶 evbuffer
  4. matlab 图中lengend换行
  5. 关于C语言编译器提示[Error] Id returned 1 exit status的原因
  6. ORACLE 中OVER()结合rank(),dense_rank(),rownumber() 使用方法
  7. presto(一) presto概述
  8. 架构师修炼系列【FMEA故障分析与影响分析】
  9. Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二
  10. 苹果手机消息先发给服务器,iPhone接收微信信息延迟,可能是这3个问题导致的,赶紧自查一下...