在Unity中创建一个基本的2D平台游戏

8
我对Unity知之甚少,想要创建一个非常简单的平台2D游戏,只使用基本形状(正方形、矩形、圆形等)。我在网上搜索到了一些教程,但它们都比我需要的更复杂。例如,我看到了this,但它的目标比我的更为雄心勃勃(我还看过其他教程,但无法添加链接)。我希望能够创建一些非常简单的东西来理解程序的基础知识,然后尝试自己制作更复杂的东西。有人有什么建议吗?这是我想象中的第一关,非常简单(而且很丑):
first level我不知道从哪里开始,我认为从复杂的东西开始没有意义,因为我什么也不懂,只会复制。最好从简单的东西开始,随着实践的深入逐渐增加难度,我是对的吗?

我补充一下,我懂Java和一点JavaScript。


我按照Fredrik的教程操作后得到了这个结果。 阅读代码,我看到了这段内容:

if(col.tag == "Coin") {
    coins++;
    Destroy(col.gameObject); // remove the coin
}

当玩家与硬币碰撞时,硬币不应该被摧毁吗?但在我的情况下并非如此。

1
我对同样的事情很感兴趣,但我看到有人建议先学习Java或C/C++来制作Flash游戏。我想看看人们会怎么回答。 - jhhoff02
1
从简单的开始是很好的。我认为你在http://gamedev.stackexchange.com/上寻找答案会更有好运。 - Catwood
这是一个非常广泛的问题,需要一个相当深入的答案。正如上面的评论所述,它可能更适合在另一个论坛上讨论,但我会写一些东西来帮助你入门!请稍等。 - Fredrik Schön
1
@Fredrik 谢谢您的时间,我会急切地等待! - user7558372
关于你的更新。使用Debug.Log("message" + variable);来记录到控制台。将One放置在OnTriggerEnter2D方法中。我从未测试过,所以可能无法正常工作,呵呵。 - Fredrik Schön
1个回答

19

虽然这不是专门讨论这个问题的论坛,但我想回答一下。希望我的回答对你有所帮助,即使被标记也无妨。

对于简单的2D平台游戏,你需要:

一个玩家

  • 具有物理属性(刚体组件)
  • 和碰撞检测(Box碰撞器组件)
  • 向左/向右移动和跳跃的代码控制
  • 能够检测触发器(如道具/陷阱/关卡结尾)的代码

地面对象

  • 具有碰撞器(以便玩家可以行走)(Box碰撞器组件)

收集品

  • 具有触发器碰撞器(以便玩家可以穿过并检测它们)(Box碰撞器组件)

通过Unity启动器创建一个新的2D项目。 点击2D按钮

  • 首先,让我们创建我们的GameObjects。 GameObjects是游戏中的每个对象,并通过右键单击层次结构(默认情况下为主摄像机所在位置)并单击“创建空对象”来创建。但由于这是一个2D游戏,我们希望每个对象都是Sprite(图像)。因此,我们不会使用“创建空对象”,而是使用“2D对象 -> Sprite”。这将成为我们的玩家。现在玩家看起来什么也没有,因为没有图片来代表它。通过将所选图片拖动到Unity资源文件夹中的某个位置,然后将该导入的图像拖动到sprite的sprite字段中来更改此设置。就像这样: http://i.imgur.com/6cKQCss.gifv

  • 添加组件(如此添加:http://i.imgur.com/UkkxbgK.pngBox碰撞器Rigidbody2d和一个新的C#脚本,例如...“Player”。继续使用现有的“Player”标签对我们的玩家游戏对象进行标记,并在Rigidbody组件约束下,勾选“冻结旋转:Z”如下图:http://i.imgur.com/be6G2pB.png

你的玩家应该现在看起来像这样http://i.imgur.com/be6G2pB.png(+Player脚本)

  • 这里是玩家脚本。可能会有一些错误(例如,即使不在地面上,玩家也可以无限跳跃),如果有,请尝试修复它们,或者改进它们,如果效果不够好。它需要玩家拥有一个Rigidbody2D-和Collider2D-组件(碰撞器组件可以是盒形碰撞器、圆形碰撞器等等任意形状),我们在上一步中添加了它们。 Rigidbody2d 给玩家物理引擎(受重力影响下落,受力影响运动),而 collider 给它与其他物体碰撞的能力。如果没有这个,玩家将会穿过地面,并且无法检测到是否触发了其他触发器/碰撞器。

这是一段C#脚本,我建议您使用。它非常类似于Java,很容易上手。大部分内容都是特定于Unity的:

using UnityEngine;

public class Test : MonoBehaviour {

    float speed = 3f;
    Rigidbody2D rb;
    int coins = 0;
    Vector3 startingPosition; // If we hit a spike we will teleport player to starting position.

    void Start()
    {
        rb = GetComponent<Rigidbody2D>(); // Get the rigidbody component added to the object and store it in rb
        startingPosition = transform.position;
    }

    void Update()
    {
        var input = Input.GetAxis("Horizontal"); // This will give us left and right movement (from -1 to 1). 
        var movement = input * speed;

        rb.velocity = new Vector3(movement, rb.velocity.y, 0);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(new Vector3(0, 100, 0)); // Adds 100 force straight up, might need tweaking on that number
        }
    }


    void OnTriggerEnter2D(Collider2D col) // col is the trigger object we collided with
    { 
        if (col.tag == "Coin")
        {
            coins++;
            Destroy(col.gameObject); // remove the coin
        }
        else if (col.tag == "Water")
        {
            // Death? Reload Scene? Teleport to start:
            transform.position = startingPosition;
        }
        else if (col.tag == "Spike")
        {
            // Death? Reload Scene? Teleport to start:
            transform.position = startingPosition;
        }
        else if (col.tag == "End")
        {
            // Load next level? Heres how you get this level's scene number, add 1 to it and load that scene:
            // SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
        }
    }
}

