Unity is a great tool for prototyping everything from games, to interactive visualisations. In this article, we run through all you need to know to get started using Unity.

Unity是一个很好的工具,可用于制作从游戏到交互式可视化等所有内容的原型。 在本文中,我们遍历了开始使用Unity所需的所有知识。

First, a little bit about me: I’m a hobbyist unity developer, 3d modeler and graphic designer who’s worked with Unity and Blender for over 5 years. I’m now a Financial Maths student at University College Dublin, and occasionally I do freelance graphic design, web prototyping, and game prototyping.

首先,关于我的一些知识:我是一个业余爱好者统一开发人员,3d建模者和图形设计师,与Unity和Blender共同工作了5年以上。 我现在是都柏林大学金融金融专业的学生,​​偶尔我从事自由图形设计,网络原型制作和游戏原型制作。

介绍 (Introduction)

This article is aimed at anyone who has never used Unity before, but has some previous experience programming or in web design / development. By the end of this article, you should have a good general overview of the engine as well as all the necessary functions and code to start making a basic game.

本文针对的对象是从未使用过Unity的人,但是具有一定的编程或Web设计/开发经验。 到本文结尾,您应该对引擎以及开始制作基本游戏的所有必要功能和代码有一个良好的总体了解。

为什么选择Unity? (Why Unity?)

如果你想做游戏 (If you want to make games)

There’s really very few options when it comes to Indie Game development. The three main choices if you want to build games are Unreal, Unity or GameMaker.

关于独立游戏开发,实际上只有很少的选择。 如果要构建游戏,三个主要选择是虚幻,Unity或GameMaker。

Unity is probably the least opinionated of the 3 platforms. It gives you a very raw product out of the box, but is highly flexible, well-documented, and highly extensible to build pretty much any genre of game you can think of.

在这3个平台中,Unity的观点最少。 它为您提供了非常原始的产品,但具有高度的灵活性,良好的文档记录和高度可扩展性,可以构建您可以想到的几乎所有类型的游戏。

There are plenty of highly successful games such as Escape from Tarkov (FPS), Monument Valley (Puzzler), and This War of Mine (Strategy / Survival) all built in Unity.


In reality the engine you build your first game on is probably not critical, so my advice is just to pick one and go with it.


如果您想原型化用户体验 (If you want to prototype user experiences)

Since unity is just an engine with a bunch of physics, animation, and real time 3d rendering, it’s also a great space to make fully fledged interactive prototypes for UX studies.


Unity has full support for VR and AR and hence could be a great tool for exploring architecture, automations and simulations with clients.


本文各节 (Sections to this article)

  • Why Unity?


  • Unity Editor Window


  • Unity Game Objects


  • Unity Builtin Components


  • Creating Custom Components


  • Structure of a MonoBehaviour


  • Manipulating GameObjects


  • Raycasting


  • Collision detection


  • Advanced Features


  • Advice For Newcomers


  • Nice Resources and Communities


  • Conclusion


Unity编辑器窗口 (Unity editor window)

The editor window is split up into a couple of sections. We will cover this very briefly as we will refer to it constantly throughout the article. If your familiar with this already just skip past!

编辑器窗口分为几个部分。 我们将在本文中简短地介绍这一点,因为我们会不断对其进行引用。 如果您对此已经熟悉,请跳过过去!

Scene View: Allows placement and movement of GameObjects in the Scene


Game View: Previews how the player will see the scene from the camera


Inspector: Provide details on the selected GameObject in the scene.


Assets / Project: All prefabs, textures, models, scripts etc are stored here


Hierarchy: Enables nesting and structuring of GameObjects within the scene


Now we’re good to start!


Unity游戏对象 (Unity Game Objects)

什么是游戏对象 (What are GameObjects)

GameObjects are the core building block of everything in the Unity games engine. The name almost gives it away:

GameObjects是Unity游戏引擎中所有内容的核心构建块。 这个名字几乎给了它:

Anything you place within a scene in Unity must be wrapped in a ‘game object.’

