当我们谈论Unity中的JavaScript时,我们实际上是在谈论UnityScript,这是一种类型化的JS方言。 Unity本身 经常引用这种JavaScript ,但是更多的愤世嫉俗的观察者认为“ Unity会使用JavaScript”是一种 营销策略 。 无论哪种方式,我们都应该清楚UnityScript不符合任何ECMAScript规范的事实,也不会这样做。 您可以 在此处找到 有关差异的 很好概述 。
要开始本教程,我们需要有一个正在运行的Unity版本,可以在 此处下载 。 Unity拥有适用于Windows和Mac OS X的安装程序。Linux用户可能 可以通过Wine来 运行Unity ,但是您的工作量可能会有所不同。
安装完成后,我们一切顺利! 因此,让我们打开Unity并创建一个新的3D项目。
Unity首次打开后,我们应该花一点时间在主窗口中找到方法:
现在我们熟悉Unity的界面,在开始开发之前,还有一件事情要做:保存当前场景。 “文件”>“保存场景”将打开一个“ 保存场景”对话框,该对话框会指向名为Assets
的文件夹。 在Unity中组织文件的一种常用方法是使用子文件夹。 因此,将一个新文件夹添加到名为Scenes
的Assets
文件夹中,并将场景以Level.unity
的名称保存在此文件夹中。
我们的游戏将包括一个英雄,一个平台一个平台跳得更高。 如果它错过了一个并被遗忘了,那么游戏将会失败。 因此,让我们从创建英雄开始。 因为玩家可以从第一人称视角观看游戏,所以英雄的外表并不重要,我们可以使用标准的球体几何形状。 球体的好处在于它可以通过几个步骤创建,并且适合我们跳跃所需的物理原理。 通过单击“ 层次结构”中的“ 创建”来添加球体,并使用检查器编辑以下属性:
登录后复制
Position { X: 0, Y: 2.5, Z: 0 }
Scale { X: 0.3, Y: 0.3, Z: 0.3 }
让我们按一下播放按钮来测试我们所做的事情。 我们应该在天际线前面的3D空间中看到一个球体。
为了使英雄跌倒,必须增加体重。 因此,我们需要通过单击“ 检查器”中的相应按钮并选择“ 刚体”将组件添加到球体中。 并且由于我们不希望英雄旋转,因此我们通过打开“ 约束”并选择“ 旋转”行中的所有轴将其冻结在“ Rigidbody
组件中。 再次播放场景时,我们应该能够看到英雄掉落。
为了使英雄免于无休止的跌倒,我们将创建一个用作平台的扁平盒子。 为此,我们必须添加一个多维数据集并将Scale.Y
值设置为0.1
。 重播场景可以确认英雄可以安全地降落在平台上,尽管我必须承认这看起来并不自然。 那么我们如何让英雄弹跳呢? 通过添加一些物理材料。
首先,我们需要为该球体创建新的物理材料以使其具有弹性。 为此,在Assets
文件夹中创建一个名为Materials
的新文件夹,然后在此处创建一个新的物理材料。 我们称其为Bouncy_Sphere
。 我们需要在检查器中调整的值为:
登录后复制
Dynamic Friction: 10
Static Friction: 10
Bounciness: 1
Friction Combine: Maximum
Bounce Combine: Maximum
如果我们将此材料添加到“ 球体对撞器”中 ,这将使球体上下反弹,但始终达到相等的高度。 为了使球体每次跳动都跳得越来越高,我们也必须在平台上添加一些物理材料。 为此,我们创建了另一个名为Bouncy_Platform
,并将其值更改为:
登录后复制
Dynamic Friction: 0.9
Static Friction: 0.9
Bounciness: 1
Friction Combine: Average
Bounce Combine: Multiply
为了达到此处的一致性,我们还应该通过在Hierarchy中两次将多维数据集元素重命名为Platform
。 现在开始游戏时,我们会注意到球体每次跳得越来越高。
我们还将创建一种称为“ Platform
的新标准材料,为Platform
提供一些颜色。 创建此材质后,使用#C8FF00
作为Albedo颜色( Albedo
是Unity UI中的标签),然后将该材质拖放到平台元素上。 现在应该是黄色。
要添加第一人称视角,我们将摄像机(在Hierarchy中 )拖放到球体上。 这将使摄影机成为英雄的子元素,并使摄影机跟随球体移动。 相机属性也必须调整为:
登录后复制
Position { X: 0, Y: 1, Z: 0 }
Rotation { X: 90, Y: 0, Z: 0 }
Scale { X: 2.5, Y: 2.5, Z: 2.5 }
Clear Flags: Solid Color
Background: #000
Field of View: 80.3
我们还将创建一个聚光灯作为球的第二个子对象。 这将使玩家对英雄当前的跳跃高度有所了解。 将Spotlight的值调整为:
登录后复制
Rotation { X:90, Y:0, Z:0 }
我们的目标是使用鼠标或触控板允许玩家向特定方向移动。 为此,我们将编写第一个脚本。 与Rigidbody一样 ,脚本也作为组件添加到游戏元素中。 在本例中,我们将向相机添加一个名为InputController
的JavaScript脚本。 另外,与场景和两种材质一样,我们应该在“ 项目”面板中创建一个名为“ Scripts
的新文件夹。 这应该包含脚本。 通过双击新脚本,Unity将在默认编辑器MonoDevelop中将其打开。 默认编辑器可以更改为任何编辑器( Unity>首选项>外部工具 ),但这并不重要。
如您所见,脚本已经包含一些代码。 首先,我们必须在第1行#pragma strict
(在Unity上下文中强制键入)之后创建一些变量。
登录后复制
#pragma strict
public var Hero : GameObject;
private var halfScreenWidth : float;
private var halfScreenHeight : float;
function Start () {}
function Update () {}
第一个变量是public,类型是 GameObject ; 它必须参考球体。 在仍然选择摄像机的情况下切换回Unity,我们可以在一个带有空值的输入字段旁边看到此公共变量。 让我们将球体拖放到此插槽中,然后为变量分配一个值。
其他两个变量都是私有变量,将在“ 开始”功能中为其分配值。 开始场景后,将调用一次此功能。 这两个私有变量将分别分配当前屏幕宽度和高度的一半,为此,我们使用Unity的内置 Screen类:
登录后复制
function Start () {
halfScreenWidth = Screen.width / 2;
halfScreenHeight = Screen.height / 2;
}
在InputController
脚本中,唯一要做的就是只要移动鼠标就从鼠标中获取值。 为此,我们使用 Update函数,每一帧都会调用一次:
登录后复制
function Update () {
var x : float = 0.0;
var z : float = 0.0;
x = ( Input.mousePosition.x - halfScreenWidth ) / halfScreenWidth;
z = ( Input.mousePosition.y - halfScreenHeight ) / halfScreenHeight;
Hero.GetComponent( HeroController ).SetPosition( x, z );
}
新变量x
和z
代表相应的轴。 当我们向下看y轴时,我们看到一个水平的x轴和一个垂直的z轴。 在这些轴上,我们希望在收到鼠标输入后调整英雄的位置。 为此,我们使用Input.mousePosition
,它返回一个 二维向量 。 零值在左下角的向量必须被处理到我们的坐标系中,其原点位于屏幕中间。 这发生在以下几行中。 最后,我们调用一个函数setHeroPosition
,将两个计算值作为参数。 我们将在连接到球体的名为HeroController
的新脚本中编写此函数:
登录后复制
#pragma strict
public function SetPosition ( x : float, z : float ) {
transform.position.x = x;
transform.position.z = z;
}
让我们通过移动鼠标或触控板并让英雄从平台掉下来测试我们的代码。
为了自动创建平台,我们需要某种平台模板。 这在Unity中称为“预制件”。 要创建预制件,我们必须将平台从Hierarchy中拖放到新的assets
文件夹中(与我们的命名约定一致),称为Prefabs
。 预制件可能会在其层次结构中通过蓝色识别。 所有平台(第一个平台除外)将通过一个称为GameManager
的新脚本创建,该脚本已附加到相机上。 我们通过引用必要的变量来启动此脚本:
登录后复制
#pragma strict
public var Platform : GameObject;
public var Hero : GameObject;
private var boundary : float;
private var rotation: Quaternion;
private var lastPlatformPosition : Vector3;
function Start () {
boundary = 1.0;
rotation = Quaternion.identity;
lastPlatformPosition = new Vector3( 0, 0, 0 );
}
function Update () {}
我们需要引用预制面板和球体,因此必须将它们拖放到编辑器中的特定插槽中。 我们还将创建三个私有变量,这些私有变量将用于实例化预制面板:
Quaternion.identity
值 根本不会旋转 ,这正是我们所需要的。 lastPlatformPosition
将最后一个平台的位置保存为 三维向量 。 现在,对于每一帧,我们将检查球体是否在边界上方。 如果是,我们将提高边界并实例化一个新面板:
登录后复制
function Update () {
if ( Hero.transform.position.y > boundary ) {
var position : Vector3;
boundary += 1.0;
position = getNextPlatformPosition();
Instantiate( Platform, position, rotation );
}
}
接下来,我们可以添加代码以获取下一个面板位置。 我们将其放置在一个额外的函数中,以保持可读性:
登录后复制
private function getNextPlatformPosition () {
var position : Vector3;
do {
position = new Vector3( Random.Range( -1, 2 ), boundary, Random.Range( -1, 2 ) );
} while ( position.x == lastPlatformPosition && position.z == lastPlatformPosition );
lastPlatformPosition = position;
return position;
}
为了确保位置向量的新x
和z
值与先前的值不同,我们使用do while
循环。 Unity的 Random.Range函数是获取x
和z
值的随机值的正确方法。 在这两种情况下,我们都希望它们在-1和2之间。最后,将新位置保存为面板的最后位置,然后将其返回。
在这种状态下,玩家可以通过在相应方向上移动鼠标来在平台上跳得更高。 但是,如果玩家摔倒并错过所有的平台,球体将无限下落。 这就是我们现在要解决的问题。 我们将检查球体是否跌落到第一个平台以下,并在这种情况下加载新场景。
首先,让我们检查英雄是否低于某个特定点。 为此,让我们在GameManager
脚本的update
功能中编辑if
语句。 else if
语句将检查球体的y位置是否低于-2.0单位。 在这种情况下,我们将调用私有函数gameOver
:
登录后复制
function Update () {
if ( Hero.transform.position.y > boundary ) {
var position : Vector3;
boundary += 1.0;
position = getNextPlatformPosition();
Instantiate( Platform, position, rotation );
} else if (Hero.transform.position.y < -2.0) {
gameOver();
}
}
我们将使用一个新函数来处理游戏结束状态,如下所示:
登录后复制
private function gameOver () {
Application.LoadLevel( 'Menu' );
}
在这里,我们使用Unity的 Application类 , 该类使我们能够访问LoadLevel
方法,可用来加载名为Menu
的新场景。 为了使此代码起作用,我们首先必须通过“ 文件”>“新场景”创建场景 ,然后将其保存为名称Menu
。 之后,我们需要将两个场景都添加到构建过程中。 可以通过“ 文件”>“构建设置”打开构建设置 。 菜单场景仍应处于打开状态,因此让我们单击“ 添加当前”按钮,以将场景添加到构建设置中。 在关卡场景打开的情况下重复此操作。 现在,当我们完成游戏时,我们应该进入新创建的游戏菜单场景。
为了使游戏具有可玩性,我们需要创建一个带有播放按钮的游戏菜单。 让我们切换到游戏菜单场景,然后首先将检查器中的相机设置调整为:
登录后复制
Clear Flags: Solid Color
Background: #000
Width: 200
Height: 60
要添加按钮,我们使用Unity的UI元素,可以通过Hierarchy像3D元素一样添加它。 添加UI按钮后,我们应该在“ 层次结构”中看到以下新元素:
画布是所有UI元素的容器,并且可以使其具有响应性。 为此,我们必须将Inspector中的Canvas Scaler:UI Scale Mode设置从“ 恒定像素大小”更改为“ 随屏幕大小缩放” 。 现在我们可以更改按钮的位置:
登录后复制
Rect Transform { Pos X: 0, Pos Y: 0, Pos Z: 0 }
Rect Transform { Width: 200, Height: 60 }
删除按钮的源图像并将颜色设置为#C8FF00
将使菜单更#C8FF00
。 最后,我们通过将Text元素的文本编辑为“ PLAY PREJUMP”并将字体大小设置为16来更改文本。为了使按钮起作用,我们将使用一个新函数,该函数将添加到Button上的新UIController
脚本中。元件。 它包含一个用于加载关卡场景的功能:
登录后复制
public function StartGame () {
Application.LoadLevel( 'Level' );
}
我们可以在按钮的检查器设置中应用此功能。 在“ Button (Script)
组件设置中,只要玩家单击它,我们就可以执行一个功能。 为此,我们通过单击+图标将新功能添加到On Click ()
事件中。 现在我们可以将按钮本身拖放到输入字段上。 然后,选择刚刚从UIController脚本( UIController.StartGame
)中编写的函数。
Unity能够将项目导出为WebGL应用程序。 打开构建设置后,我们选择WebGL作为平台。 然后,我们通过单击“ 切换平台”按钮来切换导出目标。 然后,我们只需要单击Build按钮并为我们的游戏选择一个名称。 构建过程完成后,我们可以使用支持WebGL的桌面浏览器打开html文件。
当然,可以通过例如得分,更多平台类型,其他输入方法,音频等来改进此小游戏。 但是我们在本教程中看到的是,跨平台游戏引擎Unity提供了所见即所得编辑器和脚本编制功能的组合,我们可以将其与JavaScript类似的语言一起使用。 根据我们特定的项目要求,Unity可能是WebGL框架的不错替代品。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删