Unity3D游戏开发初探—3.初步了解U3D物理引擎

1、什么是物理引擎?

  四个世纪前,物理学家牛顿发现了万有引力,并延伸出三大牛顿定理,为以后的物理学界的发展奠基了强大的理论基础。牛顿有句话是这么说的:“若是说我看得比较远的话,那是由于我站在巨人的肩膀上。”html

  平常工做生活中,咱们写文档须要Word、Excel、Visio等办公软件,写程序须要Visual Studio、Eclipse等各类集成开发环境、美术设计须要3dsMax、Maya、Photoshop等,正是由于有了这些强大的工具,咱们的工做效率才会愈来愈高效。因此用记事本写代码、用Windows画图画蒙娜丽莎什么的,只是我的能力的体现,保留一份敬佩的心情就行了,可别真应用到实际工做中哦,老板会疯掉的,么么嗒!web

  话说不知道当年那个给牛顿带来启迪的苹果,究竟是掉在了地上仍是真的掉在了牛顿的头上,总之它就是往下掉了。运用基本的初中物理知识咱们就知道这是由于地球对苹果施加了重力。一样的还有在“愤怒的小鸟”中,咱们把小鸟用弹弓弹向空中以后,始终都会掉落在地面上。工具

  那么,在Unity3D的游戏开发中,是经过什么机制来实现物体的物理效果的呢?咱们把目光转移到传说中的物理引擎上。物理引擎经过为刚性物体(游戏中的具体游戏对象-GameObject)赋予真实的物理属性的方式来模仿真实世界中的物体碰撞、跌落等反应。这里,咱们能够简单地理解为Unity3D默认帮咱们实现了一个让游戏对象具备真实物理对象的真实属性(就像微软给咱们首先铺垫了.NET Framework,而咱们要作的就是在.NET Framework为咱们提供的强大CLR和FCL之上编写代码实现具体的项目,而具体的类和对象怎么建立、分配内存、释放资源和封装方法咱们通常都交给.NET Framework去处理)。例如游戏引擎中提供了Rigid Body(刚体)组件,为对象加入了该组件以后,游戏对象若是判断脚下无支撑地面就会自动往下掉,就像当年从树上掉落砸到牛顿童鞋的苹果同样。性能

  简而言之,物理引擎就是模拟真实世界中物体碰撞、跌落等反应的引擎学习

扩展:Unity的物理引擎使用的是Nvidia的PhysX,PhysX 是一套由Nvidia设计的执行复杂的物理运算的技术。有关PhysX的相关信息请参阅:http://baike.baidu.com/link?url=kESZ9LXKgp-inbAF-tdjV3OUrwh9nxWnzqWBcGuXV51ightRio9evZ2nujXCnKdxlI3flDCWTwk2jXNH67KVb_动画

2、砸牛顿的苹果—为游戏对象增长Rigid Body(刚体)

  当一个游戏对象被赋予Rigid Body(刚体)组件以后,游戏引擎就会对其进行物理效果模拟。同时咱们也能够给这个对象施加各类做用力,让它运动起来。另外若是要实现重力的效果,那么相应的游戏物体都必须附上刚体组件。this

  那么,这里咱们经过一个小例子来看看刚体组件的应用。url

  (1)在Hierarchy中Create如下游戏对象:一个Sphere,一个Direction Light,一个Plane(这里能够理解为地平面)。spa

  首先将Plane的Position属性设置为(0,-2,0),让Plane显示在Sphere的下方,做为Sphere跌落的地平面;设计

  而后将Sphere的Position属性设置为(0,2,0),让Sphere显示在Plane的上方,这样Sphere可以显示一个完整的跌落效果;

  最后将Main Camera的Position属性设置为(0,0,-5),让主视角可以完整看到跌落效果,具体视角以下图因此:

  (2)在Hierarchy中选中Sphere,在菜单栏中选择Component-Physics-RigidBody,便为Sphere增长了一个刚体组件。这下,这个Sphere便有了重力。点击预览按钮,咱们能够看到Sphere跌落的效果。(若是不增长Plane,Sphere会一直往下跌落,有兴趣的朋友能够本身试试。)

  (3)这里,可能有的读者会说,一个球若是谈到地上应该会天然地往上弹,弹一会以后才会平躺在地面上。也就是说,咱们这个球不但应该具备重力,还应该具备弹力。没事!物理引擎早就帮咱们想好了。在资源管理器中的Assets上单击鼠标右键,选择Import Package-Physic Material(也就是导入一个物料材质的包),在弹出的选择框中选中第一项Bouncy。

  (4)在Assets中找到刚刚导入的Bouncy包,选中Bouncy并拖动到Hierarchy中的Sphere对象上,这样就为Sphere增长了一个弹力的物理材质。也就是说,如今咱们这个球能够在跌落到地面以后反弹了。

  (5)这下,咱们再预览一下,看看效果:

  (6)最后,咱们来关注一下RigidBody的几个属性:

  ①Mass:质量—>学过物理的同窗们都知道的吧,质量越大,惯性越大。这里的单位能够本身统一规定,可是官方给出的建议是场景中的物体质量最好不要相差100倍率以上。估计是防止两个质量相差太大的物体碰撞后会产生过大的速度,从而影响游戏性能吧。

  ②Drug:阻力(也能够表示为摩擦力)—>这里指的是空气阻力,当游戏物体收到某个做用力的时候,这个值越大越难移动。若是设置成无限的话,物体会当即中止移动。PS:上面那个Demo里边我就将Sphere的Drug设置为了0.5。

  ③Angular Drag:角阻力—>一样指的是空气阻力,只不过是用来阻碍物体旋转的。若是设置成无限的话,物体会当即中止旋转。

  ④Use Gravity:是否使用重力—> 勾选了这个项,游戏对象就会受到重力影响。

  ⑤Is Kinematic:是否动态—>勾选这个选项会使游戏对象不受物理引擎的影响,但这不等同于没有刚体组件。这一般用于须要用动画控制的刚体,这样就不会由于惯性而影响动画了。

  另外,还有Interplate(差值类型)Collision Detection(碰撞检测方式)以及Freeze Position/Rotation(冻结位置/旋转),若是你有兴趣,请参阅本文的参考文献之一:《物理引擎:刚体与力》。

