unity 让角色移动的方法_让不懂编程的人爱上Unity3d游戏开发030-让玩家控制游戏角色...

在前两课的内容中,我们学习了如何通过代码访问游戏对象及其组件,以及修改相关的属性。

af164766a4f595906089040978425877.png

在这一课的内容中,我们要基于之前的内容,学习如何让玩家操控游戏角色。

还等什么呢?让我们开始吧~

06 Unity和C#的双剑合璧-让玩家控制游戏角色

在游戏当中,作为“上帝”的玩家当然希望可以随心所欲的控制游戏角色了。那么,应该如何控制呢?最理想的状态当然是通过脑机接口~不要,再过三五十年,人类未来的游戏交互方式可能就是《黑客帝国》里面那样,直接让大脑和电脑连接在一起了。

不过在当前这个时间点,我们熟悉的玩家交互方式仍然是键盘、鼠标、触摸屏为主。当然,对于游戏主机和掌机还有游戏手柄,对于AR/VR游戏还有动作捕捉和面部识别、表情捕捉、眼部追踪等等~

在这一课的内容中,我们先来了解最简单的交互方式,也就是PC游戏中最常用的是用键盘和鼠标进行交互。在后续的内容中,我们还将学习如何基于智能移动设备的触摸屏进行交互,以及如何基于AR/VR/MR的语音识别、动作识别、面部识别等进行交互~

心动不如行动,让我们开始动手吧~

打开Unity Hub,找到并打开FairyLand项目。

对于PC平台的游戏,其实设置玩家的输入非常简单直接。

在Unity编辑器中点击工具栏上的Edit- Project Settings,然后从左侧切换到Input选项,就可以看到系统默认的输入设置了。

9b4dc8c1ada6b80836b370ce97579b62.png

如果你的初中英语还过得去,那么看懂这里的设置选项完全不是问题。

首先Size代表所有可以用的输入设置,默认值是18,也就是下面的18个设置选项。

接下来的Horizontal代表水平方面的操控,点击下三角符号可以展开。

0f4fd64b1a5fe6166a8fbb74965adae4.png

在下面的这些属性中,挑几个重要的简单解释一下。

Name,这里设置的是Horizontal,也就是说在代码中我们将使用这个字符串来指代水平方向的输入。

Negative Button和Positive Button代表的是负向和正向的移动,分别设置成了left(键盘的向左方向键)和right(键盘的向右方向键)。

简单来说,按下键盘上向左的方向键,就会让所关联的游戏对象产生向左的移动(x坐标的负向减少),反之就是向右的移动。

Alt Negative Button和Alt Positive Button和刚才的设置类似,只不过使用了键盘上的a字母键和d字母键。也就是说,按下键盘上的这两个键,就等同于按下键盘的向左方向键和向右方向键。

下面的Type设置成了Key or Mouse Button,也就是说这个设置是针对键盘或鼠标按键的。

关于其它属性的含义,这里就不展开讲了,感兴趣的童鞋可以查看官方文档:

对于其它17种输入设置,跟Horizontal类似,这里就不详细讲了。

对当前这个项目来说,最主要的就是Horizontal和Vertical的输入了。

好了,现在我们已经明确了键盘上的输入映射,接下来就需要用代码来实际获取玩家的输入,并驱动游戏角色做我们希望它做的事情了~

获取玩家的输入

在Project视图中找到_Script目录下的PlayerScript,双击在Visual Studio中将其打开。

在之前的内容中,我们提到过Unity所提供的事件函数。

目前基本上所有的代码都放到了Start()这个事件函数中,这是因为我们只需要在游戏开始的时候执行一次代码就好了。

但是处理玩家的交互就不同了,我们不知道玩家会在什么时候按下键盘上的某个键。因此,只是在Start()中调用相关代码肯定是不够的,我们必须在游戏的每一帧监控玩家的输入状况。而对于在游戏的每一帧都要执行的代码,通常我们会在Update()、FixedUpdate()和LateUpdate()等事件函数中。

因为玩家的输入不涉及到对物理机制的模拟,所以在Update()中添加对应的代码就Ok了~

在PlayerScript脚本文件中,更改Update()的代码如下:

void Update()

{

//7.获取通过玩家输入产生的虚拟位移

float moveHorizontal = Input.GetAxis("Horizontal");

float moveVertical = Input.GetAxis("Vertical");

//8.测试所获取的结果

Debug.Log(moveHorizontal);

Debug.Log(moveVertical);

}

这里简单解释一下:

当我们希望获取通过玩家输入让游戏角色产生的水平和垂直位移时,需要用到Input.GetAxis方法,而这正是Unity内置的重要方法.

问题来了:

作为新手小白,我怎么知道该用什么方法?

首先,因为这个操作涉及到玩家的输入,所以我们会需要用到系统的Input类,所以在官方文档里面找到Input类。

然后,我们需要获取通过玩家输入所产生的位移,在其方法中逐一找,会发现GetAxis是不二之选。当然,对于有经验的老手来说,这些就纯粹靠经验了。

最后,找到对应的方法,官方文档里面还会有详细的示例代码。即便你看不太懂,也可以先拿过来照着用~

好了,保存代码修改,回到Unity编辑器,点击预览播放按钮,看看Console视图中有什么新东西出现~

50a3b3ffd7fd2de702303efd9a02aba2.png

可以看到,当我们按下键盘上的上下左右方向键,或者awsd键时,在Console视图中会输出-1到1之间的数值。

显然,Unity已经成功捕捉到了玩家的交互输入。

让游戏角色走两步

仅仅获取玩家的输入还远远不够,因为我们真正想要的是让游戏角色可以在玩家的操控之下走两步~

