2D Platformer Tutorial for Unity
原文链接:https://github.com/hardlydifficult/Tutorials/blob/master/Platformer/C1.md
1) Project Setup
1.3) Configure Sprites
What's mesh type / full rect?
When a sprite is rendered to the screen, a combination of a mesh (like that used for 3D objects) outlining the sprite and transparency is used to draw the picture on-screen. Tradeoffs here are beyond the scope of this tutorial.
当在屏幕上渲染精灵时,(像在3D物体上使用那样)用来描绘精灵的轮廓的mesh(网格)与透明度的组合被用来在屏幕上绘制图像。这之间的折中(Tradeoffs )超出了本教程的范围。
-
Tight will attempt to better outline the sprite, using more polygons in the mesh.
-
Tight(紧密的)将尝试在mesh中使用更多的多边形,以便获得更好的精灵的轮廓
-
Full Rect will use 2 triangles per sprite.
-
Full Rect 将在每个精灵上使用两个三角形
When using tiling on a sprite, Unity recommends updating the sprite sheet to use 'Full Rect'. I don't have an example of issues that may arise from using 'Tight' instead, but here is the warning from Unity recommending 'Full Rect':
当在一个精灵上使用tiling(瓦片)时,Unity推荐使用 'Full Rect'。我不知道使用'Tight' 会有什么问题,但Unity推荐使用'Full Rect',下面是它的警告:
68747470733a2f2f692e696d6775722e636f6d2f65396a453833422e706e67.pngWhat's filter mode / point?
Using Point filter mode gets us closer to pixel-perfect sprites and prevents some visual glitches.
使用Point滤镜模式让我们获得更完美的精灵,防止产生一些视觉瑕疵。
Filter mode of Bilinear or Trilinear blurs the image a bit in attempt to make smooth lines. Often for a 2D game, we want control down to the pixel and this effect is not desirable. Here's an example with the character sprite we will be using:
Bilinear或Trilinear的滤镜模式会对图像进行少许的模糊处理来平滑线条。通常在2D游戏中,我们希望控制获得像素级控制,这种效果不满足需求。下面是我们将使用的精灵的例子:
68747470733a2f2f692e696d6775722e636f6d2f41597978334d612e706e67.pngFor sprite sheets, each object is often touching the one next to it. Filter Mode Point prevents blending between one sprite and its neighbor. The blending that occurs with other modes besides Point may lead to random lines showing up on-screen. For example:
对于精灵瓦片,每个对象常常与另一个接触。Point滤镜模式防止两个相邻精灵间的混合。除Point之外的其他模式的混合可能会导致随机线出现在屏幕上。例如:
68747470733a2f2f692e696d6775722e636f6d2f5a4b7167354a502e706e67.png1.6) Auto Save Script
using UnityEditor;
using UnityEditor.SceneManagement;
[InitializeOnLoad]
public class AutoSave
{
static AutoSave()
{
EditorApplication.playmodeStateChanged
+= OnPlaymodeStateChanged;
}
static void OnPlaymodeStateChanged()
{
if(EditorApplication.isPlaying == false)
{
EditorSceneManager.SaveOpenScenes();
}
}
}
This is a Unity-specific, editor-only attribute that enables the script. The static constructor of any class with this attribute is executed before anything else in the game.
这是Unity特有的,editor-only脚本属性。具有此属性的任何类的静态构造函数在游戏中的任何其他事物之前执行。
[InitializeOnLoad]
Here we register for a Unity event which will call the method below when the game begins while in the Unity editor. This event also fires when the game is paused or stopped.
在这里,我们注册一个Unity事件,在Unity编辑器中,当游戏开始时,将会调用下面的方法。这个事件也会在游戏暂停或停止时触发。
We don't need to deregister the event. Occasionally, Unity will terminate and restart this script, but otherwise we always want AutoSave to be running.
我们不需要销毁这个事件。有时Unity会终止并重新启动这个脚本,但是我们总是希望AutoSave运行。
EditorApplication.playmodeStateChanged
+= OnPlaymodeStateChanged;
}
What's a C# delegate / event?
A delegate in C# is an object representing method(s) to call at a later time. You may encounter delegates under the following names: Events, Action, Func, and delegate. Under the hood, these are all implemented with a 'multicast delegate'.
C#中的委托(delegate)是表示稍后调用的方法的对象。您可能会遇到以下名称的委托:Events,Action,Func和delegate。这些都是通过“多播委托( multicast delegate)”来实现的。
When a method is added to a delegate to be called later, this is referred to as 'subscribing'. 'Multicast delegate' means that any number of methods may subscribe to the same delegate. We use += when subscribing so as not to overwrite any other subscribers.
当一个方法被添加到稍后调用的委托时,这被称为“订阅”。“多播委托”意味着任何数量的方法都可以订阅相同的委托。订阅时使用+ =,以免覆盖任何其他订阅者。
EditorApplication.playmodeStateChanged += OnPlaymodeStateChanged;
If the owner of the delegate (EditorApplication in the example above) may outlive the subscriber, the subscriber should unsubscribe when it's destroyed. Also, any time you are no longer interested in future updates, unsubscribe. We do this with -= to remove our method and leave any remaining methods subscribed.
如果委托的所有者(上例中的EditorApplication)可能比订阅者活的更久,则订阅者在销毁时应该取消订阅。此外,任何时候你不再对将来的更新感兴趣时,就取消订阅。我们用 - =来移除我们的方法,并保留其余的方法订阅。
EditorApplication.playmodeStateChanged -= OnPlaymodeStateChanged;
Events are a common use case for delegates. For example, you may have a GameManager with a field for Points include an event "onPointsChange". Other components/systems in the game, such as Achievements and the UI, may subscribe to the onPointsChange event. When a player earns points, a method in Achievements is then called which can consider awarding a high score achievement, and a method in the UI is called to refresh what the player sees on-screen. This way, those components only need to refresh when something has changed as opposed to checking the current state each frame.
Events 是委托的常见用例。例如,您可能有一个GameManager,用文本框来记录得分,其中包含一个事件“onPointsChange”。游戏中的其他组件/系统(如Achievements和UI)可能会订阅onPointsChange事件。当玩家获得得分时,就会调用Achievements中的一个方法,这个方法可以考虑授予高分成就,并且调用UI中的方法来刷新玩家在屏幕上看到的内容。这样,这些组件只需要在某些事物发生变化时刷新,而不是每帧检查当前状态。
using System;
using UnityEngine;
public static class GameManager
{
public static event Action onPointsChange;
static int _points;
public static int points
{
get
{
return _points;
}
set
{
_points = value;
if(onPointsChange != null)
{
onPointsChange();
}
}
}
}
public class MyCustomComponent : MonoBehaviour
{
protected void Awake()
{
GameManager.onPointsChange
+= GameManager_onPointsChange;
}
protected void OnDestroy()
{
GameManager.onPointsChange
-= GameManager_onPointsChange;
}
void GameManager_onPointsChange()
{
// React to points changing
}
}