3、要重力更要“给力”—为游戏对象增长力

  相信你们都玩过Angry Birds—愤怒的小鸟吧,咱们在弹弓上将小鸟射出。根据咱们对弹弓的不一样力度不一样角度,小鸟飞出的距离有长有短,力量有轻有重。

  (1)在刚刚的Demo基础上增长一个C# Script,命名为AddForce。双击该脚本文件,在Update方法中写入如下代码:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class AddForce : MonoBehaviour
 5 {
 6 
 7     // Use this for initialization
 8     void Start()
 9     {
10 
11     }
12 
13     // Update is called once per frame
14     void Update()
15     {
16         // 判断用户是否按下了鼠标左键(0为左键,1为中建,2为右键)
17         if (Input.GetMouseButtonDown(0))
18         {
19             // 参数一:朝哪一个方向使力?使多大的力?
20             // 参数二:给什么类型的力?
21             this.gameObject.rigidbody.AddForce(Vector3.forward * 50, ForceMode.Impulse);
22         }
23     }
24 }

  (2)编写完成以后,仍是老规矩:将脚本拖动到Sphere对象上进行绑定(也能够说是将脚本依附于游戏对象)。绑定完成以后,便可预览该“给力”效果。在Sphere跌落到地平面的时候,点击鼠标左键,该Sphere便迅速向前飞出。

PSrigidbody.AddForce(Vector3.forward*50,ForceMode.Impulse)表示给一个向前(up为向上,down则为向下,back为向后)为50的力->因此Sphere会弹得那么有力!Impulse表示默示冲击力。代码中首先判断用户是否点击了鼠标左键,若是点击了则给Sphere对象增长一个向前的力。

 (3)那么,看到这里也许玩过不少游戏的你会说:能不能让小球朝着我鼠标指的方向飞呢?答案是确定的,Unity3D早就为咱们提供了这样的方法,让咱们能够“指哪打哪”!这里就涉及到一个如何将鼠标所指示的屏幕坐标转换为世界坐标(3D游戏中所能识别的正确坐标—NGUI坐标)的问题,在Unity中可使用Camera.main.ScreenToWorldPoint(new Vector3(x,y,z))方法来实现。那么,如今就来实践一下,修改刚刚的脚本代码以下:

 1     void Update()
 2     {
 3         // Demo1: 判断用户是否按下了鼠标左键(0为左键,1为中建,2为右键)
 4         //if (Input.GetMouseButtonDown(0))
 5         //{
 6         //    // 参数一:朝哪一个方向使力?使多大的力?
 7         //    // 参数二:给什么类型的力?
 8         //    this.gameObject.rigidbody.AddForce(Vector3.forward * 50, ForceMode.Impulse);
 9         //}
10 
11         // Demo2:朝着用户指定的区域为游戏对象给“力”
12         if (Input.GetMouseButtonDown(0))
13         {
14             Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position); 
15             Vector3 targetPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
16                 Input.mousePosition.y, screenSpace.z));
17             Vector3 dirPos = targetPos - Camera.main.transform.position;
18 
19             this.gameObject.rigidbody.AddForce(dirPos * 10, ForceMode.Impulse);
20         }
21 }

 (4)保存以后,再次预览效果,差很少达到预期效果了,指哪打哪!

4、小结

  本篇主要介绍了物理引擎最重要的刚体组件,它让游戏对象一秒具备现实物理对象的重力效果。而为对象增长冲击力,可让对象实现显示对象中的冲击效果,对于制做游戏有着重要的做用,也是后续篇制做打箱子游戏的基础。转眼之间,今天就是正月十四了,后天就要回学校了,回到成都了。抓紧时间,把最后一篇也是本系列初探Unity3D的完结篇完成,也算对得起本身这一段时间的成果了,同时也谢谢各位园友给个人鼓励!最后,再谢谢杨中科老师在上一篇博客中给个人鼓励,谢谢如下参考文献的做者!

参考文献与资料

  (1)Unity3D基础教程之组件介绍—物理引擎:http://www.narkii.com/club/thread-289321-1.html

  (2)Unity3D学习笔记(十一):物理引擎之刚体与力:http://bbs.9ria.com/thread-186986-1-1.html

  (3)传智播客Unity3D公开课:http://net.itcast.cn/subject/Unity3D/index.html

  (4)物理引擎-百度百科:http://baike.baidu.com/link?url=ff2cOmwhuHmwPPJT5ntk7_5UxqnUdQxrJuar3iLIzvM55ZEbCW3vS2SQ6nAYX4aD

 

相关文章
相关标签/搜索