那么,应该怎么办呢?

对于新手来说,可以模仿一下刚刚打开的官方文档:

这里提供了两个示例代码,在第一段示例代码中:

public class ExampleClass : MonoBehaviour

{

public float speed = 10.0f;

public float rotationSpeed = 100.0f;

void Update()

{

// Get the horizontal and vertical axis.

// By default they are mapped to the arrow keys.

// The value is in the range -1 to 1

float translation = Input.GetAxis("Vertical") * speed;

float rotation = Input.GetAxis("Horizontal") * rotationSpeed;

// Make it move 10 meters per second instead of 10 meters per frame...

translation *= Time.deltaTime;

rotation *= Time.deltaTime;

// Move translation along the object's z-axis

transform.Translate(0, 0, translation);

// Rotate around our y-axis

transform.Rotate(0, rotation, 0);

}

}

当我们获取了玩家在Horizontal和Vertical方向的输入后,将所获取的结果乘上运动 的速度,然后又乘上Time.deltaTime,最后,使用Translate方法让角色进行位移,使用Rotate方法让角色进行旋转。

回到Visual Studio之中,继续修改PlayerScript中的代码。

首先,在Start()方法之前添加一个新的变量定义:

//9.创建变量用来保存游戏角色的运动速度

public float moveSpeed = 5.0f;

这一行代码没什么好解释的,就是定义了一个float类型的变量,保存角色的运动速度。因为是public类型的,我们可以在其它类,或者Inspector视图中进行访问和修改。

然后更改Update()方法中的代码:

void Update()

{

//7.获取玩家通过键盘产生的水平和垂直位移

float moveHorizontal = Input.GetAxis("Horizontal");

float moveVertical = Input.GetAxis("Vertical");

8.测试所获取的结果

//Debug.Log(moveHorizontal);

//Debug.Log(moveVertical);

//10.让游戏角色走两步~

transform.Translate(moveHorizontal * moveSpeed * Time.deltaTime, 0, moveVertical * moveSpeed * Time.deltaTime);

}

这里我们只添加了注释行编号为10下面的这段代码。

看起来有点复杂,其实也很简单。

首先,因为要移动游戏角色,所以我们使用了transform.Translate犯法。

当然,这里其实我们也偷懒了,严谨的写法应该是:

gameObject.transform.Translate(moveHorizontal * moveSpeed * Time.deltaTime, 0, moveVertical * moveSpeed * Time.deltaTime);

只不过因为我们要移动的游戏角色就是当前这个游戏对象,所以就把最前面的gameObject省略了~

而Translate方法则是Transform类的重要方法,它的作用就是让游戏角色产生位移。

假定我们不知道怎么用这个方法,那么当然还是参考官方文档了~

可以看到,这个方法的定义是:

public void Translate(Vector3 translation);

public void Translate(Vector3 translation, Space relativeTo = Space.Self);

也就是说需要给它传递一个Vector3类型的变量。在之前的内容中我们提到过,Vector3是一个结构体,它通常用来保存游戏对象在空间中的坐标或坐标位移,分别是x轴,y轴和z轴。

所以,如果严谨起见,其实我们应该这样写刚才的代码:

Vector3 translation = new Vector3(moveHorizontal * moveSpeed * Time.deltaTime, 0, moveVertical * moveSpeed * Time.deltaTime);

transform.Translate(translation);

问题又来了?为什么角色的位移不直接用moveHorizontal和moveVertical的变量值?

刚才提到过,其实使用Input.GetAxis()方法所获取的位移数值在-1到1之间,是一个相对值。所以,如果我们希望使用这个值乘以角色的移动速度,才会有一个合理的结果。

那么Time.deltaTime又是啥东西?

这个也不难理解。因为我们是在Update()方法中执行这行代码。如果不乘以Time.deltatime,那么就意味着每一帧都要产生这么多的位移,这个就有点夸张了。

当我们乘以Time.deltaTime之后,就代表每一秒产生这么多的位移。

如果大家希望了解Time.deltaTime的更详细用法,可以参考官方文档。

当然,我们还有个非常直观的方式来认识Time.deltaTime,那就是添加一行代码~

print(Time.deltaTime);

实际执行后,根据电脑的配置不同,会看到不同的结果,在我的电脑上Time.deltaTime的数值大概是0.017~

具体的数值是多少并不重要,重要的是,通过在Update()方法中乘以Time.deltaTime,就可以确保位移是以每秒为单位,而不再是以每帧为单位。

好了,保存代码,回到Unity编辑器,点击工具栏上的预览播放按钮,就可以使用键盘上的上下左右方向键和awsd键来控制游戏角色的移动了~

是不是有点小小的成就感了。

不过且慢,当前的游戏视角看起来似乎有点问题,因为游戏角色在场景中的位置并不是很合理。

这里有个小小的技巧。

让我们回到Unity 编辑器,在Scene视图中手动将游戏角色调整到自己满意的位置,然后在hierar视图中选中Main Camera,按下快捷键Shift+Ctrl+F(Mac下Shift+Command+F)。

再次點擊預覽按鈕,就可以看到角色的視角看起來比較舒服了~

當然,還有一個小小的問題,現在玩家的活動空間似乎有點太小,而運動速度似乎有點太快了。

我們可以在Inspector視圖中調整 Move Speed的值,到自己滿意的程度~

至於活動空間,可以在Hierarchy視圖中選中Floor,在Inspector視圖中將Transform組建的Scale屬性設置為(10,1,10).

好了,再次預覽遊戲效果,我們的小仙女終於可以愉快的在虛擬世界中飛來飛去了~

好了,这一课的内容到此结束。

让我们下一课再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值