Unity中可以扩展的相机属性●清除标记:决定场景的哪个部分需要清除。你可以创建多个相机并赋予它们不同的深度。如果当前相机没有设置天空盒,它将缺省使用在渲染设置中的天空盒。武器相机的Clear Flags应该被设置为仅深度。为了使UI显示在所有其他相机视的顶部,你还需要设置Clear Flags和Depth only并确定相机的深度比其他相机的高。图7-53景深相机正交相机。......
2023-10-17
图8-32 Ball脚本创建
1)概要
前面创建了一个游戏项目,并且创建了玩家角色和小球这些游戏对象,还通过添加游戏脚本实现了小方块的弹跳。虽然功能比较简单,但是完整地表现了使用Unity开发游戏的大体流程。
为了让这个游戏变得更加有趣,下面要进一步完善玩家角色和小球的动作。
目前小球是静止在空中的,下面来尝试让它朝玩家角色飞去。为了令小球能够模拟物理运动,需要添加Rigidbody组件。同时还需要创建一个Ball的脚本(见图8-32)。此操作见8.2小节中的步骤10)和步骤11)。
添加了Ball脚本以后,我们要对Start方法做如下修改:
游戏开始后,小球将向画面左侧飞去(见图8-33)。
3)创建大量小球(预设游戏对象)
为了能够随时创建出小球对象,首先需要对小球对象进行预设。
(1)请将层级视图中的Ball项文本拖拽到项目视图中。项目视图中将出现Ball项。同时,层级视图中的Ball项文本将会变为蓝色(见图8-34)。
(2)将项目视图中的Ball预设拖拽到场景视图中,可以看到场景中会多出一个小球对象(见图8-35)。预设了游戏对象后,就能够非常容易地创建出多个同样的物体。
图8-33 游戏开始状态
图8-34 Ball项文本变为蓝色
图8-35 多出一个小球对象
(3)将Player和Floor游戏对象也做成预设(见图8-36)。
图8-36 将Player和Floor游戏对象做成预设
4)整理项目视图
(1)用文件夹将这些项目归类整理。在项目视图左上角的菜单中单击Create→Folder按钮后,项目视图中将生成一个文件夹,将名字改为Prefabs(见图8-37)。
图8-37 创建文件夹并修改其名称
图8-38 移动Player预设和Floor预设至Prefabs文件夹
(2)将预设Ball Prefab拖拽到Prefabs文件夹下。单击Prefabs文件夹,可以看到刚才移动的Ball预设。接着把Player预设和Floor预设也移动到Prefabs文件夹下(见图8-38)。
(3)采用同样的方式创建Scenes、Scripts、Materials文件夹,并把各项目放到相应的文件夹下。注意在创建前务必先单击项目视图左侧的Assets图标以确保当前文件夹回到Assets(见图8-39)。
图8-39 保存文件夹回到Assets
图8-40 游戏对象命名
5)发射小球(通过脚本创建游戏对象)
(1)在窗口顶部菜单中依次单击GameObject→Create Empty。由于该游戏对象被用作发射台,因此命名为Launcher(见图8-40)。
(2)对游戏对象Launcher进行预设(见图8-41)。
(3)创建Launcher脚本(见图8-42)。
(4)将Launcher脚本添加到Launcher预设中去(另外一种方法)。
图8-41 对Launcher进行预设
图8-42 创建Launcher脚本
①在项目视图中切换到Prefabs文件夹,单击选中Launcher预设。此时检视面板上将显示Launcher的相关信息,然后单击最下方的Add Component按钮(见图8-43)。
图8-43 添加组件
②在标题为Component的下拉菜单中单击最下方的Script项。单击后菜单将向左移动,显示出所有创建好的脚本。找到Launcher脚本并单击(见图8-44)。
小结:现在已经知道在检视面板中也可以添加组件,除此之外,还可以使用窗口顶部菜单或者直接拖拽。
(5)编辑Launcher脚本。除了Update方法有变动之外,还增加了ballPrefab变量。Instantiate是通过预设生成游戏对象实例的方法。不过脚本中并没有对ballPrefab变量进行初始化的代码,所以在游戏运行前必须先在检视面板中对ballPrefab变量赋予预设对象值。
图8-44 找到Launcher脚本
图8-45 public成员变量
从项目视图中选择Launcher预设。可以看到在检视面板中的Launcher(Script)标签下显示有Ball Prefab项。脚本代码中声明的所有public成员变量都将在这里列出(见图8-45)。
往类中新添加的变量默认表示为None(GameObject),意味着该变量还未被赋值。请将项目视图中的Ball预设拖拽到这里(鼠标左键按着不要松手),如图8-46和图8-47所示。
(6)运行游戏。每次单击鼠标右键时,都会射出一个小球(见图8-48)。这里,为了和预设对象分开,我们把脚本中通过Instantiate方法生成的游戏对象称为实例,把产生实例的过程称为实例化。
图8-46 Ball预设拖拽(1)
6)删除画面外的小球(通过脚本删除游戏对象)
游戏现在出现了一个Bug:发射出去的小球永远不会消失(见图8-49)。游戏运行时由脚本动态生成的游戏对象也会显示在层级地图中。每单击一次鼠标,层级视图中都会增加一个Ball(Clone)游戏对象。因此即使小球已经跑出游戏画面之外,这些游戏对象也并未消失。
跑出画面之外的小球不会再回到画面中,所以完全可以删除。在脚本Ball.cs中添加OnBecameInvisible方法,该方法可以被添加到Ball类定义范围内的任意位置。OnBecameInvisible方法是在游戏对象移动到画面之外不再被绘制时被调用的方法。Destroy(this.gameObject)则是删除游戏对象的方法。
图8-47 Ball预设拖拽(2)
图8-48 运行游戏
图8-49 小球不会消失
注意:如果把参数设置成this的话,删除的就不是游戏对象,而是Ball脚本组件。
7)防止玩家角色在空中起跳(发生碰撞时的处理)
为了防止玩家角色在空中再次起跳,我们来添加下列处理:①添加着陆标记;②着陆标记值为false时不允许起跳;③将起跳瞬间的着陆标记设为false;④将着陆瞬间的着陆标记设为true;⑤修改Player脚本,代码如下。
当一个游戏对象同其他对象发生碰撞时,OnCollisionEnter方法将被调用。这是为了检查玩家角色是否着陆而添加的。在该方法中把着陆标记的值设为true。这样玩家角色就不能在空中再次起跳了。
8)禁止玩家角色旋转(抑制旋转)
在某种程度上完成了玩家角色和小球的脚本编程后,让我们来调整各相关参数,以使角色在起跳后能和小球发生碰撞。这里我们采用下列值:玩家角色的位置:(-2.0,1.0,0.0);玩家角色的起跳速度(Player.cs脚本中jump_speed的值):8.0;小球的位置:(5.0,2.0,0.0);小球的初始速度(Ball.cs脚本中使用Start方法设定的值):(-7.0,6.0,0.0)。
(1)选择项目视图中的Player并打开检视面板中的Rigidbody标签下的Constraints项。(www.chuimin.cn)
(2)单击左边的三角形图标,下面会进一步显示Freeze Position和Freeze Rotation。其中Freeze Position对于将游戏对象的位置坐标固定在某些方向上,Freeze Rotation则用于固定其角度(见图8-50)。由于我们希望玩家角色只上下跳跃而不做左右和前后的移动,因此:
(3)把Freeze Position的“X”“Z”前面的复选框选中。Freeze Rotation方面则把“X”“Y”“Z”全部选中(见图8-51)。
图8-50 Freeze Position和Freeze Rotation(1)
图8-51 Freeze Position和Freeze Rotation(2)
9)让玩家角色不被弹开(设置重量)
选择项目视图中的Ball预设,打开Rigidbody标签,将Mass项的值由1改为0.01(见图8-52)。Mass项用于设定游戏对象的重量。两个游戏对象发生碰撞时,Mass值较大的物体将保持原速度继续运动,相反Mass值较小的物体则容易因受到冲击而改变移动的方向。
图8-52 Mass项设置
10)让小球强烈反弹(设置物理材质)
(1)创建物理材质。从项目视图的Create菜单中选择Physic Material,创建一个新材质并将其名称改为Ball Physic Material(见图8-53)。相对于用来指定颜色等可以看见的属性材质,物理材质则是用于设定弹性系数和摩擦系数等与物理运动相关的属性。
图8-53 创建新材质并设置名称
(2)修改属性值。在项目视图中选择Ball Physic Material后,在检视面板中选择Bounciness,将其值由0改为1。这个值越大,游戏对象越容易被“弹开”(见图8-54)。
图8-54 修改属性值
(3)将新创建的材质拖拽到Ball预设下的Material。从项目视图中选择Ball预设,接着把Ball Physic Material拖拽到检视面板中Sphere Collider标签下的Material(见图8-55),或者可以单击Ball Physic Material右侧的圆形图标。这时Select Physic Material窗口将被打开,在这个“物理材质选择窗口”中也可以进行选择设定(见图8-56)。
图8-55 将新创建的材质拖拽到Ball预设下的Material
图8-56 物理材质选择窗口
11)消除“漂浮感”(调整重力大小)
(1)在窗口顶部菜单中依次单击Edit→Project Settings→Physics按钮(见图8-57),检视面板中将切换显示PhysicsMana(见图8-58)。
图8-57 窗口顶部菜单
图8-58 窗口菜单
(2)将Gravity项的“Y”值稍微提高一些,在此设为-20(见图8-59)。
(3)调整参数。通过增强重力可以减弱物体在运动时的“漂浮感”,不过跳跃的高度和小球的轨道也显得比原来低了。这种情况下,我们可以考虑调整为下列数值:玩家角色的起跳速度(Player.cs脚本中的jump_speed的值):12.0;小球的初始速度(Ball.cs脚本中使用Start方法设定的值):(-10.0,9.0,0.0)。
图8-59 Gravity项Y值设置
12)调整摄像机的位置
(1)选择摄像机后,场景视图右下角将出现一个小窗口。这是从摄像机看到的画面。如果无法看到这个窗口,请在检视面板中展开Camera标签(见图8-60)。
图8-60 场景视图
(2)为了能够俯视地面,需要使摄像机在往上偏移的同时绕X轴旋转,调整角度时需把移动工具切换为旋转工具(见图8-61)。用移动工具调整摄像机的位置,用旋转工具调整摄像机的角度(见图8-62)。
(3)在检视面板中输入数值(可根据自己喜好进行设置)(见图8-63)。
(4)对比效果。调整摄像机前如图8-64所示,调整摄像机后如图8-65所示。
图8-61 工具切换栏(1)
图8-62 工具切换栏(2)
图8-63 数值输入
图8-64
图8-65
13)修复空中起跳的bug(区分碰撞对象)
(1)bug的发现。试玩游戏后,我们注意到玩家角色和小球碰撞后还可以再次起跳。这可能是因为防止空中跳跃的代码存在bug。
(2)bug的证明。
①游戏启动后,在层级视图中选择Player。可以在检视面板中的Player(Script)标签下看到Is_landing项。这就是在Player脚本中定义过的is_landing变量(见图8-66)。
图8-66 游戏启动、看到Is_landing
②游戏刚开始时画面上还没有小球。随着玩家角色起跳,可以看到Is_landing复选框由取消变为了选中状态,跳跃过程中Is_landing为取消状态(值为false),如图8-67所示。着陆后Is_landing为选中状态(值为true),如图8-68所示。
图8-67 Is_landing变为取消
图8-68 Is_landing变为选中
③修改Player.Update方法如下:
修改后仅添加了Debug.Break方法的调用。在玩家角色起跳时的瞬间暂停游戏的运行。按下播放控制工具条最右边的按钮,在逐帧模式下可以看到玩家角色在一直上升。在玩家角色和小球碰撞的瞬间,Is_landing的值变成了true(此处无法截图,见谅)。搞清楚了bug的原因,接下来就考虑解决bug的对策。
(3)bug的解决如下:
①首先需要区分开碰撞对象是地面还是小球,此处我们可以利用标签。需要对游戏对象的种类进行大致区分时,可以使用标签来分组。添加标签到项目中,在项目视图中选择Floor预设→单击Untagged→单击Add Tag→单击Tags左侧的三角形→单击“+”→输入Floor→再次在项目视图中选择Floor预设→单击Untagged→单击Floor(见图8-69—图8-73)。
图8-69 选择Floor预设
图8-70 选择“+”
图8-71 输入Floor
图8-72 选择Floor
图8-73 单击Floor
②修改脚本。修改Player.OnCollisionEnter方法。在这里提醒下:记得删除了之前在Player.Update方法中添加的Debug.Break()。
使用了标签后就可以区分碰撞对象了。这样一来就只有在和地面碰撞时,也就是着陆时Is_landing的值才会变为true。
有关虚拟现实理论基础与应用开发实践的文章
Unity中可以扩展的相机属性●清除标记:决定场景的哪个部分需要清除。你可以创建多个相机并赋予它们不同的深度。如果当前相机没有设置天空盒,它将缺省使用在渲染设置中的天空盒。武器相机的Clear Flags应该被设置为仅深度。为了使UI显示在所有其他相机视的顶部,你还需要设置Clear Flags和Depth only并确定相机的深度比其他相机的高。图7-53景深相机正交相机。......
2023-10-17
在Assets→Audio文件夹下,右击Create→AudioMixer。只要在主角受伤时播放音效就可以了,开枪的声音同理。刚刚制作的AudioMixer还没有用到,现在我们开始制作,双击AudioMixer,添加一个SoundEffect。在AudioMixer添加一个Music用来控制背景音乐,SoundEffect用来控制音效,Master用来同时控制二者。图8-261enemies放到怪物的AudioSource的output图8-262添加组件图8-263新建脚本MixLevel图8-264把代码放至Canvas回到MasterMixer,单击volumn,选择exposed。图8-267添加music、sound脚本代码回到UI界面里面的slider条,按照不同的slider条功能添加不同的函数。......
2023-10-17
实例化预设使用上面章节中描述的创建预设的方法。一旦你创建了预设,你就可以简单快速地得到一个预设的拷贝,称为实例。为了创建任何预设的一个实例,从工程视图中拖动一个预设到层次或场景视图中。添加组件和脚本当你选中任何预设或物体时,你可以通过使用组件来向其中添加一些额外的功能。脚本也是组件的一种类型。缺省情况下脚本也包含在组件菜单中。你可以通过Components→Camera-Control来找到它。......
2023-10-17
图8-120公有变量初始化这里要注意的是,Tank Mask的选取必须是Players,否则后面子弹的爆炸将不会作用于坦克。图8-121FireTransform的transform设置2)发射子弹接下来就要实现子弹的发射功能,并且子弹可以蓄能,蓄能越久射击距离也就越长,因此也就需要有一个蓄能状态的指示。首先,选中Hierarchy层级下的Tank,为它新建一个子对象Create Empty,命名为FireTransform。该对象主要是规定子弹的射出位置。测试完毕之后,把Hierarchy层的Tank删除掉,保存当前场景。......
2023-10-17
图9-71创建游戏管理器的逻辑脚本游戏胜负逻辑是与GameManager等脚本关联起来的。图9-76添加Look At Target组件运行游戏,发现收集物状态UI已经可以正常显示,面向摄像机了。图9-78添加Wall Mover组件图9-79组件关联在Scripts文件夹内右键Create→C# Script,重命名GoalZone,用于处理到达终点的逻辑。找到VR Win Panel→Exit Game Button上的Button组件,设置On Click事件调用为Game Manager UI→GameManager.ExitGame方法。图9-84设置完成的效果显示成功拾取到4个盾牌收集物到达GoalZone,也会弹出VR Win Panel的UI,可以进行一样的操作。......
2023-10-17
本小节将介绍的是Unity数据库与存储的相关内容。XML的设计宗旨是传输数据,而非显示数据。7)Xml数据生成步骤在Unity引擎中如何生成本地XML数据?8)Xml数据生成示例9)Xml序列化序列化是将对象状态转换为可保持或传输的格式的过程。12)什么是SQLite①SQLite是一款轻型的数据库。语法:SELECT列名称FROM表名称13)Unity当中使用SQLite导入mono.data.sqlite.dll到Assets文件夹代码添加库:using Mono.Data.Sqlite;使用SQLiteConnection对象,进行数据库连接,此操作可以创建空的数据库。关闭数据库连接,释放资源。…......
2023-10-17
尝试添加一个刚体到刚创建的物体上。选择该物体并从菜单中选择Component→physics→Rigidbody。它们使用一个粒子发射器,粒子动画和粒子渲染器来创建一组移动的粒子。音频剪辑是一个引用属性。移除组件如果你想移除一个组件,在检视面板的头部使用option-或右击然后选择移除组件。例如,如果你想访问变换组件的变换功能,你只需要使用transform.Translate()或gameObject.transform.Translate()。使用GetComponent()有许多组件不能成为一个游戏物体类的成员。通过调用GetComponent并存储一个引用到结果中。......
2023-10-17
在先前的PlayerShoot中我们改变一句代码。图8-236设置完成后Apply的效果图8-237EnemyHealth脚本图8-238EnemyHealth脚本图8-239PlayerShoot代码修改图8-240SetTrigger设置图8-241Trigger设置完成图8-242给怪物的Prefab添加EnemyHealth及刚体+碰撞体图8-243怪物被扣血2)动画事件假如你在试验的时候发现报了类似这个错误。图8-247添加变量图8-248StartSinking方法的添加这时候单击运行可以看见怪物死亡,并且下沉了。......
2023-10-17
相关推荐