接下来,让我们创建等级对象。
  • 在Hierarchy中右键单击,点击“Create Empty”创建一个空对象。这将充当所有等级对象的文件夹,以使其整洁有序。右键单击这个新创建的空游戏对象,点击“2D Object->Sprite”,并将其命名为“Floor”(或其他名称)。如果您想要看到它,请像我们与玩家一样给它一个sprite! (gif链接: http://i.imgur.com/6cKQCss.gifv) 给这个方块添加一个"Box Collider 2D"组件。现在玩家可以站在这些对象上了。您现在可以运行游戏,并且应该能够拥有一个(有点)可用的玩家和供玩家站立的对象。更改其Transform组件中的值以更改其大小属性。如果需要更多对象,则可以复制并粘贴此对象(您将需要这样做)。还有一个叫做“Prefab”的东西。它就像保存GameObject一样,因此您可以多次使用它,并具有许多您稍后将意识到的其他好处。要将GameObject保存为Prefab,只需将对象从Game Hierarchy拖动到项目资源文件夹中的某个位置即可(与sprite类似,有点)。

  • 对于Coins,做同样的操作,但给它一个新的标签(如何创建新标签:http://i.imgur.com/dYt9b0T.gifv),称为“Coin”,并在Box Collider 2D组件中勾选“Is Trigger”按钮。这将使它在我们走进去时触发OnTriggerEnter2D,并且玩家无法站在上面;我们会直接穿过它(因为它只是一个触发器)。我们将使用标签名称来识别它在玩家的OnTriggerEnter2D方法中是什么类型的对象。

对于大多数其他您想要的对象,请重复上述硬币步骤。我们使用标签名称来识别它们,并处理我们想要的动作。

void OnTriggerEnter2D(Collider2D col)
{
    if (col.tag == "Coin")
    {
        coins++;
        Destroy(col.gameObject); 
    }
    else if (col.tag == "Water")
    {
        transform.position = startingPosition;
    }
    else if (col.tag == "Spike")
    {
        // Death? Reload Scene? Teleport to start:
        transform.position = startingPosition;
    }
    else if (col.tag == "End")
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    }

    /*
    *
    * Keep adding objects to collide with here!
    *
    */
}

这是一个基本的例子,展示了如何完成你所要求的内容。更加深入的了解需要知道的事情... 重要的进一步信息将会是...
每个物体都有一个“Transform”对象,其中包含物体的位置、旋转和缩放属性。通过修改它们(在脚本中:transform.position、transform.rotation、transform.localScale)来修改这些属性。
要在代码中获取组件,你需要使用GetComponent();其中“Component”是你想要的组件名称,就像我们在Player脚本中使用了 rb = GetComponent<Rigidbody>();
现在请按照此示例进行操作,进行扩展,如果您需要帮助,请搜索“Unity 如何...”,或者在这里询问,如果您无法使其正常工作。
祝您在 Unity 中玩得愉快! 如果对我的回答有问题,请继续提问。

1
不错的回答。我认为如果他遵循Unity的2D项目教程之一,Op会没问题。@jhhoff02 你可以在3天左右之后放置赏金,但今天不行。 - Programmer
哈哈,你的赞赏就是我所需要的!虽然最后不得不匆忙写完,但我很享受写作的过程。干杯! - Fredrik Schön
1
非常感谢您的帮助,非常棒的教程!我完成了教程,但我有一个小问题(我编辑了问题),您能帮我吗? - user7558372

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接