Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thunderkit Utilities #558

Merged
merged 23 commits into from
Sep 18, 2024
Merged
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7f73102
Added asset bundles guide
Indigocoder1 Feb 28, 2024
2d9cd12
Grammar changes and formatting
Indigocoder1 Feb 28, 2024
2f03104
Grammar & readability improvements. Added prefab guide
Indigocoder1 Feb 29, 2024
612d98d
Fix a couple grammar issues
LeeTwentyThree Feb 29, 2024
c8d44e8
Fixed names and comment spaces
Indigocoder1 Mar 1, 2024
c41b416
Merge branch 'master' of https://github.com/Indigocoder1/Nautilus
Indigocoder1 Mar 1, 2024
699d92e
Replace constant classID with PrefabInfo one
Indigocoder1 Mar 1, 2024
56a92bc
Changed TechType to PascalCase
Indigocoder1 Mar 1, 2024
19bda17
Fix duplicate usage of "on"
LeeTwentyThree Mar 1, 2024
d4616b4
Add Nautilus.Utility using statement
LeeTwentyThree Mar 1, 2024
3bc5d8a
Since the prefab has a recipe, must be pickupable
LeeTwentyThree Mar 1, 2024
12d6124
Merge branch 'master' of https://github.com/Indigocoder1/Nautilus
Indigocoder1 Sep 14, 2024
f0e3d6f
Added thunderkit utilites
Indigocoder1 Sep 14, 2024
ad6de78
Added SN/BZ checking
Indigocoder1 Sep 14, 2024
cbd18cb
Added separate enums for the layers in SN & BZ
Indigocoder1 Sep 14, 2024
a6cd36c
Changed name of application modes
Indigocoder1 Sep 14, 2024
600639d
Moved material getters to MaterialUtils
Indigocoder1 Sep 14, 2024
0e5f48d
Changed layer application to use switch expression
Indigocoder1 Sep 14, 2024
50efec8
Removed unnecessary comment
Indigocoder1 Sep 14, 2024
8b2ddd0
Changed property names to respect their type name
Indigocoder1 Sep 14, 2024
a86deef
Added default index of 0 to material indices
Indigocoder1 Sep 14, 2024
1c2a2d5
Added graphic setting and reverted default build config
Indigocoder1 Sep 14, 2024
3a31553
Added graphic option to layer applier & removed outdated comment
Indigocoder1 Sep 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Grammar & readability improvements. Added prefab guide
  • Loading branch information
Indigocoder1 committed Feb 29, 2024
commit 2f03104d83e1314cbbdb2c6e6c6cfe9c33ac9b84
222 changes: 195 additions & 27 deletions Nautilus/Documentation/guides/assetbundles.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Asset Bundles Guide

This guide will show you how to take a 3d model file from a program such as Blender, and turn it into a GameObject which can then be used in your mod.
This guide will show you how to convert and package custom files into the Asset Bundle format, which can easily be loaded by your mods.
You will learn how to take a file exported from a 3D modeling program (such as Blender) and turn it into a GameObject which can then be loaded by your mod.

Basic modding knowledge is required for this tutorial.
Here are some things you will need to know:
Expand All @@ -10,50 +11,77 @@ Here are some things you will need to know:
The first thing you will need to do (Assuming you have a model already) is download the Unity Hub.
This is where you will get the Unity version you need to use to export your asset bundle.

The version Subnautica uses is 2019.4.36 for SN1, as well as Below Zero.
If you can't find that exact version, just get the one closest to it.
The version Subnautica uses is 2019.4.36.
This is the same on Below Zero.

