Unity第一人称设计游戏雏形

编程入门 行业动态 更新时间:2024-10-27 17:10:59

Unity第一人称设计游戏<a href=https://www.elefans.com/category/jswz/34/1742214.html style=雏形"/>

Unity第一人称设计游戏雏形

本博主要是通过简单的Unity第一人称设计游戏的简单的实现来回顾相关知识点,纯属个人碎碎念,不具有普适性,大神绕道。


因为基本是一个游戏了,所以要考虑游戏怎么开发。那就要有游戏的整体框架和模块的思路。

首先你要这样想,我的游戏是什么样的场景,比如说基本的元素,我要有好看的地、漂亮的光、我要有枪,枪要有子弹,另外我要有可以命中的物体。所以这是基本的元素,那这些东西,我们都可以通过建模来实现。Unity直接导入这些模型或者图片就行了。

然后你要想,我的游戏规则是什么,比如说,我的枪可以发子弹,子弹打中这个东西就能得分。那么子弹是不是得有方向和速度?你的相机是不是得能够移动?

最后你想,那这些规则和元素怎么建立联系呢?子弹的方向和速度需要附加到子弹这个游戏物体上,相机的移动脚本需要挂到相机上,然后我还需要碰撞检测对不对等等。


一般一堵墙是由许多个砖块组成的,一个砖块我可以用一个Cube表示,那墙呢?我可以用多个Cube表示,但是,我要把好多个Cube都放在Hierarchy面板上吗?那实在是太难受了。此时我可以创建Empyt GmmeObject作为所有Cube的“老父亲”,ctrl+D是复制的快捷键:

这里我们用相机作为第一人称,从相机发射子弹,会给你一种本人在发射子弹的感觉,所以脚本直接写在相机下面,我们要有子弹,子弹有初速度,它会做抛物线运动,因此它是一个刚体。然后我们要移动相机,因为移动相机才能改变子弹的发射方向。

在工程面板中拽住你的脚本文件Shooter,把它拖动到层次面板中的Main Camera上释放。这时,你会看到脚本(Script)以组件的形式添加在了Main Camera的检视面板中,并且你还能看到我们在脚本中声明的三个公有变量。

大家还可以看到,我们的Bullet变量的值是None,这是因为我们还没有在Unity中创建炮弹对象,不要着急,我们很快就会走到那一步。

这是Unity的一个内置方法,能够检测出用户的键盘输入(Input),我们为这个方法传递了两个参数"Horizontal""Vertical",告诉Input.GetAxis()方法获取(监听)用户在水平和垂直轴上的键盘输入。当用户按下正方向键时,Input.GetAxis()方法返回1,当用户按下负方向键时,Input.GetAxis()方法返回-1,而当用户放开按钮时,Input.GetAxis()方法返回0。然后,我们再乘上moveSpeed(移动速度值),这样便得到了我们所需要的速度(方向和数值)。

transform则代表的是相机的Transform(变换)属性,transform调用了自身的一个Translate()方法,用来移动对象本身。而(h,v,0)则表示一个三维向量,表示我们在X、Y、Z方向上的移动速度。

 

似乎这个代码看起来是可以了,你看我们声明了子弹,声明了子弹的属性;我们还可以通过键盘来控制相机的移动。那我们试试看效果吧。然后我们发现问题了,好像相机很着急,移动的太快了,这TM是怎么回事?

我们需要在为h、v两个速度变量赋值前,在等式右边乘上Time.deltaTime(连续2次调用Update()函数的间隔时间)来抵消Unity的帧频,使得相机的移动恢复正常。


下面是炮弹:

①在层次面板点击Create按钮,选择Sphere,在检视面板修改它的位置为(4,4,4),回到层次面板双击聚焦该对象。

②在工程面板点击Create按钮,选择Material,重命名该材质球为bulletColor,在检视面板打开拾色器,选择绿色,关闭拾色器窗口。选择拖拽该材质球到层次面板中Sphere对象上释放,完成材质赋予。

③在层次面板选中Sphere,同之前一样在主菜单栏选择Component | Physics | Rigidbody,为Sphere对象添加刚体物体效果。

④在层次面板中选中Sphere对象,把它拖拽到工程面板中释放,它将会被保存为预制元件,把该元件重命名为Projectile,然后删除原层次面板中的Projectile对象。(YG: 原来创建prefab还有这么快捷的方法。注意也可以直接对prefab设材质加rigidbody),但是我本人喜欢先对Hierarchy面板下的物体做完“手脚”,再变成prefab,因为这样感觉很舒服,像是自己完成了一个完整的模板一样。

我们之所以这样做,是因为我们希望玩家在按下发射按钮之后,炮弹才出现在场景中,而不希望玩家还没做任何操作,场景中已经有了一颗炮弹,我们可已通过脚本,在游戏进程中实时地创建炮弹,这样更为真实。

OK,那我们要发射炮弹了,肯定是用户点击鼠标或者敲击键盘可以发射炮弹。所以键盘交互还是需要滴。

你来想想看,我们需要干点什么?用户点击鼠标左键之后也就是Fire1,肯定要在场景中生成一个子弹对吧,并且还要生成一个具有初始速度,抛物线状跑的可欢快的子弹对吧。好,那我们生成。

我们在if条件语句中定义了一个新变量叫instance(实例),然后给定它的类型为刚体,接着我们为实例化执行函数Instantiate()传入了3个参数,第一个是实例化对象bullet(也就是我们的炮弹),第二个是Shooter脚本附加对象(也就是相机)transform组件的位置,第三个是它的旋转,实例化函数执行完成后返回一个bullet实例,接着把它赋予instance变量保存。

