14
Розробка власного 2D- редактора рівнів на Unity

Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Embed Size (px)

DESCRIPTION

Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Citation preview

Page 1: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Розробка власного 2D-редактора рівнів

на Unity

Page 2: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Трохи про гру та її виклики

прив’язка до сіткирізні конвеєри труби та інше...

Page 3: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Готові асети vs свій велосипедSpriteTileTile BuilderUniTileTilerU2DEXNostalgia...ціни: $15-30

різноманітні можливості з асетів:

● зручності редагування● додаткові скрипти● колекції картинок● оптимізації drawcall’ів● геренерація оптимальних колайдерів● запікання шляхів● прив’язка до сітки - єдине що нам треба

Page 4: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Вікно редактора. початки

public class LevelEditorWindow : EditorWindow

{

public static bool editorEnabled = true;

[MenuItem("Window/Level Editor %_l")]

public static void Init()

{

var window = (LevelEditorWindow)GetWindow(typeof(LevelEditorWindow));

window.title = "Level Editor";

window.minSize = new Vector2(100, 50);

}

public void OnGUI()

{

editorEnabled = EditorGUILayout.Toggle("Enabled", editorEnabled);

}

}

Assets/Editor/LevelEditorWindow.cs:

Page 5: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Зберігаємо дані. EditorPrefs

...

public void OnFocus()

{

if (EditorPrefs.HasKey("LevelEditorEnabled"))

editorEnabled = EditorPrefs.GetBool("LevelEditorEnabled");

}

public void OnLostFocus()

{

EditorPrefs.SetBool("LevelEditorEnabled", editorEnabled);

}

public void OnDestroy()

{

EditorPrefs.SetBool("LevelEditorEnabled", editorEnabled);

}

...

Assets/Editor/LevelEditorWindow.cs:

Page 6: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Головна логіка редактора

Vector3 lastSelectedPos;

Transform selectedTrans;

public void Update()

{

if (editorEnabled && !EditorApplication.isPlaying && Selection.transforms.Length == 1)

{

selectedTrans = SelectImportantObj();

if (selectedTrans.position != lastSelectedPos)

{

var snapped = SnapSelected();

if (snapped) { … }

lastSelectedPos = selectedTrans.position;

}

}

}

...

Assets/Editor/LevelEditorWindow.cs:

Page 7: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Вибір головного об’єкта

static Transform SelectImportantObj()

{

var selectedTrans = Selection.activeTransform;

var rootTrans = selectedTrans.root;

if (rootTrans != null && rootTrans != selectedTrans)

{

if (rootTrans.CompareTag("Toggle") || rootTrans.CompareTag("Press") || ...)

{

Selection.activeTransform = rootTrans;

}

else if (rootTrans.CompareTag("Conveyer"))

{

Transform trans;

if ((trans = selectedTrans.ClosestWithTag("ConveyerCorner")) != null)

Selection.activeTransform = trans;

else

Selection.activeTransform = rootTrans;

}

Assets/Editor/LevelEditorWindow.cs:

Page 8: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Прив’язка з різними

якорями

enum Snap { Half, One, OneHalf }

bool SnapSelected()

{

if (selectedTrans.CompareTag("Arrow"))

return false;

if (selectedTrans.CompareTag("MainCamera") || ...)

{

return SnapCustom(selectedTrans, Snap.Half, Snap.Half);

}

if (selectedTrans.CompareTag("Ground") || ...)

{

return SnapCustom(selectedTrans, Snap.Half, Snap.OneHalf);

}

return SnapCustom(selectedTrans, Snap.OneHalf, Snap.OneHalf);

}

Assets/Editor/LevelEditorWindow.cs:

static bool SnapCustom(Transform trans, Snap snapX, Snap snapY) { var pos = trans.position; var x = SnapCustomVal(pos.x, snapX); var y = SnapCustomVal(pos.y, snapY); if (Mathf.Abs(x - pos.x) > Mathf.Epsilon || Mathf.Abs(y - pos.y) > Mathf.Epsilon) { trans.position = new Vector3(x, y, pos.z); return true; } return false; }

Page 9: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Інтерактивні елементи

рівня

Assets/Editor/LevelEditorWindow.cs:

if (snapped) { rootTrans = selectedTrans.RootIfExists(); else if (rootTrans.CompareTag("Conveyer") && selectedTrans != rootTrans) HandleConveyer(); ... }

void HandleConveyer()

{

...

conveyer.Resize(...);

EditorUtility.SetDirty(conveyer);

}

Page 10: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Custom Editorsбаза

Assets/Editor/ConveyerEditor.cs:

[CustomEditor(typeof(Conveyer))]public class ConveyerEditor : Editor{ Conveyer conveyer;

protected void OnEnable() { if (EditorUtility.IsPersistent(target) || !LevelEditorWindow.editorEnabled) return;

conveyer = (Conveyer) target; }

public override void OnInspectorGUI() { if (EditorUtility.IsPersistent(target) || !LevelEditorWindow.editorEnabled) { DrawDefaultInspector(); return; }

… }}

Page 11: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Custom Editorsдія на зміну поля

Assets/Editor/ConveyerEditor.cs:

public override void OnInspectorGUI() { ... GUI.changed = false; var canChangeDirBefore = conveyer.canChangeDir; …

DrawDefaultInspector();

if (GUI.changed) { if (canChangeDirBefore != conveyer.canChangeDir) conveyer.UpdateDirArrowDisabled(); …

EditorUtility.SetDirty(conveyer); } }

Page 12: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Скрипти-фіксери

всіх рівнів

Assets/Editor/LevelFixer.cs:

public class LevelFixer : MonoBehaviour{ [MenuItem("Custom/Fix Conveyers")] public static void FixLevelConveyers() { var conveyers = FindObjectsOfType<Conveyer>(); foreach (var conveyer in conveyers) {

// ... fix conveyer …

EditorUtility.SetDirty(conveyer.gameObject); } }

[MenuItem("Custom/Fix Conveyers (All levels)")] public static void FixAllLevelsConveyers() { RunOnAllLevels(FixLevelConveyers); }}

static void RunOnAllLevels(Action action) { if (!EditorApplication.SaveCurrentSceneIfUserWantsTo()) return;

var currentScene = EditorApplication.currentScene;

foreach (var scene in EditorBuildSettings.scenes) if (scene.path.Contains("Level")) { EditorApplication.OpenScene(scene.path); action(); EditorApplication.SaveScene(); }

EditorApplication.OpenScene(currentScene); }

Page 13: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Демонстрація редактора

Page 14: Gamedev Mixer. Лев Лукомський "Розробка власного 2D-редактора рівнів на Unity"

Дякую за увагу :)

Facebook: Лев Лукомськийemail: [email protected]: lllukom