If you’ve got a web design background, you can think of GameObjects as being a lot like <div> elements! Extremely boring containers, but are highly extensible to create complex functionality or visuals.

如果您具有网页设计背景,则可以认为GameObjects与<div>元素非常相似! 容器非常无聊,但是可以高度扩展以创建复杂的功能或视觉效果。

Literally everything from particle effects, cameras, players, UI elements, … (the list goes on) is a GameObject.


创建层次结构 (Creating Hierarchy)

Like a <div> in web development, a GameObject is also a container. Just as you nest <div>s to create varied and desirable layouts or abstractions you may wish to do the same with games objects.

就像Web开发中的<div>一样,GameObject也是一个容器。 正如您嵌套<div>来创建各种所需的布局或抽象一样,您可能希望对游戏对象也是如此。

The logic behind nesting game objects is much the same as web development, I’ll give a few examples…

Clutter & Efficiency


Web Analogy: You’ve got many similar elements which may be dynamically generated on the fly in response to user interaction and want to keep them tidy.

网络类比: 您有许多类似的元素,它们可能会动态生成以响应用户交互,并希望保持它们整洁。

Unity Translation: Your building a Minecraft clone and you’ve loads of blocks in the scene, you need to add and remove ‘chunks’ of blocks from the scene for performance reasons. Thus having them parented to an empty GameObject for each chunk makes sense, as deleting the chunk parent removes all the children blocks.

Unity Translation: 构建Minecraft克隆并且场景中有大量块,出于性能原因,您需要从场景中添加和删除块的“块”。 因此,让它们为每个块添加一个空的GameObject作为父项是有意义的,因为删除父块会删除所有子块。



Web Analogy: You want to keep the position of the content contained ‘relative’ to the container and not to the web page.

网络类比: 您想保持包含的内容相对于容器而不是网页的位置。

Unity Translation: You’ve created a bunch of helper drones which hover around the player. You would really not rather write code to tell them to chase after the player, so instead you instantiate them as children of the player game object.

Unity Translation: 您已经创建了一群辅助玩家,它们徘徊在玩家周围。 您实际上并不想编写代码来告诉他们追随玩家,而是将它们实例化为玩家游戏对象的子代。

Unity内置组件 (Unity Builtin Components)

演员组件模型 (The Actor Component Model)

GameObjects on their own are pretty useless — as we’ve seen they’re pretty much just containers. In order to add functionality to them we have to add components, which are essentially scripts written in either C# or Javascript.

单独的GameObjects毫无用处-正如我们已经看到的,它们几乎只是容器。 为了向它们添加功能,我们必须添加组件,这些组件本质上是用C#或Javascript编写的脚本。

Unity works off an Actor Component model, put simply the GameObjects are the actors and the Components are your scripts.

Unity采用Actor Component模型,简单地说GameObjects是actor,而Components是您的脚本。

If you’ve written any web apps before you’ll be familiar with the idea of creating small reusable components such as buttons, form elements, flexible layouts that have various different directives and customisable properties. Then assembling these small components into larger web pages.

如果您已经编写了任何Web应用程序,那么您将熟悉创建小型可重用组件(例如按钮,表单元素,具有各种不同指令和可自定义属性的灵活布局)的想法。 然后将这些小的组件组​​装成较大的网页。

The big advantage of this approach is the level of reusability and clearly defined communication channels between elements. Likewise in game development, we want to minimise the risk of unintended side effects. Small bugs tend to spiral out of control if you’re not careful, and are extremely difficult to debug. Thus creating small, robust and reusable components is critical.

这种方法的最大优势是可重用性级别以及元素之间明确定义的通信渠道。 同样,在游戏开发中,我们希望将意外副作用的风险降至最低。 如果您不小心,小错误往往会失控,并且极难调试。 因此,创建小型,坚固且可重复使用的组件至关重要。

关键的内置组件 (Key Built-in Components)

I think it’s time for a few examples of the built in components provided by the Unity Games engine.