其实我这样理解instance实例,它相当于把虚的变成实的。你不是说你有子弹吗?你给我实例一个出来!恩?这样怎么感觉也说不清楚呢?那这样理解,就和c++一样,你不是说你有一个子弹类吗?你光说有什么用?我要对象!有了对象我才能干事儿!恩。。。来我们写点代码:

public class bullet{
public:bullet(vec3 position,vec3 rotation){this.position = position;this.rotation = rotation}~bullet(){};
public:vec3 position;vec3 rotation;};int main(){vec3 pos = camera.transform.pos;vec3 rot = camera.transform.rot;bullet  instance_bullet = new bullet(pos,rot);这是c++
}
public Rigidbody bullet;Rigidbody instance_bullet = Instantiate(bullet,transform.position,transform.rotation) as Rigidbody;//这是Unity中的c#

什么?你还没有看懂???滚去学c++!!!(c++是世界上最好的语言!!!手动狗头)

接下来,我们来为炮弹添加动力,才能让它发射出去。在添加动力之前,我们需要为炮弹添加一个方向,不能让我的炮弹在视口中胡乱发射。以此,我们接着更新Update()函数,为炮弹发射提供一个方向:

在这里,我们又定义了一个变量fwd,它的类型是一个三维向量,用来保存我们炮弹的发射方向。而Vector3.forwardVector3(0,0,1)的简写形式,它表示我们相机局部坐标的Z轴正方向,注意是相机的局部坐标!!!!!!!而TransformDirection()方法是用来把局部坐标转化为世界坐标的(YG:TransformDirection就相当于是transform中提供的一个方法,能够将局部坐标方向转化为世界坐标方向。外面那个fwd需要得到的是世界方向,所以必须转换),上面的代码是把我们相机的正方向转化为世界坐标系的正方向,转化后也正是我们炮弹的发射方向,转化后的值被保存在我们新建的fwd变量中保存。现在,我们拥有了发射方向,我们再来完成最后一步,为炮弹添加动力。接着更新代码:

这行代码中,instancebullet的一个实例),调用一个AddForce()方法,从语义上很好理解,就是增加动力。然后我们传入一个参数fwd * power,之前我们说过,fwd是决定(保存)我们炮弹发射方向的,而power则是我们最开始就定义好的一个公有变量,它保存了决定发射力量大小的一个数量值,这样我们就等于告诉了AddForce()方法:我们要朝哪个方向发射,发射的力度要有多大。(YG: 注意rigidobdy似乎只有force,没有speed,force似乎就是代表了其的加速度。Rigidody发射后,只要其mass不为0,就会受重力的影响)

以下是我们此次案例脚本中的完整代码:

好了,我们怎么把代码和子弹这个prefab联系上呢?

工程面板中拽住Projectile元件,然后把它拖到检视面板的None上面释放,这样我们便完成了二者的关联,很简单吧!


注意:brick也可以设置为prefab,不过这里不需要在程序里生成brick,所以不用prefab也是可以的。而bullet就必须是prefab的,因为我们要不断的生成它的实例,只有在有模板的情况下才能生成实例啊对吧,我们的模板就是prefab。

你会发现每发射一个bullet,旁边就会提示产生了一个物体,如果你不断发射,就会产生许多bullet。其实为了不浪费资源,我们可以在代码中规定bullet过一段时间后自己destroy掉

 


来来来,进一步了解一下prefab,这可是Unity开发的重头戏:

所有在project面板中出现的模型都是prefab,都会在asset文件夹下有对应的文件。当你把一个物体从Hierarchy面板拖动到Project面板时,这个物体自动就变成了一个prefab,你可以看到物体的颜色在Hierarchy中变成了淡蓝色,并且在asset文件夹下有了对应的资源文件。如果这个物体来自于prefab,那么你在其Inspector面板中会看到前面有Prefab字样,在其后有三个按钮:Select, Revert, Apply。如果你点击select,那么就会自动跳转到其所属的那个Prefab的Inspector面板中;可以直接设置这个prefab的属性了。

再举个例子说明Prefab与其实例间的连接关系。造个cube,将其拖入Project面板,将之变成Prefab。修改这个Prefab的size,你会发现那个cube的size也跟着变了,也就是说那个cube的参数来自于此。

再从此prefab中实例化一个cube,名字起为cube2.回到Hierarchy面板,点中cube2,直接修改此cube2的size-y。你会发现原先那个cube并没有变化。再回到project中点中prefab来修改此prefab的size-y参数,你会发现只有cube的y会跟着变,而cube2并不跟着变!-----也就是说如果你修改了某个prefab实例物体的参数,那么这个物体的参数就与prefab断开了联系! 不过如果你修改prefab的其他参数,cube2还是会跟着变的。也就是说看起来prefab实例的每个参数上都应该有个标签,标志其来自于prefab,还是自己完全控制的。如果你修改了cube2的scale-y参数后,点击其inspector面板的Apply按钮,那么你就会发现prefab的y参数就变成了这个物体的参数了,那个cube的相应参数也会变得与cube2同。也就是说依然保持了cube2与prefab的连接关系,而且prefab的参数还与cube2保持了一致!

他这种prefab与物体间的连接关系其实是非常细致的,细致到了每一个参数。

那个revert按钮是干什么呢?当你修改了cube2的scale-y参数后,如果觉着不合适,那你可以点击revert将之恢复,且依然保持了cube2与prefab间的联系。

 

更多推荐

Unity第一人称设计游戏雏形

本文发布于:2024-03-10 01:07:46,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1726631.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:雏形   人称   游戏   Unity

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!