Creating Your First Map - SkaterXLModding/skater-xl-mapping-wiki GitHub Wiki
This guide will cover the first, and most basic, steps required to create a Skater XL map. For the sake of being beginner friendly, we will not use any 3rd party plugins of any kind, and this guide will be focusing completely on the Unity engine aspects of the process. For modelling guides please check the [modelling guides] sections. As always, you can refer to the related pages at the bottom.
Firstly, follow this link to go download Unity Hub. Follow the installation through, this process is fairly simple. It is recommended you make a Unity account and register a personal license in the Hub.
After installing Unity Hub, you will need to download the correct version of Unity. Skater XL currently runs using Unity 2019.3.15f1
, which can be found at the Unity download archive.
By clicking the Unity Hub download button, you will be able to initialize your new Unity version in the hub for ease of access.
Now open Unity hub, and select the drop down arrow next to the blue New
button in the top right. Select Unity 2019.3.15f1
from the list
Skater XL uses HDRP 7.3.1
, so in new project prompt window, we can select High Definition RP
to create a preset HDRP template project to work within. Be sure to title your project something meaningful, and select a good location for it to be stored.
Once you are ready, click Create
. It will take a few minutes for Unity to set up your new project, so go grab a drink.
In this guide we will not be covering a ton of in depth info related to using the Unity Editor beyond what is immediately pertinent to the SXL introductory process. To learn more please refer to the related pages or other external sources
After Unity has completed its initializing process, you will be greeted with this screen.
It's best to not totally close out of the HDRP Wizard, rather, we can grab it by the tab header and relocate it over to our right side panel. If you closed it and want it back, simply go to Window > Render Pipeline > HD Render Pipeline Wizard
to reopen the window.
If your window layout looks different, you can go to
Window > Layouts > Revert Factory Settings
Unity's window layout is very customizable, and you can easily rearrange existing windows, add more windows, close tabs, and more using the Window
drop down menu, and simply dragging and dropping things at will. Spending a moment to reorganize in a manner that makes sense for your workspace (for instance utilizing multiple monitors) can be a useful step to take before you get started on your project.
We can briefly take a look at some of the default tabs in our Unity editor, and what they do now.
The
Project
window is essentially our folder navigation. Any assets we add to our project, are stored here for easy access.
`Hierarchy is our tree of objects in the current scene
The central window is our
Scene
viewer, allowing us to interact with our current scene in real time
The
Inspector
is where we can see detailed information on the currently selected object
The
Tools
panel hosts basic implements that can be used to adjust objects in the scene in 3D space
Something that may take a minute to get used to, especially if you are not previously familiar with other 3D workspace programs, is navigating the scene window. Learning the navigational hotkeys and shortcuts can be very useful for this aspect
You can find more information on hotkeys and shortcuts in the unity editor at these pages:
Unity Manual - Scene View Navigation
Now that we are familiar with the basics of the Unity interface, it's time to create the scene we will be working in. Simply go File > New Scene
to do so
Before getting into doing the SXL specific things, its important to get a well set up scene. One handy trick is to select the Main Camera
object, and setting its layer to Editor Only
. If the map is loaded into the game with a camera then it'll force the player cam to that camera object. If it is set to the Editor Only
layer, then the camera will not be compiled in the runtime version of the map, but it can be used to preview things like lighting and post processing in the editor.
Now by right clicking in the hierarchy, you can create a new object. In this guide we are going to spawn a basic ground, and then place a cube on that plane, and make that cube a grindable ledge. So the first step is going to be to create the plane that will serve as the ground.
Next lets go ahead and get a 3D model of the skater for size reference before setting up a ledge. A low poly reference model can be found here. To keep the project organized, create a new folder in your Assets folder in the project window, in this guide we'll just call it Models
.
You can now simply drag and drop the .fbx file of the skater from your windows explorer into the models folder in the project window.
Back in the Unity Editor simply drag and drop the model into the 3D scene viewport.
Right click in the hierarchy to spawn another 3D object, this time a cube. By using the move tool we can rearrange the scene so the reference skater is next to the cube.
Now with a little bit of tweaking the ledge in the 3D viewport with the various tools at our disposal, we can easily resize the cube to resemble a more skatable feature.
This is a good time to go ahead and save the scene. Simply right click on the Untitled
name of the scene in the hierarchy and then select Save Scene As
. It is recommended you save your scene in the Scenes
folder.
Press
Ctrl + S
often to save your scene regularly
Before we move on with setting up the scene, it is important to add a spawn point, which will determine where the skater spawns in when loading into the map for the first time. Right click in the hierarchy, and Create Empty
. Select the new GameObject
and press F2, to rename the object. Rename the GameObject
to SpawnPoint
(case sensitive).
The skater will spawn with the board at the axis indicator gizmo location, and will always spawn pointing along the blue arrow. In the above example, the skater spawns just to the right corner of the box, looking towards it.
One tool SXL uses in Unity to determine certain functions of the objects we create in Unity is the Layer and Tag systems. We can, for instance, use tags to communicate to the game where to play brick rolling sounds, or to determine whether a bowl uses the AutoPump function or not. As such, it is important to set these up in a specific way so that the game can read information appropriately.
To set up the appropriate layers and tags, click the Layers
drop down in the top right of the editor, and select Edit Layers
from the menu.
Expand the categories for Layers and Tags, and add new ones using the following tables. Ordering, number, and capitalization are important.
Layer # | Layer Name |
---|---|
12 | Grindable |
16 | Coping |
Tag # | Tag Name |
---|---|
0 | Concrete |
1 | Wood |
2 | Metal |
3 | SpawnPoint |
4 | AutoRevert |
5 | AutoPumpAndRevert |
6 | Grind_Concrete |
7 | Grind_Metal |
8 | Surface_Concrete |
9 | Surface_Wood |
10 | Surface_Brick |
11 | Surface_Tarmac |
12 | AutoRevert_Concrete |
13 | AutoPumpAndRevert_Concrete |
14 | Surface_Grass |
Before moving on from this section, go ahead now and select the SpawnPoint object created earlier, and tag it as SpawnPoint.
Skater XL uses things called Grind Splines
to determine what is a surface for the skater to grind and slide. It is up to mappers to set up these grinds for the game to read upon loading the map. There are a small variety of different methods that can be used to create these splines, but in this guide we will be focusing on the Hondunes method, as it is 100% free, and does not require us to install any 3rd party assets of any kind. That being said, the Hondunes spline method is also arguably the least user friendly, and most tedious way to create grinds for a map. Feel free to skip this section of the guide and use the [Bill] (free community made editor plugin)or Dreamteck (paid, official dev used plugin) methods instead.
[Bills Spline Tool] is recommended for beginners
Grind splines are made up of 2 core components: collider and spline. Colliders are what Unity uses to determine what objects exist as interactable, and the shape of the collider determines the shape of the objects physical existence. Skater XL's custom map importer uses code to locate spline objects, and essentially draw lines between them to calculate the location of grinds on custom maps.
Using Hondunes spline technique, all grinds must be parented (sub-objects of, in the hierarchy) to one gameobject named Grinds
. So the first step is to create this object. Similar to before with the SpawnPoint
, right click in the hierarchy, Create Empty
, then rename it appropriately. You will also notice in the example image below I have manually adjusted the transform values of this game object to that it is centered at the world origin of 0,0,0
. This step is not necessary, but recommended.
Now, right click on the Grinds
object, and Create Empty
again. The new Game Object
, should be a child of the Grinds
object.
This new object will be the parent object of our first spline. These grind parents must follow a specific naming pattern to allow the game to not only register them as grind splines, but also dictate what sound the grind will make. The naming convention is as follows:
GrindSpline_<GrindType>_<GrindName>
<GrindName>
is fully optional, but recommended for the sake of organization further down the line
Grind_Metal
Grind_Concrete
Wood
GrindSpline_Grind_Metal_DownRail
GrindSpline_Wood_Bench
GrindSpline_Grind_Concrete
In this specific example, we are going to use the Grind_Concrete
sound on our ledge.
After naming the spline object appropriately, the next step is to locate it
Using the same 3D viewport implements as earlier, we can easily eyeball this empty game object into place. This particular object does not need to be super accurately placed, a near estimate is satisfactory as this will really only act as a container to control the next points we create. Once this object is in place, we will right click on our GrindSpline
object (or press Alt + Shift + N
) and create a child empty. These children of the GrindSpline
object are the points that "draw" the spline in the map importer. Splines are automatically calculated from point to point, allowing for both simple and complex splines to be quickly created. These points do not require any sort of naming convention to function.
In this example, the spline points should be positioned at either end of the edge of the ledge. While they can be estimated roughly into place as with the parent object, it is best to be precise with these. By selecting the Move Tool
, clicking in the scene viewport to make sure it is the active window tab, and then holding the V
key, we can enable vertex snapping. Now when moving the mouse, the GameObject
will automatically snap to a vertex on the 3D models in the scene. This allows us to easily align this point to an exact edge.
One thing to keep in mind, although not pertinent to this particular example, is that the green axis arrow on the move tool indicates the orientation of the grind normal. In simple terms, the green arrow, is the upwards lean of the grind. On a flat ledge like this leaving it default is what we want, but for instance on a down feature like a handrail, we would want to angle that using the
Rotation
tool so that it aligns perpendicularly to the grinding surface.
Now by pressing Ctrl + D
with the GameObject
selected still, we can duplicate this spline point. Once again, using the Move Tool
and vertex snapping, to easily align the spline point, this time with the far corner.
The spline hierarchy should now look like this. The blue line indicates where the importer will draw the spline for the skater to follow in game.
Now we need to implement the second core component of grinds, the collider. As we do not want this entire surface to trigger a grind (the middle of the ledge should be rideable as a normal surface) we need to give it specific colliders for each edge we want to be a grind.
Start by creating a new empty GameObject
as a child to our ledge
In the example I have renamed a few things such as the ledge, ground, and collider for easier organization. Not required, but recommended
A quick method to easily generate our new collider so that it is effectively aligned with the ledge, is to simply copy the ledge collider and then re-adjust the bounds to be where we want them. To do this, select the ledge in the hierarchy, right click the Box Collider
component, and select Copy Component
Then select the grind collider object in the hierarchy, right click the Transform
component, and select Paste Component as New
We can now adjust the bounds of the collider by enabling the Edit Bounding Volume
toggle on the Box Collider
component
Using the handles that appear with this toggle enabled, simply adjust the bounds of the collider so that it only covers the edge we have set up the grind for
Once the collider is in place, go ahead and disable the Edit Bounding Volume
toggle. Next, select the Layer
and Tag
dropdowns in the object inspector and apply Grindable
for the layer, and Grind_Concrete
for the Tag
Use the appropriate tag for your grind, we are using concrete in this example, but for a metal handrail use
Grind_Metal
, and so forth
You have now successfully set up your very first grind. Go ahead and replicate this process for all 4 edges of our ledge
Use duplicating, copy/paste, and vertex snapping to accelerate this process
The final step that will be covered in this guide will be the most basic lighting for our scene. Please keep in mind that lighting is a very complex topic, so much so that proper AAA environment design teams have dedicated lighting artists. If you are interested in learning more about lighting, consult the [Lighting Guide] wiki page, or one of the external resources cited on that page.
Lighting in Unity is comprised of two different types: Baked
and Realtime
. Realtime lighting is exactly as the name implies, light that is calculated in real time during gameplay. Baked lighting, is light that is pre-calculated, or baked, in the editor. Baked lighting uses 2D lightmap textures to store the lighting information. What this means, is that realtime lighting is more computationally intensive on the end user at runtime than baked. Another advantage of baked lighting is it allows us to calculate indirect lighting, or the way light would naturally bounce off objects. Shadows in real life are not perfectly black, because of indirect lighting, and we want to simulate that same effect in our level design. Baked lighting has one drawback however; which is calculating lighting on dynamic objects. The skater in our case, is a dynamic object. You cannot precalculate the lighting on the skater, because the skater can move freely and there fore there is no way to apply a 2D texture of lighting to such a dynamic object in game. The way to calculate indirect lighting, on a dynamic object, and allow baked lighting to work as flawlessly in game as possible, is to use LightProbes
, which calculate indirect lighting on dynamic objects.
Now that we have a very (very) basic grasp on some fundamental lighting concepts, we can use these to light our scene. The first step will be to set our Directional Light from Realtime
to Mixed
lighting.
It is recommended to keep the amount of
Realtime
andMixed
lights in your scene to an absolute minimum to save on performace
This allows the directional light, which is essentially our simulated sunlight, to be included in both realtime, and baked lighting calculations. This is usually one of the few lights in our scene we will set to Mixed
due to the performance cost of realtime lighting. Being a realtime light allows it to cast realtime shadows of the skater, which in this case we most definitely want.
The next step is to tell the game what objects in our scene are going to be receiving baked lighting. For this example I will mark the ledge and ground as baked objects, and leave the skater model as dynamic for the sake of demonstration.
In the hierarchy, hold Shift
and left click the objects we are settings as Static
for light baking. Then in the top right of the inspector check the box next to the Static
drop down. This will automatically set the objects to being fully static, which includes light baking. When prompted if we want to change children go ahead and select yes (although for this specific example it doesn't matter too much as the only children are grind colliders). Now you can check the drop down and see all the static properties that have been enabled. If you'd like to learn more about what all of these do, read more on the unity manual
Now that the appropriate objects are marked static, the next step is to set up a very basic LightProbe
network that will allow baked lighting to be calculated on dynamic objects as discussed earlier. In the hierarchy, right click, Light > Light Probe Group
. This will spawn a new Light Probe Group
comprised of 4 probes in the middle of your scene. Similar to editing the Box Collider
component earlier, select the Light Probe Group
game object and enable the Edit Light Probes
toggle in the inspector panel. This will allow us to adjust the location of the probes.
By having the Move Tool
selected, and then dragging in the 3D scene window, we can select multiple probes at once, similar to selecting multiple shortcuts on a Windows desktop.
Using the Move Tool
and selecting the appropriate multiple probes at the same time, move them so that they are above the ground, and there is a stack in each corner as shown in the example below.
Now that our objects are set to static and a basic Light Probe Group
is set up, it is time to bake the lighting. To do so, we need to add the Lighting Settings
window tab to our workspace. This can be accessed through Window > Rendering > Lighting Settings
Feel free to arrange this window in your workspace in a way that you find comfortable
For this basic bake, we will only need to adjust a few settings. There are a lot of values that can be adjusted to tweak how lighting in your map is generated, but with this example we will be focusing on 3. Firstly, if it is not automatically populated, set the Profile
to the profile that your scene is using by either dragging and dropping from the project window, or click the radio button (small circular button next to the property panel) and selecting it from that window. If you don't know what profile that is, select the Sky and Fog Volume
in the hierarchy, then click on the profile in the inspector. This will highlight the applied profile asset in your project window
Set the lighting sky to the appropriate one from the scene settings profile, by default it uses HDRISky
. Finally, we are going to set the Lightmap Resolution
from 40 to 1. This is not a necessary step by any means, but it will increase the speed of the bake significantly. This is a useful tip for any time in the future you are performing a very preliminary light bake, just to calculate the general lighting impression without taking a long time.
Once you have adjusted these settings appropriately, go ahead and click the Generate Lighting
button in the bottom right. After a moment of Unity running the lighting bake system, your lighting should be fully baked, and at the bottom of your Lighting Settings
you will see an info panel summarizing your baked lighting info
It is worth noting, that a final adjustments of lighting are often best done in PostProcessing
rather than directly applied through physical lighting. A good example of this is simply by disabling and enabling the PostProcessing
stack in the SampleScene. By default, if Unity does not detect any Post Processing volumes in the project, it will generate a baseline one for you. To learn more about post processing, check out the Post Processing wiki page, along with the external sources cited on that page.
As of 7/22/20 there is one more required step to create an SXL map. This section may be deprecated and removed with an upcoming patch.
On the Sky and Fog Volume
game object, add an exposure Override
to the Volume
component. This is required to avoid a 100% map loading error
Now that everything we need to make a baseline SXL map is set up, it is time to compile (export/build) the scene into an AssetBundle
for the game to read. First, open the Package Manager
window. This can be found in Window > Package Manager
After allowing the package manager a moment to load in all the packages, scroll down and select the Asset Bundle Browser
package, and click the Install
button in the bottom right
Once Unity has finished importing the package to the project, it can be accessed through Window > Asset Bundle Browser
Recommended to organize this along with your other window tabs somewhere easily accessible
Navigate the project window to the location your SXL scene is stored, in this case it is in the Scenes
folder. Select this scene asset so that it appears in the inspector. In the bottom of the inspector there is an AssetBundle
drop down initially labeled "None". Select this and click New
, then type in a name for your map file.
Click back on the scene view, after a moment of loading unity will prompt you that the open scene has been modified externally, select Reload
Now select the asset bundle browser window tab, and click the refresh button in the top right. After a moment your bundle should appear in the list. Here we can easily view the asset bundle contents and information.
Select the Build
tab at the top of the asset bundle browser. Expand the Advanced Settings
section. From the Compression
dropdown, select Chunk Based Compression (LZ4)
. This compression system allows for faster in game loading times at a very slight increase file size over the traditional LZMA method.
If you would like, you can change the output path, but for this guide we will leave it default
Finally, click the Build
button. Unity will now begin the process of compiling the asset bundle that we will use as our map file.
This process can take a long time, especially on the first pass, and any other pass after significant changes to the project, maybe get another drink
Once unity has finished the build process, you can quickly navigate to the assetbundle location by right clicking the Assets
folder in the project window, and selecting Show in Explorer
Once in your windows explorer, look for the File
type item that has the name you assigned. This should be the only file in your AssetBundles folder >2kb
Copy paste this file to your maps folder.
Congratulations, you just made a map for Skater XL!
[Intro to 3D Modelling]
[Bill's Splines]
[Advanced Collider Generation]
[Introduction to Lighting]
Learning the Unity High Definition RP
Unity Manual - Scene View Navigation