我想是时候来看看Unity Games引擎提供的内置组件的一些示例了。

  • MeshFilter: Allows you to assign materials to a 3D mesh to a GameObject


  • MeshRender: Allows you to assign materials to a 3D Mesh


  • [Box | Mesh]Collider: Enables detection of GameObject during collisions

    [箱| Mesh] Collider:可在碰撞期间检测GameObject

  • Rigidbody: Enables realistic physic simulation to act on GameObjects with 3d Meshes and will be trigger detection events on box colliders


  • Light: Illuminates portions of your scene


  • Camera: Defines the player viewport to be attached to a GameObject


  • Various UI Canvas Components for displaying GUIs


There are loads more, but these are the main ones you’ll need to get familiar with. One tip is that you can access all the docs for these through the unity manual and scripting reference offline wherever you are:

还有更多的负载,但是这些是您需要熟悉的主要负载。 一个提示是,无论您身在何处,都可以通过统一手册和脚本参考脱机访问这些文档的所有文档:

创建自定义组件 (Creating Custom Components)

The builtin components control physics and visuals primarily, but to really make a game, you’re going to need to accept user input and manipulate those standard components as well as the GameObjects themselves.


To start creating components, go into the desired GameObject > Add Component > type the name of your new component in the search bar > new script (c#).

As a general recommendation I’d advise against using Javascript in Unity. It hasn’t been kept updated with all the great stuff that came with ES6, and most of the more advanced stuff relies on C# stuff ported over to Javascript… It just becomes a one giant work-around in my experience.

作为一般建议,我建议不要在Unity中使用Javascript。 尚未随ES6附带的所有出色功能对其进行更新,并且大多数更高级的功能都依赖于移植到Javascript的C#内容……根据我的经验,这只是一个巨大的解决方法。

MonoBehaviour的结构 (Structure of a MonoBehaviour)

关键功能 (Key Functions)

All components inherit from the MonoBehaviour Class. It includes several standard methods, most importantly:

所有组件都继承自MonoBehaviour类。 它包括几种标准方法,最重要的是:

  • void Start() which is called whenever an object containing the script is instantiated in the scene. This is useful anytime we want to perform some initialisation code, eg. set a player’s equipment after they spawn into a match.

    void Start() ,每当在场景中实例化包含脚本的对象时,就会调用该方法。 每当我们想要执行一些初始化代码时,这都是很有用的。 在比赛产生后设置球员的装备。

  • void Update() which is called every frame. This is where the bulk of code involving user input will go, updating various properties such as the motion of the player in the scene.

    void Update() ,每帧都调用一次。 这是涉及用户输入的大量代码的去向,将更新各种属性,例如场景中播放器的运动。

检查器变量 (Inspector Variables)

Often we want to make components as flexible as possible. For example all weapons might have a different damage, rate of fire, has_sight etc. Whilst all the weapons are essentially the same thing we may want to be able to create different variations quickly through the unity editor.

通常,我们希望使组件尽可能地灵活。 例如,所有武器可能具有不同的伤害,射速,has_sight等。虽然所有武器本质上都是同一件事,但我们可能希望能够通过统一编辑器快速创建不同的变体。

Another example where we might want to do this is when creating a UI component that tracks user mouse movements and places a cursor in the viewport. Here we might want to control the sensitivity of the cursor to movements (if the user was using a joystick or gamepad vs a computer mouse). Thus it would make sense to have these variable easy to change both in edit mode and also experiment with them during runtime.

我们可能要执行此操作的另一个示例是在创建一个UI组件时,该组件可以跟踪用户的鼠标移动并将光标放置在视口中。 在这里,我们可能想要控制光标对移动的敏感度(如果用户使用的是操纵杆或游戏板而不是计算机鼠标)。 因此,使这些变量易于在编辑模式下进行更改并在运行时进行试验是有意义的。

We can do this easily by simply declaring them as public variables in the body of the component.


接受用户输入 (Accepting user input)

Of course, we want our game to respond to user input. The most common ways to do that are using the following methods in the Update() function of a component (or anywhere else you like):

当然,我们希望我们的游戏能够响应用户输入。 最常见的方法是在组件(或您喜欢的其他任何地方)的Update()函数中使用以下方法:

  • Input.GetKey(KeyCode.W) Returns True W key is being held down

  • Input.GetKeyDown(KeyCode.W) Returns True when W key is first pressed

  • Input.GetAxis(“Vertical”), Input.GetAxis(“Horizontal”) Returns between -1,1 mouse input movement

    Input.GetAxis(“ Vertical”),Input.GetAxis(“ Horizo​​ntal”)返回-1,1鼠标输入之间的移动

操纵游戏对象 (Manipulating GameObjects)

Once we have user input we want GameObjects within our scene to respond. There are several types of responses we may consider:

获得用户输入后,我们希望场景中的GameObjects做出响应。 我们可能会考虑几种类型的响应:

  • Translation, Rotation, Scale

  • Create new GameObjects

  • Sending messages to existing GameObjects / components

    向现有的GameObjects /组件发送消息

转变 (Transformations)

GameObjects all have a transform property which enable various useful manipulations on the current game object to be performed.


The methods above are fairly self explanatory, just note that we use lowercase gameObject to refer to the GameObject which owns this specific instance of the component.


In general it’s a good practice to use local[Position,Rotation] rather than the global position / rotation of an object. This usually makes it easier to move objects in a manner that makes sense, as the local space axis will be oriented and centered on the parent object rather than the world origin and x,y,z directions.

通常,最好使用local [Position,Rotation]而不是对象的全局位置/旋转。 由于局部空间轴将定向并居中放置在父对象上,而不是世界原点和x,y,z方向,因此这通常使以一种有意义的方式移动对象变得更加容易。

If you need to convert between local and world space (which often is the case) you can use the following:


As you can imagine, there is some fairly simple linear algebra behind this hinted at by the ‘Inverse’ in the method name.


创建新的游戏对象 (Creating new GameObjects)

Since GameObjects are basically everything in your scene, you might want to be able to generate them on the fly. For example if your player has some sort of projectile launcher you might want to be able to create projectiles on the fly which have their own encapsulated logic for flight, dealing damage, etc…

由于GameObjects基本上是场景中的所有内容,因此您可能希望能够即时生成它们。 例如,如果您的玩家使用某种弹丸发射器,则您可能希望能够动态创建具有自己封装的逻辑(用于飞行,造成伤害等)的弹丸……

First we need to introduce the notion of a Prefab. We can create these simply by dragging any GameObject in the scene hierarchy into the assets folder.

首先,我们需要介绍Prefab的概念。 我们可以简单地通过将场景层次结构中的任何GameObject拖动到资产文件夹中来创建它们。

This essentially stores a template of the object we just had in our scene with all the same configurations.


Once we have these prefab components we can assign them to inspector variables (as we talked about earlier) on any component in the scene, so that we can create new GameObjects as specified by the prefab at any time.


We can then perform ‘instantiation’ of the prefab and manipulate it to the desired location in the scene and establish the necessary parent relationships.


访问其他游戏对象和组件 (Accessing other GameObjects and Components)

Often we need to communicate with other GameObjects as well as their associated components. Once you have a reference to a game object this is pretty simple.

通常,我们需要与其他GameObject及其关联的组件进行通信。 引用游戏对象后,这非常简单。

ComponentName comp = some_game_object.GetComponent<ComponentName>();
ComponentName comp = some_game_object.GetComponent <ComponentName>();

After that you can access any of the public methods / variables of the component in order to manipulate the GameObject. This is the straightforward bit, however actually obtaining the reference to the GameObject can be done in several ways…

之后,您可以访问组件的任何公共方法/变量以操纵GameObject。 这很简单,但是实际上可以通过几种方式获得对GameObject的引用。

通过检查器变量访问 (Access via inspector variable)

This is the most straightforward. Simply create a public variable for the GameObject, as we’ve demonstrated earlier with the prefabs, and manually drag and drop it onto the component via the inspector. Then access the variable as above.

这是最直接的。 只需为GameObject创建一个公共变量(如我们之前在预制件中所展示的),然后通过检查器将其手动拖放到组件上即可。 然后按上述方式访问变量。

通过标签访问 (Access via tagging)

We can tag GameObjects or prefabs via the inspector and then use the find game object functions to locate references to them.


This is simply done as below.


GameObject some_game_object = GameObject.FindGameObjectWithTag(“Brick”);
GameObject some_game_object = GameObject.FindGameObjectWithTag(“ Brick”);

通过转换访问 (Access via transform)

If we wish to access components in some parent object we can easily do this via the transform attribute.


ComponentName comp = gameObject.transform.parent.GetComponent<ComponentName>();
ComponentName comp = gameObject.transform.parent.GetComponent <ComponentName>();

通过SendMessage访问 (Access via SendMessage)

Alternatively if we want to send a message to many other components or wish to message an object which is far up a nested hierarchy, we can use the send message functions, which accept the name of the function followed by the arguments.

另外,如果我们想向其他许多组件发送消息或希望向嵌套层次结构中远一个对象发送消息,则可以使用send message函数,该函数接受函数名和参数。

gameObject.SendMessage(“MethodName”,params); // Broadcast message
gameObject.SendMessage(“ MethodName”,params); // 广播消息
gameObject.SendMessageUpwards(“MethodName”, params); // Only received by components which are nested above.
gameObject.SendMessageUpwards(“ MethodName”,params); //仅由嵌套在上面的组件接收。

射线广播 (Raycasting)

You may have heard of this before when people compare FPS games that are ‘physics based’ or ‘ray based’. Raycasting is essentially like having a laser pointer which, when it comes into contact with a ‘collider’ or ‘rigidbody’, it returns a ‘hit’ and passes back the details of the object.

在人们比较“基于物理学”或“基于射线”的FPS游戏之前,您可能已经听说过这一点。 射线投射本质上就像是一个激光指示器,当它与“对撞机”或“刚体”接触时,它会返回“命中”并传回对象的详细信息。

There are two scenarios where this comes in handy (There’s probably loads more):


  1. If you were designing a weapon system for a game, you could use raycasting for hit detection, and even customise the length of the ray so that melee items ‘hit’ only at short ranges

  2. Create a ray from the mouse pointer to a point in 3d space, ie if you wish the user to be able to select units with their mouse in a strategy game.


As you can see, the code for this is a little bit more involved. The key thing to understand is that to cast a ray to where the mouse is pointing in 3d space requires the ScreenPointToRay transformation. The reason for this is the camera is rendering a 3d space as a 2d viewport on your laptop screen, so naturally there is a projection involved to transfer back to 3d.

如您所见,此代码涉及更多。 要理解的关键是将射线投射到鼠标在3d空间中指向的位置需要ScreenPointToRay转换。 原因是相机在笔记本电脑屏幕上将3d空间作为2d视口渲染,因此自然会有一个投影转移回3d。

碰撞检测 (Collision detection)

Earlier we mentioned the Collider and Rigidbody components which can be added to an object. The rule for collisions is that one object in the collision must have a rigidbody and the other a collider (or both have both components). Note that when using raycasting, rays will only interact with objects with collider components attached.

前面我们提到了可以添加到对象中的Collider和Rigidbody组件。 碰撞的规则是,碰撞中的一个对象必须具有刚体,而另一个必须具有碰撞体(或两者都有)。 请注意,在使用光线投射时,光线只会与附加了对撞机组件的对象进行交互。

Once setup within any custom component attached to the object, we can use the OnCollisionEnter, OnCollisionStay and OnCollisionExit methods to respond to collisions. Once we have the collision information we can get the GameObject responsible and use what we learned earlier to interact with components attached to it as well.

一旦在附加到对象的任何自定义组件中进行设置,我们就可以使用OnCollisionEnter,OnCollisionStay和OnCollisionExit方法来响应碰撞。 一旦获得了碰撞信息,我们就可以让GameObject负责并使用我们先前学到的知识来与连接到它的组件进行交互。

One thing to note is that rigid-bodies provide physics such as gravity for objects, so if you want this turned off you will need to check the is_kinematic on.


高级功能 (Advanced Features)

We won’t go into any of this now but perhaps in a future article — just to make you aware that they exist.


创建GUI的 (Creating GUI’s)

Unity has a fully fledged UI engine for laying out the GUI for your game. In general these components work pretty similarly to the rest of the engine.

Unity具有完善的UI引擎,可为游戏布置GUI。 通常,这些组件的工作原理与引擎的其余部分非常相似。

扩展Unity编辑器 (Extending the Unity Editor)

Unity enables you to add custom buttons to your inspectors so that you can affect the world during edit mode. For example, to help with world building you might develop a custom tool window for building modular houses.

Unity使您可以将自定义按钮添加到检查器,以便您可以在编辑模式下影响整个世界。 例如,为了帮助进行世界构建,您可以开发用于构建模块化房屋的自定义工具窗口。

动画 (Animation)

Unity has a graph-based animation system which enables you to blend and control animations on various objects such as players implementing a bone based animation system.


材料和PBR (Materials and PBR)

Unity runs off a physically-based rendering engine which enables real time lighting and realistic materials. The reality is you will either need to learn 3d modeling first or use models made and optimised by someone else before you get to this, in order to make stuff that actually looks good.

Unity运行于基于物理的渲染引擎,该引擎可实现实时照明和逼真的材质。 现实情况是,您需要先学习3D建模,或者使用其他人制作和优化的模型才能制作出看起来不错的东西。

给新人的建议 (Advice For Newcomers)

If you’re planning on writing your first game, don’t underestimate the complexity and time it takes to write even the most trivial of games. Remember most of the games that come out on Steam have teams working on them for years full-time!

如果您打算编写第一个游戏,请不要低估编写最琐碎游戏的复杂性和时间。 请记住,Steam上发布的大多数游戏都拥有专门从事多年工作的团队!

Pick a simple concept and break it down into small achievable milestones. It’s highly recommended to separate your game into as small independent components as possible, as you’re much less likely to run into bugs if you keep the components simple rather than monolithic code blocks.

选择一个简单的概念,并将其分解为可实现的较小里程碑。 强烈建议将您的游戏分成尽可能小的独立组件,因为如果使组件保持简单而不是单块代码块,则您遇到错误的可能性将大大降低。

Before you go and write any code for any part of your game, go and research what someone else has done before to solve the same problem — chances are they’ll have a much slicker solution.


不错的资源和社区 (Nice Resources and Communities)

Game design has one of the best communities of any out there, and there are loads of highly skilled pros in the industry who put content up for free or for next to nothing. It’s a field that requires 3d Modelers, Concept Artists, Game Designers, Programmers and so on. I’ve linked some great general resources that I’ve come across for each of these fields below:

游戏设计是目前为止最好的社区之一,并且行业中有大量熟练的专业人士,他们免费或几乎没有内容提供内容。 这个领域需要3D建模者,概念艺术家,游戏设计师,程序员等。 我已经为下面的每个领域链接了一些很棒的常规资源:

Concept Art


3D Modelling


  • CG Cookie (Best Mesh Modeling Basics in Blender Ever, they’ve loads of other excellent content for blender)

    CG Cookie (Blender中最好的网格建模基础,他们为Blender提供了许多其他出色的内容)

  • Tor Frick (Hard Surface Modelers & Sculptors in Blender)

    Tor Frick (Blender中的硬表面建模器和雕刻器)

  • Gleb Alexandrov (Short powerful rendering tutorials in Blender)

    Gleb Alexandrov (Blender中的简短强大的渲染教程)

Game Design




结论 (Conclusion)

Hope you guys liked this tutorial! I do a bit of graphic design work as well as game and UI prototypes so check out my portfolio! I’m also on linked in.

希望你们喜欢本教程! 我会做一些图形设计工作以及游戏和UI原型,所以请查看我的投资组合 ! 我也在链接中

Portfolio | LinkedIn

作品集 | 领英

翻译自: https://www.freecodecamp.org/news/the-ultimate-beginners-guide-to-game-development-in-unity-f9bfe972c2b5/


  • 2
  • 0
  • 5
  • 扫一扫,分享海报

评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
钱包余额 0