天天看点

《Unity 4 3D开发实战详解》一6.5 交通工具

本节书摘来异步社区《unity 4 3d开发实战详解》一书中的第6章,第6.5节,作者: 吴亚峰 , 杜化美 , 张月霞 , 索依娜 责编: 张涛,更多章节内容可以访问云栖社区“异步社区”公众号查看。

unity 4 3d开发实战详解

在前面的内容中,讲解了unity开发平台下物理引擎的相关内容,正是这一完善的物理引擎,使得模拟现实变得极其简单。在本小节中,将通过一个交通工具的小案例来模拟现实生活中汽车的各种运动。下面将对交通工具案例的开发步骤进行介绍。

1.案例的构思

在开发案例之前,这里先介绍一下本案例的设计思路。

(1)首先要明确案例要达到的目的。本案例是为了演示使用unity物理引擎模拟现实生活中交通工具的运动特性。

(2)接着要明确案例场景的设计。在本案例中,使用了地形引擎系统,在地形上有一些任意位置形状的小山丘。同时,场景中有一辆汽车模型,在汽车正前方摆放有两个油桶和3个木箱。这些场景的设计是为了观察汽车在地形上的运动以及跟油桶和木箱的碰撞情况。

(3)然后是对汽车模型的开发。导入的汽车模型是不能够运动的,必须给其添加必要的组件。在本案例中,汽车模型整体被添加了刚体和相应的脚本组件,车轮也被添加了车轮碰撞器组件和相应的脚本组件。

(4)最后就是把pc端的程序移植到android设备上。本案例中采用unity引擎自带的single joystick预制件来实现android设备上的操纵杆控制汽车。

2.案例场景的设计

在明确了案例的构思后,就可以按照构思的步骤来进行开发了。主要的开发步骤如下。

(1)首先新建一个项目,选择file→new project选项创建一个新项目,并命名为“vehicledemo”。然后,选择file→save scene(或者按下快捷键ctrl+s)保存场景为car。最后,选择gameobject→create other→directional light来创建一个光源,如图6-118所示。

(2)创建地形。选择terrain→create terrain创建一个新的地形,然后使用地形编辑工具对地形进行适当的编辑,最终的地形效果如图6-119所示。

说明 因为地形引擎系统不是本小节的重点,该内容将在后续的章节里具体介绍,所以,本小节只是简单地说明,如果读者当前还不习惯使用地形引擎系统,可以创建一个平面来替代,相信对认真学习过前面章节内容的读者来说,创建一个平面应该不是什么难题。
《Unity 4 3D开发实战详解》一6.5 交通工具

(3)导入资源。将光盘中本章节对应文件夹下的“资源包”文件夹中的“model.unitypackage”文件复制到第(1)步中新建项目时生成的“vehicledemo”文件夹下。然后,选择assets→import package→custom package导入“model.unitypackage”中的所有文件,如图6-120所示。

(4)在场景中创建汽车和油桶模型。将“assetsmodel”文件夹下的“car_model”拖曳到scene视图中,如果汽车模型没有显示贴图,则可以将“assetsmodelmaterials”文件夹下的“car_material”材质分别拖曳到汽车模型的车身和4个车轮上。然后用同样的方法,在场景中创建两个油桶模型,分别命名为“oiltank1”和“oiltank2”,如图6-121所示。

(5)在场景中创建3个木箱。选择gameobject→create other→cube分别创建3个立方体,且分别命名为“box1”、“box2”、“box3”。然后将“assetstexture”文件夹下的“woodboxtex”纹理贴图分别拖曳到新创建的3个立方体上,调整场景中各个模型的transform参数,如图6-122所示。

《Unity 4 3D开发实战详解》一6.5 交通工具
《Unity 4 3D开发实战详解》一6.5 交通工具

3.案例主体部分设计

前面刚介绍完场景的搭建,接下来将介绍案例主体部分的设计。这部分主要是为了增加案例运行过程中的真实性和交互性,这就需要给场景中的各个游戏对象加上相应的组件,具体步骤如下。

(1)为油桶和木箱添加物理属性。选择component→physics→rigidbody为油桶和木箱添加刚体,接着选择component→physics→box collider为油桶添加“box collider”组件(木箱已有该组件,不需重复添加)。同时,为木箱添加“wood”材质,为油桶添加“metal”材质,如图6-123所示。

《Unity 4 3D开发实战详解》一6.5 交通工具

(2)为汽车的车轮添加“wheel collider”组件。选择gameobject→create empty创建一个空对象,重命名为“flcollider”,然后选择component→physics→wheel collider给“flcollider”添加碰撞体,并将“flcollider”的位置和汽车左前轮位置对齐。按照此操作步骤,依次创建“frcollider”、“blrcollider”、“brcollider”,并组织好目录结构,如图6-124所示。

