(除特殊说明,以下为原文翻译版)
上次,安装上了Unity3d,并且做了一个很简单的场景,之后简单的运行了一下。现在,是时候开始做一些有挑战性的事情了。这次,我们将会试着创造一个能互动的东西了。首先,我们会创造一个摄像机,玩家可以控制它在整个场景中游荡。这将会上我们开始编写程序,我们会像一开始说的,使用C#.
玩家:
在一个即时战略游戏中,创建一个能游览整个地图的摄像机是非常重要的事情。说到玩家,这远远不只是一个简单的摄像机。对于一个即时战略游戏,所有的建筑,单位都将与玩家进行互动。游戏中还会有多个电脑控制的玩家参与游戏。不过,首先我们先看看人类控制的游戏参与者。
因此,在我们做任何事情之前,我们必须创建处理“玩家”的操作,这样我们才能让游戏与玩家进行互动。让我们来创建一个空的游戏对象(Game Object,GameObject->Create Empty),并将它改名为“Player”。
现在,我们需要创建一个脚本,来定义玩家可以做什么,不可以做什么。我创建两个脚本来做这个,一个是玩家(Player),另一个用来获取游戏者的输入动作。首先,让所有东西随着项目的发展来慢慢增加(这句可能我理解的不是很对,原句为:To keep things organized as the project grows)。在项目资源(项目文件夹->Asset)目录里,创建一个文件夹,重命名为“Player”。把所有有关玩家的资源都放在这个文件夹中。之后,我们来创建两个脚本,叫它们“Player”和“UserInput”。(脚本名字中文翻译分别为“玩家”和“用户输入”)
把这两个脚本拖到我们刚刚创建的空游戏对象“Player”上。 干得好! 现在我们来创建一个用来与玩家互动的框架。
Player脚本细节:
现在,我们来针对每个玩家来定义一些东西。首先,需要一个名字来辨认每个玩家,还有,我们还需要知道,这个玩家是否是由一个人类控制(或许是电脑玩家)的。打开Player.cs代码。加上这两行代码:
public string userName;
public bool human;
当你完成添加后,Player.cs脚本看上去应该像这样:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public string userName;
public bool human;
//Use this for initialisation
void Start (){
}
// Update is called once per frame
void Update (){
}
}
我们现在暂时不在Start()和Update()中写任何代码。现在回到Unity3d ,你可以看见在Inspector中,已经出现了我们刚才定义的两个变量,玩家的名字和它是否为人类控制的布尔变量。你看见的将会像图中这样。
Player.cs和UserInput.cs
资源管理器:
在我们开始创建控制摄像机的脚本之前,还有一件事请要做。我们做很多事情将会用到某些一定的数值,例如拖动的速度,距离地面的高度,每个按钮的宽度等等。我们应该创建一个新的类,用来统一管理这些,我就是我们要创建的Resource Manager(资源管理器)。
现在,我们需要创建一个我们自己的命名空间(Name Spaced)。我希望引用这些数值是这样写:
using RTS;
创建一个新的脚本,叫它ResourceManager,然后打开并编辑它。要引用这些变量,需要将它放入一个静态类中,我们将创建一个静态类来保存这些数值,因为这只是用来保存数值,所以我们不需要继承MonoBehaviour最后,需要把这些都放在我们的RTS命名空间中。你的代码看上去应该是这样:
using UnityEngine;
using System.Collections;
namespace RTS {
public static class ResourceManager {
}
}
注意这里我依然使用了UnityEngine,因为只里面包含了Unity提供给我们的所有东西。
摄像机输入:
是时候做点有趣的事了——处理用户对摄像机的输入。我们又要接触摄像机了。
现在,打开UserInput.cs 我们来继续编辑它。
第一件事,我们要引用刚刚创建的ResourceManager。
using RTS;
UserInput类的顶部,加上这个:
private Player player;
这是个private的变量,它只能在定义它的类中被访问。那么,为什么我要这样做?因为这个变量并不需要在其他地方被访问或修改。我们需要在游戏开始运行时,初始化这个变量(给它负值),并且将不会再修改。
通过这行代码来初始化:
player = transform.root.GetComponent<Player>();
我会把这个语句加在Start()中,因为Unity会在一开始调用Start(),而我们需要在游戏开始运行时(或者说,在带有UserInput.cs的游戏对象被创建时),执行这一句。
这句将会在带有UserInput.cs的游戏对象的父物体中(transform.root),获得Player组件(就是我们之前创建的Player.cs)。
做完这些,在UserInput.cs中,就可以访问Player了。下面,我们来在Update()中添加这两句(这里就需要访问Player的变量了):
if(player.human) {
MoveCamera();
RotateCamera();
}
看下这个if语句,这意味着Update()将不会对电脑玩家做任何事。注意我们应尽量在Update()中执行较少的语句,因为Update()是每一帧执行一次的,如果Update()中很复杂,那将会降低游戏运行的帧数,会让整个游戏变得非常不流畅。
如果现在编译的话,会出错,因为我们调用了两个并不存在的方法(函数),MoveCamera()和RotateCamera().
MoveCamera()来让摄像机移动,RotateCamera()负责旋转摄像机。现在来创建这两个方法,并暂时让它们是空的,像这样:
private void MoveCamera() {
}
private void RotateCamera() {
}
在写这两个方法之前,我们先在ResourceManager中添加几个合理的数值。并且,在控制摄像机的时候来引用它。像这样:
public static float ScrollSpeed { get { return 25; } }
public static float RotateSpeed { get { return
100; } }
摄像机移动:
现在,来让我们的摄像机可以围绕着整个地图移动!
首先我们应该判断鼠标什么时候在屏幕的边缘。首先定义一个数值来表示在屏幕边缘的范围有多少像素。在ResourceManager中添加这一句:
public static int ScrollWidth { get { return 15; } }
这可以让我们方便的修改可滚动范围距屏幕边缘有多少像素的宽度。但这不需要每次修改,因为我们只需要将它设置出一个合适的值。
我们首先要加在MoveCamera()方法中的是两个变量,来保存鼠标的坐标,像这样:
float xpos = Input.mousePosition.x;
float ypos = Input.mousePosition.y;
Vector3 movement = new Vector3(0,0,0);
摄像机的Y轴代表高度,那么我们需要在X和Z轴来控制移动。因此,X轴是水平移动,Y轴是垂直移动。这样来判断:
if(xpos >= 0 && xpos < ResourceManager.ScrollWidth) {
movement.x -= ResourceManager.ScrollSpeed;
}
else if(xpos <= Screen.width && xpos > Screen.width - ResourceManager.ScrollWidth) {
movement.x += ResourceManager.ScrollSpeed;
}
//vertical camera movement
if(ypos >= 0 && ypos < ResourceManager.ScrollWidth) {
movement.z -= ResourceManager.ScrollSpeed;
} else if(ypos <= Screen.height && ypos > Screen.height - ResourceManager.ScrollWidth) {
movement.z += ResourceManager.ScrollSpeed;
}
这样来适当的按照希望移动的方向来改变movement变量。
movement还需要一个方法来使摄像机的高度不偏离(Y轴)。Unity3d有一个方法来实现这个:
//make sure movement is in the direction the camera is pointing
//but ignore the vertical tilt of the camera to get sensible scrolling
movement = Camera.main.transform.TransformDirection(movement);
movement.y = 0;
最近实在没时间翻译,感谢您的等待。很快将会更新,
给您带来的不便,尽情谅解
最后一次编辑:Fri 27 Oct 2013
By Spinach HaoYan QI