Here are the download links you will need:
- Unity hub: [https://unity.com/download](https://unity.com/download)
- Unity version archive: [https://unity.com/releases/editor/archive](https://unity.com/releases/editor/archive)
- Unity version archive: [https://unity.com/releases/editor/archive](https://unity.com/releases/editor/archive)

## Creating the Unity Project

> [!NOTE]
> It's not necessary to make a new Unity project for each mod (individual projects are actually quite large), but for this tutorial we will be making a fresh project.

Once you've installed both, open Unity hub and click "New Project" from the top right.
Once there, select 3D Core, choose your project name and then click "Create Project".
Next, follow these steps:
1. Verify your Unity version is correct.
2. Select 3D core from the template list.
3. Configure your project name and location.
4. Click on "Create Project."
![assetbundles-project-setup](../images/guides/assetbundles-project-setup.png)

> [!NOTE]
> If you get the error "<font color="red">Failed to resolve project template</font>", follow these steps:
> 1. Locate where your editor is.
> You can do that by opening Unity Hub, going to Installs, and then right clicking on the version in question and clicking "Show in Explorer"
> You can do that by opening Unity Hub, going to Installs, and then right clicking on the version in question and clicking "Show in Explorer."
> 2. Go to ``Editor\Data\Resources\PackageManager\ProjectTemplates``. You will find a ``manifest.json`` and ``UnityLicense.json`` files. delete them both.
> 3. Kill Unity Hub in your task manager and open it again.
>
> You should now be able to create your project!

The Unity editor will now open. This may take a while.
Once the editor is open, drag your model from your file manager into the Scene window.

You can either click on your model in the scene window or in the hierarchy on the left to select it.
## Installing the Asset Bundle Browser

Next, click on ``Window`` at the top of the Unity editor, and then click ``Package Manager``.
Once the editor has opened, click on ``Window`` at the top of the editor, and then click ``Package Manager``.
Click on the dropdown at the top left and select ``Unity Registry`` if not on it already.
Search for "Asset Bundle Browser" and install it.

Next, drag your model from the hierarchy on the left into the ``Assets`` section at the bottom.
## Creating the Prefab

Once the editor is open, drag your model from your file manager into the Scene window.
You can either click on your model in the scene window or in the hierarchy on the left to select it.

If you need to, you may place your model under an empty GameObject (in the editor, GameObject -> Create Empty) to apply any necessary model scaling and to separate it from any other children. Constructable prefabs (aka base modules) specifically REQUIRE the model object to be separate from the entire prefab as an individual child object.

Next, drag your model from the hierarchy on the left into the ``Project`` section at the bottom.
This will create what is called a ``Prefab``. It can be instantiated (created/spawned) multiple times, but they are all copies of the original.

To edit the prefab, double click on it in the ``Assets`` window.
## Editing the Prefab and Adding Components

To edit the prefab, double click on it in the ``Project`` window.
You can add components to the prefab by clicking "Add Component" in the inspector on the right.
One example of a component is a ``RigidBody``, which can apply physics to your Prefab.
One example of a component is a ``Rigidbody``, which can apply physics to your Prefab.
Keep in mind, however, that every (non-kinematic) Rigidbody requires a WorldForces component to work properly, which must be added either through code or with a tool such as Thunderkit.
Any components you add will be included in the AssetBundle.

You <font color="red">**should not**</font>, however, add scripts you made in the editor, as the AssetBundle will not link them to the scripts in your modding project and you will get errors.
> [!CAUTION]
> You <font color="red">**should not**</font>, however, add scripts to your prefab that you made in the editor!
> The AssetBundle will not link them to the scripts in your modding project and you will get errors.

## Assigning the Asset Bundle

After all your prefab configuration is done, click on it in the ``Assets`` window, and click on "Asset Bundle" in the bottom right of the Inspector.
Next, follow these steps to assign an asset bundle to your prefab.
1. After all your prefab configuration is done, select it in the ``Project`` window.
2. Click on on "Asset Bundle" in the bottom right of the Inspector.
Here you can either assign your prefab to an existing AssetBundle or create a new one.

![assetbundles-assigning](../images/guides/assetbundles-assigning.png)

Once you've assigned your AssetBundle, click ``Window``, and then ``AssetBundleBrowser``.
## Exporting the Asset Bundle

Once you've assigned your AssetBundle, open the Asset Bundle Browser (Window → AssetBundleBrowser at the top of the editor).
Here you can see all the assets that will be put into your AssetBundle.
![assetbundles-browser](../images/guides/assetbundles-browser.png)

Expand All @@ -62,18 +90,46 @@ You can also configure the ``Output Path`` of the build.
After all that is set, click ``Build``.

Once your AssetBundle is built, move the built file to the location of your mod in the Plugins folder.
I prefer to put them inside a folder namded "Assets", but that isn't necessary.
It's generally prefered to put them inside a folder named "Assets", but that isn't necessary.
![assetbundles-assets-folder](../images/guides/assetbundles-assets-folder.png)

Now the hard part is done! All you need to do is load it into your mod's code.
To do this, you will need to add an extra reference to your mod.
Right click ``References`` in Visual Studio under your project and select add reference.
Now the hard part is done! All you need to do is load it within your mod's code.

## Referencing the AssetBundleModule

Click Browse, and navigate to ``[Game Location]/Subnautica_Data/Managed``, and add ``UnityEngine.AssetBundleModule.dll`` as a reference.
This will allow you to load your AssetBundle into code.
> [!WARNING]
> If you are using the Nautilus template or have installed the Nautilus NuGet package, skip this step.
> The template and package include all the ``UnityEngine`` references already, so referencing them twice may cause errors.

The first thing you will need to do is add the ``UnityEngine.AssetBundleModule.dll`` as a reference in your IDE (Assuming you don't already have it referenced).

## [Visual Studio 2022](#tab/vs)
1. Open your project tab and right click on References.
2. Select ``Add Reference``.
3. Click Browse, and navigate to ``[Game Location]/Subnautica_Data/Managed``, and add ``UnityEngine.AssetBundleModule.dll`` as a reference.
4. Click ``Ok`` to close the window.
![assetbundles-references](../images/guides/assetbundles-references.png)

## [JetBrains Rider](#tab/rider)
1. Right click on your project, and navigate to ``Add → Add Reference``.
2. Click ``Add From``.
3. Navigate to ``[Game Location]/Subnautica_Data/Managed``, and add ``UnityEngine.AssetBundleModule.dll`` as a reference.
4. Click ``Ok`` to close the window.

## [.NET CLI](#tab/cli)
1. Open a terminal.
2. Enter ``dotnet add [Path to your project file (.csproj)] reference [Subnautica Location]/Subnautica_Data/Managed/UnityEngine.AssetBundleModule.dll``.
---

## Using the Asset Bundle

> [!NOTE]
> The way you load assets from the Asset Bundle will depend on if you're using Nautilus or not.

# [Not using Nautilus](#tab/noNautilus)

Here's some example code of how you can load in your prefab:

```csharp
using BepInEx;
using System.IO;
Expand All @@ -84,7 +140,7 @@ namespace Examples
{
internal class AssetBundles : BaseUnityPlugin
{
//I usually do this in my Plugin script but technically you can do it wherever
//Usually this is done in your Plugin script but technically you can do it wherever
public static AssetBundle assetBundle { get; private set; }

//This gets the path to the "Assets" folder inside my plugin folder
Expand All @@ -95,20 +151,132 @@ namespace Examples
private void Awake()
{
//Keep in mind that the assetbundle can only be open in one place at a time, so keep a reference
assetBundle = AssetBundle.LoadFromFile(Path.Combine(AssetsFolderPath, "mirrorassetbundle"));
assetBundle = AssetBundle.LoadFromFile(Path.Combine(AssetsFolderPath, "myAssetBundle"));

//This name needs to be the exact same name as the prefab you put in the bundle
GameObject mirrorVariant1 = assetBundle.LoadAsset<GameObject>("Mirror_Variant1");
GameObject mirrorVariant1 = assetBundle.LoadAsset<GameObject>("myGameObject");
}
}
}
```

# [Using Nautilus](#tab/nautilus)

Here is one example of how to load in the asset bundle using the Nautilus ``AssetBundleLoadingUtils`` class:

```csharp
using BepInEx;
using System.IO;
using System.Reflection;
using UnityEngine;

namespace Examples
{
internal class AssetBundles : BaseUnityPlugin
{
//Usually this is done in your Plugin script but technically you can do it wherever
public static AssetBundle assetBundle { get; private set; }

private void Awake()
{
//Keep in mind that the assetbundle can only be open in one place at a time, so keep a reference
//This method assumes you have a folder named "Assets" in your mod's plugin folder
//The second parameter needs to be the name of the asset bundle file (Usually they don't have file extensions)
assetBundle = AssetBundleLoadingUtils.LoadFromAssetsFolder(Assembly.GetExecutingAssembly(), "myAssetBundle")

//This name needs to be the exact same name as the prefab you put in the bundle
GameObject mirrorVariant1 = assetBundle.LoadAsset<GameObject>("myGameObject");
}
}
}
```
---

## Using the Imported Asset

And just like that you have your prefab in your code!
To use this in a Nautilus prefab, just use
To use a GameObject from your Asset Bundle in a Nautilus prefab, simply write
```csharp
myCustomPrefab.SetGameObject(myAssetBundleGO);
```
Instead of using a CloneTemplate.
Instead of using a prefab template.
<br>
For more complicated prefabs (such as buildables), you can create your own method that loads the prefab from the asset bundle and applies extensive modifications to it.
You can *also* apply changes to the prefab directly.

E.g., ``myAssetBundleGO.AddComponent<WorldForces>();``

Here is one example of how to use an Asset Bundle GameObject in a custom prefab:
```csharp
using Nautilus.Assets;
using Nautilus.Assets.Gadgets;
using Nautilus.Crafting;
using Nautilus.Utility;
using UnityEngine;
using Ingredient = CraftData.Ingredient;

namespace ExamplePrefab
{
internal static class MyCoolPrefab
{
public static TechType techType { get; private set; }

public static void Patch()
{
PrefabInfo prefabInfo = PrefabInfo.WithTechType("myCoolPrefab", "My Cool Prefab", "Pretty cool, right!")
.WithIcon(SpriteManager.Get(TechType.Titanium));
//Just using the Titanium sprite as a placeholder

//Cache the tech type for use in other places
techType = prefabInfo.TechType;

var prefab = new CustomPrefab(prefabInfo);

//Create the recipe
RecipeData recipe = new RecipeData
{
craftAmount = 1,
Ingredients =
{
new Ingredient(TechType.Titanium, 2),
new Ingredient(TechType.CopperWire, 2),
},
};

//Set the prefab GamrObject to the result of the GetAssetBundlePrefab method
prefab.SetGameObject(GetAssetBundlePrefab());

//Using the Seaglide as a placeholder unlock
prefab.SetUnlock(TechType.Seaglide);

//Set the recipe
prefab.SetRecipe(recipe)
.WithCraftingTime(6f);

//Add the prefab to the Miscellaneous tab of the blueprints in the PDA
prefab.SetPdaGroupCategory(TechGroup.Miscellaneous, TechCategory.Misc);

prefab.Register();
}

private static GameObject GetAssetBundlePrefab()
{
GameObject myCoolPrefab = assetBundle.LoadAsset<GameObject>("myCoolPrefab");

//The classID is the same as the one we put into the PrefabInfo.WithTechType up above
//The LargeWorldEntity.CellLevel determines how far away the object will be loaded from the player
PrefabUtils.AddBasicComponents(myCoolPrefab, "myCoolPrefab", techType, LargeWorldEntity.CellLevel.Medium);

//Makes the GameObject have the correct shaders
//You can use the optional inputs here to change the look of your object
MaterialUtils.ApplySNShaders(myCoolPrefab);

//Return the GameObject with all the components added
return myCoolPrefab;
}
}
}
```

This reaches the end of this guide. If you have more questions about AssetBundles, feel free to ask in the modding channels of the modding Discord.
There are endless possibilities with Asset Bundles, so don't hesitate to experiment!
If you have more questions about Asset Bundles, feel free to ask in the modding channels of the modding Discord.
Loading