Unity入门:第一个游戏

Unity官网提供了详尽的文档和丰富的教学视频,昨天跟着视频做了一个简单的3d游戏“roll-a-ball”。游戏涉及了许多Unity的基本知识,用来入门很不错。

这篇博文并不讲述整个游戏的制作流程,如果您感兴趣,可以访问这里,如果访问遇到什么困难,在B站有一摸一样的视频

这是完成以后的样子:


运行效果:


作为个人小结,下面写一些做这个游戏的收获:

1、什么是Unity?

一款游戏引擎,至于什么是游戏引擎,这里不展开。

2、下载和安装

官网:Unity官网

作为学习用途,下载personal版即可。

3、熟悉Unity界面

进入Unity后,将会看到这样的界面:


上图将界面划分成了5部分,下面分别解释每部分的功能:

(1)Toolbar

上面的按钮有不同的功能,比如左侧的第一个按钮可以用来移动场景中的物体,第二个按钮用来进行平移变换,第三个按钮用来进行旋转变换等。

(2)Hierarchy window

顾名思义,这个部分显示的是“层次结构”,场景中的对象都会被列到这个窗口中。当我们新建一个Unity项目时,Unity就会自动为我们添加两个东西:Main Camera和Directional Light,一个是相机,一个是光照。Hierarchy window上面有一个create按钮,点击这个按钮,我们可以看到一个包含了空对象、2d,3d对象、UI、光照、相机等在内的菜单,在这里你可以点击你想创建的东西。

(3)Scene view

这是游戏的场景,我们可以通过调整右上角的坐标系图案来调整观察场景的位置。

(4)Inspector window

当我们选中一个对象,打开Inspector window,这个对象的信息,例如所在的位置,平移了多少等等都会在这个窗口显示,当然也可以用这个窗口来调整场景中的对象,例如为了编辑方便,一开始我们会使用transform中的reset,将对象放置在坐标原点(0,0,0)。Inspector window最下面有一个Add Component按钮,通过这个按钮可以给对象增加其它的component,例如添加一条C#脚本等。

(5)Project window

这个窗口显示的是这个游戏使用的资源,通常我们会在这里建立一些文件夹,例如Scenes文件夹专门保存场景,Materials文件夹专门保存材质,Scripts文件夹专门保存脚本等。Project window上有一个不起眼的create按钮,这个按钮很有用,例如我们可以点击create->folder来新建一个文件夹等等。

事实上,这只是Unity界面一个最基本的布局,你可以自己拖动这些window或者view来将它们放置在自己喜欢的位置,也就是说,操作界面是可以个性化的。其实上面漏掉了一个很重要的view:game view,如下图所示:


这个view的按钮就在scene view旁边,上图中我已经将它拖动到了scene view下面,这个视图显示的是我们的游戏最终呈现给用户的样子,制作好一个游戏后,可以点击Toolbar中间那个表示Play的按钮进行试玩,游戏的运行情况就显示在这个视图中。

为了方便编辑,我们常把Scene view和Game view并列在一起,就像上图一样,这样,在用Play试玩调试的时候可以不用频繁切换视图,从而节省了时间。

4、怎么理解游戏中的几个脚本?

Unity会自动为每个新建的C#脚本生成void Start()和void Update()两个方法,第一个在第一帧,也就是游戏刚开始时调用,第二个在画面更新时调用(准确地说是在渲染每一帧之前被调用)。

在这个游戏中我们会用到三个脚本:

(1)CameraController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour {
	public GameObject player;
	private Vector3 offset;

	void Start () {
		offset = transform.position - player.transform.position;
	}
	
	void LateUpdate () {
		transform.position = player.transform.position + offset;
	}
}
脚本的作用是当Player移动时,让相机也随着移动。

这里有一个问题:要达到类似的效果,为什么不直接把Main Camera设置成Player的孩子?

(2)PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour {
	public float speed;
	public Text countText;
	public Text winText;

	private Rigidbody rb;
	private int count;


	void Start()
	{
		rb = GetComponent<Rigidbody>();
		count = 0;
		SetCountText();
		winText.text = "";
	}

	void FixedUpdate()
	{
		float moveHorizontal = Input.GetAxis("Horizontal");
		float moveVertical = Input.GetAxis("Vertical");
		Vector3 movement=new Vector3(moveHorizontal,0.0f,moveVertical);
		rb.AddForce (movement*speed);
	}

	void OnTriggerEnter(Collider other)
	{
		if (other.gameObject.CompareTag ("PickUp")) 
		{
			other.gameObject.SetActive (false);
			count++;
			SetCountText();
		}	
	}

	void SetCountText()
	{
		countText.text = "Count:" + count.ToString ();
		if(count>=12)
		{
			winText.text="You Win!";
		}
	}
}

这个脚本被添加到了叫做Player的小球上,Start函数用来做初始化,其中的getComponent用来获取刚体对象,也就是添加到叫做Player的小球上的那个RigidBody。为什么用FixedUpdate()不用Update()?因为FixedUpdate在做物理计算之前被调用,这个游戏中的碰撞属于physics的范畴,所以用FixedUpdate()。还有一个要注意的函数是OnTriggerEnter(),这个函数在对象碰到collider的时候会被触发,在这个例子中,我们给12个Pickup关联上了一个叫“PickUp”的Tag,当碰撞发生时如果发现Tag是PickUp,就deactivate这个PickUp(每个PickUp的is trigger需要勾选上)。教学视频中提到一个问题:除了要给PickUp的collider勾选is trigger,还要加上rigidbody(is kinematic),这是因为Unity计算所有collider的体积后把它们放在一个cache里,如果collier是静态的(static),这样做可以避免在每帧更新的时候重复计算,但是在我们这个游戏中,因为每次collider都在旋转,所以每次它的体积都会被重复计算,为了节省资源,可以把collider设置成动态的(dynamic=collider+rigidbody)。

(3)Rotater.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotator : MonoBehaviour {

	
	// Update is called once per frame
	void Update () {
		transform.Rotate (new Vector3(15,30,45)*Time.deltaTime);
	}
}
这里要用的是Update而不是FixedUpdate(和物理无关)。

5、其他

(1)prefab

类似模板一样,可以将需要复用某个逻辑的一堆对象放到prefab文件夹中,这就可以对整体进行编辑、修改了。

(2)快捷键

例如ctrl+D用来duplicate

(3)有不懂的查文档!!!

阅读更多
换一批

没有更多推荐了,返回首页