Creating RTS Game With Unity3d(Chinese Edition) Part II 使用Unity3d制作即时战略游戏

(除特殊说明,以下为原文翻译版)


        上次,安装上了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.cs的最上面。接下来,我们需要引用我们要控制的Player(类)。在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变量。


      还有件事值得一提,我们的摄像机是在3D世界中,所以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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值