《Unity 4 3D开发实战详解》一6.5 交通工具

(3)为汽车的车身添加“box collider”组件。选择gameobject→create empty创建一个空对象,重命名为“bottomcollider”,然后选择component→physics→box collider给“bottomcollider”添加碰撞体,并使碰撞体包裹住车身下半部分。按照此操作步骤,创建“topcollider”并使其包裹住车身上半部分,并组织好目录结构,如图6-125所示。

《Unity 4 3D开发实战详解》一6.5 交通工具

(4)为汽车的车轮编写脚本。该脚本的作用是控制车轮的位置和旋转参数,使车轮在车的移动过程中跟着转动,这样车轮的运动看起来更逼真。具体代码如下所示。

1 var frontleftwheel : wheelcollider;//定义左前轮碰撞器

2 var frontrightwheel : wheelcollider;//定义右前轮碰撞器

3 var gearratio : float[];//定义齿轮比数组,程序会根据齿轮数比来决定应该给车轮多大的扭矩

4 var currentgear : int = 0;//定义当前齿轮索引

5 var enginetorque : float = 600.0;//定义发动机转矩

6 var maxenginerpm : float = 3000.0;//定义发动机最大转速

7 var minenginerpm : float = 1000.0;//定义发动机最小转速

8 private var enginerpm : float = 0.0;//定义发动机转速

9 var movejoystick : joystick;//定义操纵杆

10 function start () {

11 //给汽车质心的y方向的位置赋值,确定汽车质心的位置是为了保证汽车在运动过程中不容易翻车

12 rigidbody.centerofmass.y = -1.5;

13 }

14 function update () {

15   rigidbody.drag=0.15 +rigidbody.velocity.magnitude/25;//设置汽车运行阻力,限制汽车速度

16 //计算汽车转速

17 enginerpm = (frontleftwheel.rpm + frontrightwheel.rpm)/2 * gearratio[currentgear];

18 shiftgears();//调用方法

19 if(application.platform == runtimeplatform.android) {//如果程序运行在android平台上

20 var touchkey_x : float = movejoystick.position.x; //获取操作杆的坐标x

21 var touchkey_y : float = movejoystick.position.y; //获取操作杆的坐标y

22 //根据操纵杆的y位置计算汽车速度

23 frontleftwheel.motortorque = enginetorque / gearratio[currentgear] * touchkey_y;

24 frontrightwheel.motortorque = enginetorque / gearratio[currentgear] * touchkey_y;

25 //根据操纵杆的y位置计算汽车转向

26 frontleftwheel.steerangle = 10 * touchkey_x;

27 frontrightwheel.steerangle = 10 * touchkey_x;

28 }else {//如果是其他平台

29 //计算汽车速度,当按下前进键或后退键,计算两个前轮的马达转矩

30 frontleftwheel.motortorque = enginetorque / gearratio[currentgear] * input.getaxis("vertical");

31 frontrightwheel.motortorque = enginetorque / gearratio[currentgear] * input.getaxis("vertical");

32 //控制汽车转弯,当按下左右按键时,计算两个前轮的旋转角度

33 frontleftwheel.steerangle = 10 * input.getaxis("horizontal");

34 frontrightwheel.steerangle = 10 * input.getaxis("horizontal");

35 }}

36 function shiftgears() {//转换齿轮数的方法

37 if ( enginerpm >= maxenginerpm ) {//如果引擎转速大于等于最大引擎速度

38 var appropriategear : int = currentgear;//定义一个合适齿轮数

39 for ( var i = 0; i < gearratio.length; i ++ ) {//遍历所有的齿轮数比

40 //如果左前轮转速和齿轮数比的乘积小于最大引擎转速

41 if ( frontleftwheel.rpm * gearratio[i] < maxenginerpm ) {

42 appropriategear = i;//赋值

43 break;//跳出循环

44 }}

45 currentgear = appropriategear;//赋值

46 }

47 if ( enginerpm <= minenginerpm ) {//如果引擎转速小于等于最大引擎速度

48 appropriategear = currentgear;//赋值

49 for ( var j = gearratio.length-1; j >= 0; j -- ) {//遍历所有的齿轮数比

50 //如果左前轮转速和齿轮数比的乘积大于最小引擎转速

51 if ( frontleftwheel.rpm * gearratio[j] > minenginerpm ) {

52 appropriategear = j;//赋值

53 break;//跳出循环

54 }}

55 currentgear = appropriategear;//赋值

56 }}

继续阅读