diff --git a/global.typ b/global.typ new file mode 100644 index 0000000000000000000000000000000000000000..1c00b11a57d0f0cd1ea2a1a7d0cb900466d4aaca --- /dev/null +++ b/global.typ @@ -0,0 +1,18 @@ +#import "@preview/wrap-it:0.1.0": wrap-content +#import "@preview/big-todo:0.2.0": * +#import "@preview/cetz:0.2.2": canvas, draw, tree + +#let add(s) = todo(inline: true, s) + +#let path(segments) = { + let e = 0.2em + box(inset: (x: e, y: e), fill: gray, radius: 3pt, baseline: e, { + for (idx, s) in segments.enumerate() { + let f = "DejaVu Sans Mono" // I think this is the default mono font. See https://github.com/typst/typst/issues/2870 + text(font: f, size: 9pt, s) + if idx + 1 != segments.len() { + $->$ + } + } + }) +} \ No newline at end of file diff --git a/images/Unity/actionmaps.png b/images/Unity/actionmaps.png new file mode 100644 index 0000000000000000000000000000000000000000..005ec57a8c64fff1089caa59e872bf9312117193 Binary files /dev/null and b/images/Unity/actionmaps.png differ diff --git a/images/Unity/components.png b/images/Unity/components.png new file mode 100644 index 0000000000000000000000000000000000000000..f778351a1805750662d24f22a14770811a171a23 Binary files /dev/null and b/images/Unity/components.png differ diff --git a/images/Unity/crosscompile.png b/images/Unity/crosscompile.png new file mode 100644 index 0000000000000000000000000000000000000000..dab1017667a553fd5e805603c93ff58225c3ba13 Binary files /dev/null and b/images/Unity/crosscompile.png differ diff --git a/images/godot/export/1 Open Export.png b/images/godot/export/1 Open Export.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e1b91e1b7d2d6ae42f38253ecb0487b5bdf1e2 Binary files /dev/null and b/images/godot/export/1 Open Export.png differ diff --git a/images/godot/export/2 Add.png b/images/godot/export/2 Add.png new file mode 100644 index 0000000000000000000000000000000000000000..ba31fee78c55666bf6456dd01e00417326a7a3d4 Binary files /dev/null and b/images/godot/export/2 Add.png differ diff --git a/images/godot/export/3 Select platform.png b/images/godot/export/3 Select platform.png new file mode 100644 index 0000000000000000000000000000000000000000..7a70e0c2c6b052e6de084b5d70c15e158a5f3935 Binary files /dev/null and b/images/godot/export/3 Select platform.png differ diff --git a/images/godot/export/4 Add template.png b/images/godot/export/4 Add template.png new file mode 100644 index 0000000000000000000000000000000000000000..e03d175b56e59513cb53a8238cc07dd62bad8663 Binary files /dev/null and b/images/godot/export/4 Add template.png differ diff --git a/images/godot/export/5 Download.png b/images/godot/export/5 Download.png new file mode 100644 index 0000000000000000000000000000000000000000..36772efc6d3fd7f19754f354917bf3a39f645f5c Binary files /dev/null and b/images/godot/export/5 Download.png differ diff --git a/images/godot/export/6 Export.png b/images/godot/export/6 Export.png new file mode 100644 index 0000000000000000000000000000000000000000..56cd11921d3555b94c5cb0bf0e02560c3e4043e4 Binary files /dev/null and b/images/godot/export/6 Export.png differ diff --git a/leitfaden.typ b/leitfaden.typ index fe52467f9588a2135c95d417edd36152ccd64b56..0e42e594310d5f29a27c69f1c3558d29da0b8eb0 100644 --- a/leitfaden.typ +++ b/leitfaden.typ @@ -1,7 +1,5 @@ #import "template.typ": * -#import "@preview/big-todo:0.2.0": * -#import "@preview/cetz:0.2.2": canvas, draw, tree -#import "@preview/wrap-it:0.1.0": wrap-content +#import "global.typ": * #let title = "Guideline for the RWTH GameJam 2024\nof Fachschaft Mathematik/Physik/Informatik" @@ -9,8 +7,6 @@ #outline(indent: auto, depth: 2) -#let add(s) = todo(inline: true, s) - #let info(content) = align(center)[ #box(fill: teal, stroke: black, width: 100%, inset: 1em, content) ] @@ -260,60 +256,5 @@ However, while high-quality and made for games, the animations can be difficult A screenshot from #link("https://play0ad.com/media/screenshots/")[0.A.D.] showing the 3D assets in action. ]) -= How to Godot - -== 3D Navigation -You navigate in the 3D panel, by pressing the right mouse button and move around with WASD. -Press `Shift` to fly faster. - -== Physics -You can generate a collider from a `MeshInstance3D` by selecting it, then open the `Mesh` options as seen in @godot-create-mesh. - -#figure(image("images/godot/create_mesh.png"), caption: [ - "`Create Trimesh Static Body`" creates a static body (position and rotation are locked) with a complex collider. - The other options create dynamic rigid bodies with colliders of varying complexity for this mesh. -]) <godot-create-mesh> - -#let simple_mesh_figure = figure(image("images/godot/simple_collider.png"), caption: [ - Inspector view, with a simple shape (here a sphere) selected -]) -<godot-simple-collider> - -#let body = [ - Instead of generating colliders, you can also add a child of type `CollisionShape3D` and select a simple shape in its shape attribute. - This is preferable performance-wise. -] -#wrap-content(simple_mesh_figure, body, align: top + left) - -== UI -UI components all inherit from the `Control` class. -The simplest layouting is to use `BoxContainer`s or `FlowContainer`s. -They work conceptually similar to flexbox#footnote[https://css-tricks.com/snippets/css/a-guide-to-flexbox/] in the HTML document model. -`HBoxContainer` and `VBoxContainer` stretch elements along the cross axis and cannot wrap in main direction. -`HFlowContainer` and `VFlowContainer` don't stretch elements along the cross axis and do wrap in main direction. -Elements whose position and size is not determined by the parent container, can use either absolute positions or anchors. -Text colors of `Label`s, space between of container elements, and similar properties are defined by the theme and can be overwritten by individual elements. - -#add("Image with anchor example") - -To theme your UI, set the theme in the topmost UI node. -#add("Theme example") - -== How to cross-compile? - -= How To Unity - -== Obtain Unity and setup a project -- UnityHub -- download a unity version in UnityHub - -== Objekte übers Netzwerk synchronisieren - -== UI Overlay - -== Music und Soundeffekte abspielen -#add("Unity sound manager den ich in Bubbleball hatte ins Template. Schauen wegen Galactic Kittens Lizenz falls noch anwendbar.") - -== Input processing - -== How to cross-compile? +#include "sections/godot.typ" +#include "sections/unity.typ" \ No newline at end of file diff --git a/sections/godot.typ b/sections/godot.typ new file mode 100644 index 0000000000000000000000000000000000000000..7eee432fd30ceda99ed5d6fc7010a2e921cad6be --- /dev/null +++ b/sections/godot.typ @@ -0,0 +1,76 @@ +#import "/global.typ": * + += How to Godot + +== Tips +- All fields accepting numbers also accept math expressions like `sqrt(2) - 1`. + +== 3D Navigation +You navigate in the 3D panel, by pressing the right mouse button and move around with WASD. +Press `Shift` to fly faster. + +== Physics +You can generate a collider from a `MeshInstance3D` by selecting it, then open the `Mesh` options as seen in @godot-create-mesh. + +#figure(image("/images/godot/create_mesh.png"), caption: [ + "`Create Trimesh Static Body`" creates a static body (position and rotation are locked) with a complex collider. + The other options create dynamic rigid bodies with colliders of varying complexity for this mesh. +]) <godot-create-mesh> + +#let simple_mesh_figure = figure(image("/images/godot/simple_collider.png"), caption: [ + Inspector view, with a simple shape (here a sphere) selected +]) +<godot-simple-collider> + +#let body = [ + Instead of generating colliders, you can also add a child of type `CollisionShape3D` and select a simple shape in its shape attribute. + This is preferable performance-wise. +] +#wrap-content(simple_mesh_figure, body, align: top + left) + +== UI +UI components all inherit from the `Control` class. +The simplest layouting is to use `BoxContainer`s or `FlowContainer`s. +They work conceptually similar to flexbox#footnote[https://css-tricks.com/snippets/css/a-guide-to-flexbox/] in the HTML document model. +`HBoxContainer` and `VBoxContainer` stretch elements along the cross axis and cannot wrap in main direction. +`HFlowContainer` and `VFlowContainer` don't stretch elements along the cross axis and do wrap in main direction. +Elements whose position and size is not determined by the parent container, can use either absolute positions or anchors. +Text colors of `Label`s, space between of container elements, and similar properties are defined by the theme and can be overwritten by individual elements. + +#add("Image with anchor example") + +To theme your UI, set the theme in the topmost UI node. +#add("Theme example") + +== Global state / Keep state accross scenes +https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html + +== How to cross-compile? +To export Godot games to different platforms, +you can read #link("https://docs.godotengine.org/en/stable/tutorials/export/index.html")[their manual], +or follow @godot-export. + + +#let godotExportGrid = grid( + columns: 3, + align: horizon, + image("/images/godot/export/1 Open Export.png", fit: "contain"), + image("/images/godot/export/2 Add.png", fit: "contain"), + image("/images/godot/export/3 Select platform.png", fit: "contain"), + image("/images/godot/export/4 Add template.png", fit: "contain"), + image("/images/godot/export/5 Download.png", fit: "contain"), + image("/images/godot/export/6 Export.png", fit: "contain"), +) +#figure(godotExportGrid, caption: [ + Open #path(("Project", "Export")) for the export menu. + There you can add targets with `Add`. + After adding the first target, Godot will complain that you have no export templates. + By click on `Manage Export Templates` you can open the dialog to download them. + After downloading the templates, you can add all targets and set the export path for each target. + You can either export a sigle target with `Export Project` or all with `Export All...` after configuring the export path for every target. +]) <godot-export> + +To use headless mode, simply add the `--headless` option when executing the game. + +To run on macOS, #link("https://developer.apple.com/programs/enroll/")[enroll the apple developer programm] or +#link("https://docs.godotengine.org/en/stable/tutorials/export/running_on_macos.html")[disable gatekeeper]. \ No newline at end of file diff --git a/sections/unity.typ b/sections/unity.typ new file mode 100644 index 0000000000000000000000000000000000000000..a986c77810864283ef7bedf78402d179c196fba6 --- /dev/null +++ b/sections/unity.typ @@ -0,0 +1,105 @@ +#import "/global.typ": * + += How To Unity + +== Obtain Unity and setup a project +Use #link("https://docs.unity3d.com/hub/manual/InstallHub.html")[UnityHub]. +You will also need to #link("https://unity.com/products")[register as student or personal user]. + +== Networking +Use #link("https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/tree/develop")[NetCode GameObjects]. +You can see it in use #link("https://github.com/UnityTechnologies/GalacticKittens/tree/main")[in GalacticKittens]. +See especially the `NetworkManager` component in the `Scenes/Bootstrap`, which has a list of Prefabs that need synchronization over the network. +See also the `Network Object`, `Client Network Transform`, and `Network RigidBody` components in `Prefabs/Net/Player/PlayerShipBase`, which are needed to determine what properties should be synchronized. + +== UI Overlay +The GalacticKittens sample project still uses the old UI system. +It is simple to start with, but inflexible and unresponsive. +The new system #link("https://docs.unity3d.com/Manual/UIElements.html")[UI Toolkit] builds UIs from XML and CSS with flexbox#footnote[https://css-tricks.com/snippets/css/a-guide-to-flexbox/] for layouts. + +#figure(```xml +<ui:UXML + xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" + xsi="http://www.w3.org/2001/XMLSchema-instance" + engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" + noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd" + editor-extension-mode="False" +> + <ui:Style src="OverlayBig.uss"/> + <ui:VisualElement name="full-screen-column"> + <ui:VisualElement name="top-row"> + <ui:Label class="fixed-portion" text="Testgame" name="mode"/> + <ui:Label class="fixed-portion" text="Left" name="team-left"/> + <ui:Label class="fixed-portion" text="" name="score"/> + <ui:Label class="fixed-portion" text="Right" name="team-right"/> + <ui:Label class="fixed-portion" text="0:00" name="time"/> + </ui:VisualElement> + </ui:VisualElement> +</ui:UXML> +```, caption: [UXML example]) + +#figure(```css +#top-row { + flex-grow: initial; + flex-direction: row; + justify-content: center; + font-size: 36; + -unity-font: url("../Fonts/OpenSans-Bold.ttf"); + background-color: lightgray; + height: 5%; + /* vertical horizontal */ + padding: 2px 8px; + margin: 0; +} +```, caption: [USS example]) + +== Music and sound effects +See #link("https://github.com/UnityTechnologies/GalacticKittens/blob/main/Assets/Scripts/Managers/AudioManager.cs")[the AudioManager from the GalacticKittens sample game] for sound management under Unity. + +== Input processing +There are two input systems. +The old one, called #link("https://docs.unity3d.com/Manual/class-InputManager.html")[Input Manager], and the new one in the #link("https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7/manual/index.html")[`InputSystem`-Package]. +The new input systems has a simple way (actionmaps) and a complex way (event handling) of processing user input. + +The simple way is shown by #link("https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7/manual/ActionAssets.html")[the docs]. +You create an `.inputactions` file with actions that are then mapped to `On<actionname>` methods. +This works if you have only one input device per local game instance. +However, it is unsuited if you want to allow a multiplayer mode by connecting multiple gamepads to the same PC. +In that case you need the to handle InputEvents, that know what device triggered them. + +The complex way is to register handlers for events in `UnityEngine.InputSystem.InputSystem`. +```cs +// on device connect or disconnect +void OnDeviceChange(InputDevice device, InputDeviceChange change); +// on input +void OnInputEvent(InputEventPtr inputEvent, InputDevice inputDevice); + +// register +UnityEngine.InputSystem.InputSystem.onDeviceChange += OnDeviceChange; +UnityEngine.InputSystem.InputSystem.onEvent += OnInputEvent; + +// unregister +UnityEngine.InputSystem.InputSystem.onDeviceChange -= OnDeviceChange; +UnityEngine.InputSystem.InputSystem.onEvent -= OnInputEvent; +``` + +#figure(image("/images/Unity/actionmaps.png"), caption: [ + Example of an action map with an action `Move` of type `Vector 2`, + that can be triggered on keyboard by WASD keys or with on gamepad with the left stick. +]) + +== Global state / Keep state accross scenes +Keep entities with `DontDestroyOnLoad` after scene and initialize them in a bootstrapping scene. +Again, see #link("https://github.com/UnityTechnologies/GalacticKittens/blob/main/Assets/Scripts/Utility/Singleton.cs")[GalacticKittens]. + +== How to cross-compile? +You can adapt #link("https://osak.fsmpi.rwth-aachen.de/files/gamejam-2024-07-05/Builds.cs")[the build file from my bubbleball project] +and put it into `Assets/Editor/Builds.cs` to create a Unity Toolbar Item for builds. + +To make it work, you need to have the modules for all supported platforms installed via UnityHub as seen in @unity-export. + +#figure(image("/images/Unity/crosscompile.png"), caption: [ + Module options on Linux for Linux, MacOS, and Windows support for both graphical and headless (dedicated server) mode. + Since this screenshot was done on Linux, there is no `Linux Build Support (Mono)` option, which is built-in on Linux. + If you are on Windows, the `Windows Build Support (Mono)` option would be built-in and `Linux Build Support (Mono)` has to be selected additionally. +]) <unity-export> \ No newline at end of file