Animated Custom Character - brandonandzeus/Trainworks2 GitHub Wiki

Introduction

Note This tutorial is adopted from the older Trainworks. I am not familiar with the Software Described here and just paid someone for Spine Animations. So I will keep the information on Dragonbones up, but will be updating the after steps.

Trainworks allows for the easy creation of Custom Animated Characters, this guide will go over the following:

  • Dragonbones Animation
  • Unity Engine Asset Bundling for Monster Train
  • Custom Character programming

TLDR: Workflow

For those familiar with an aspect of this guide, this TLDR will provide you with a quick synopsis of the workflow

  1. Open DragonBones and create an Animation, choosing the Animation name to be one of the following names: Idle, Attack, HitReact, Idle_Relentless, Spell, Death. (Note: most Monsters only use Idle, Attack, and HitReact animations, with the Death animation being rare. Idle_Relentless and Spell are for Flying Bosses.) The minimum requirement is just an Idle animation.
  2. Once you have completed one or more animations, export for Spine 3.7.94
  3. Import files into a Unity Project that contains the Spine.Unity Package
  4. Create an AssetBundle containing a SkeletonAnimation GameObject and a Sprite for representing the Character, move it to your plugin folder
  5. Create a Project using Trainworks, create a CardDataBuilder and within the Card set up your Character
  6. Set the SpriteBundleLoadingInfo to have your asset bundles name as its first parameter and your Sprite name as the second parameter, use the third parameter if you intend to have your asset bundle kept in a sub-folder of your plugin folder, do the same with SkeletonDataBundleLoadingInfo except with your SkeletonAnimation's name as the second parameter.
  7. If you did everything right it should work!

Full Walkthrough

DragonBones (unverified)

A note that this section may be out of date and that I the current maintainer have not followed these steps.

Installation

To begin, you need to Install Dragon Bones Pro v5.6.3, which can currently be found at https://docs.egret.com/dragonbones/en/index.html

Earlier versions of Dragon Bones Pro also work, but v5.6.3 does not require registration in order for you to export, which can save time and headache.

Alternatively, you can purchase Spine Essential at http://esotericsoftware.com/ which offers a premium version of the Dragon Bones Pro Workflow with fewer bugs and fancier exports.

Usage

For tutorials on the Usage of Dragon Bones Pro, Check out this video series: https://www.youtube.com/watch?v=GGD1jE2cpGM

Some Notes:

  1. It is imperative that your Animation name is one of the Following: Idle, Attack, HitReact, Idle_Relentless, Spell, or Death. Your Animation will not play in-game if that is not one of your Animation names. Added note from the current maintainer Idle, Attack, HitReact, and Death are the only animations used by Monsters in the game. Idle_Relentless and Spell is used for flying bosses.

Make Sure It's Named like this

  1. When you are ready to export, go under File > Export and make sure that the Type Dropdown is Spine, Data Version is 3.3 and Output Path is somewhere you can find your files

The Following Settings Work

  1. To make sure that the files will be able to properly be imported into unity, it is imperative that you alter the names and some text of the files outputted by Dragon Bones. Failure to do so may result in Spine.Unity being unable to recognize one of your files. If you are using Spine as your main tool, your export may automatically do these fixes.
  • Rename the Atlas File exported by DragonBones to be [Name].atlas.txt, so that it is recognized as a text file rather than an atlas file
  • Inside the [Name].json file after "skeleton":{ add "spine":"3.6.07-beta",, so that your [Name].json file is recognized later by Unity as being a valid Skeleton JSON file.

Should Look like this.

Json File should look like this

Unity Game Engine

Unity Installation

In case you do not have the Unity Game Engine, it highly recommended to download the Unity Hub at https://unity3d.com/get-unity/download

Once you have Unity Hub, head over to https://unity3d.com/get-unity/download/archive and go under there 2018.X section and get the latest Edition of Unity 2018.4.X. Click on the Unity Hub button and you should get Unity 2018.4.X

Other Future Versions of Unity can also work, but 2018.4.X versions are recommended because it minimizes the possibility of bugs and/or glitches that can occur between your Assets and Monster Train.

Spine for Unity Installation

Open up Unity Hub and create a New 2D Unity Project using your version of choice.

Once your project has opened, we need to get to work on importing Spine for Unity.

Luckily, the Installation is quite easy: just download one of the packages at http://esotericsoftware.com/spine-unity-download, I personally recommend Spine 3.7 found under older versions as it is likely to be the version used by Monster Train. Versions 3.6 or earlier do not work and it is likely that future versions will not be compatible with Monster Train.

Once you have the file, double click it and it should start installing into your open Unity Project.

Setting up your project

Once Spine is installed, it is time to get your animations into Unity.

  1. Create a New Folder with whatever name you want inside your Assets Folder, this is where we are going to put the Assets Created by our Export. (To Create a Folder, right-click inside your Assets Folder, selecting Create then Folder)
  2. Inside your Folder, press Show In Explorer, this will open up your Explorer System, drag and drop your exports into your folder, then click back on unity.
  3. If three news items appear, jump to step #4, else wise we need to create those Assets ourselves:
    • Right-Click inside your New Folder, Select Create then Material. Select your newly created a material and look for the Shader Drop-down, Select Spine, then Skeleton. Drag and Drop your Sprite into the Section marked as Main Texture.
    • Right-Click inside your New Folder, Select Create then Spine then Spine Atlas Asset, set materials to 1, dragging and dropping both your atlas.txt file and your material into their respective places.
    • Right-Click inside your New Folder, Select Create then Spine then SkeletonData Asset, set atlas assets size to be 1 and drag and drop the last remaining file of the three into the Skeleton JSON section and your Atlas Asset into the Atlas Asset Area. Set Scale to 0.01. If it worked Mix Settings, Preview, and other information should appear. When done your Skeleton Asset should look like this:

4. Now we need to create the Skeleton Animation, Right-Click on the Area denoted by SampleScene (by default), or whatever your Scene's name is. Select Spine then Skeleton Animation. Left-Click on the newly created asset and scroll down, in the area marked for SkeletonData Asset, Drag and Drop your SkeletonData Asset. Now test that everything worked as it intended by selecting your Animation in the Animation Name dropdown and pressing the play symbol near the top middle of your screen. If it all worked, you should see your animation play on your screen. 5. Left Click on your Skeleton Animation Asset and Drag and Drop it into your Folder, Right-Click and Rename it to be something you can remember. (I suggest naming it something like SkeleAnim_[Character Name])

Preparations for Bundling

Now we have all of our Assets properly in our project, we now just need to Bundle them together, for that we are going to need to quickly write a script. Importing Spine should have made a folder inside Assets named Editor, if not create a folder named Editor.

Inside your Editor Folder, Right-Click and Make a Script by pressing Create then C# Script, name that Script: AssetBundler, double-click to open that file and paste inside the following information, then save:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class AssetBundler : MonoBehaviour
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string assetBundleDirectory = "Assets/AssetBundles";
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        BuildPipeline.BuildAssetBundles(assetBundleDirectory,
                                        BuildAssetBundleOptions.None,
                                        BuildTarget.StandaloneWindows);
    }
}

Now we need to mark our Assets to be a part of our Asset Bundle, Select the Skeleton Animation Asset that you created earlier. In the Bottom-Right, you should see a section marked Asset Labels. On the first dropdown select it and press new, type in a name (I suggest you name it: [ModName]data). Whatever your name is, it will automatically be converted to lowercase.

One Last Thing: I suggest you import an image that you can use as a non-animated version of your animated character. Rename the image to something you can remember and under the Asset Labels dropdown select your previously named asset bundle. If you wish to edit the Image using code, mark in its import settings advanced -> Read/Write. Note: not all properties of Import Settings are transferred over via asset bundles, so the API offers a code-based way to set and modify them once loaded.

When you are ready to bundle, go to the top left and find Assets then select Build AssetBundles, wait a bit, then go over to the folder named AssetBundles. Right-Click on the Folder and show in explorer, look for the file with your only your asset bundles name that is not a meta-file, copy and paste it into your Monster Train Plugins Folder at C:\Program Files (x86)\Steam\steamapps\common\Monster Train\BepInEx\plugins

Visual Studio

Create a Visual Studio Class Library Project if you dont have one already. Inside of Visual Studio, Add your references by pressing Project then Add Reference, Look for the following:

Download off of the Releases Pages or Build yourself, then put into C:\Program Files (x86)\Steam\steamapps\common\Monster Train\BepInEx\plugins:
- MonsterTrainModdingAPI.dll
Find at C:\Program Files (x86)\Steam\steamapps\common\Monster Train\BepInEx\core
- BepInEx.dll
- BepInEx.Harmony.dll
- 0Harmony.dll
Find at C:\Program Files (x86)\Steam\steamapps\common\Monster Train\MonsterTrain_Data\Managed
- Assembly-CSharp.dll
- Unity.Addressables.dll
- UnityEngine.AssetBundleModule.dll
- UnityEngine.CoreModule.dll
- UnityEngine.dll
- UnityEngine.UI.dll

Rename Class1 to be Plugin and add the following code and then replace the bracketed information with the following:

[Project Name] should be whatever you named your project

[ModId] should be replaced with io.github.[Your Username].[Shorthand for your Mod], an example might be io.github.xxx_MonsterTrainFan_xxx.myAweMod

[ModName] should be the non-Shorthand version of your mod's name, an example might be myAwesomeMod

[ModVersion] should be the version, an example might be "0.1"

using System;
using BepInEx;
using MonsterTrainModdingAPI.Interfaces;
using HarmonyLib;

namespace [Project Name]
{
    [BepInPlugin(ModID, ModName, ModVersion)]
    [BepInProcess("MonsterTrain.exe")]
    [BepInProcess("MtLinkHandler.exe")]
    [BepInDependency("api.modding.train.monster")]
    public class Plugin : BaseUnityPlugin, IInitializable
    {
        public const string ModID = "[ModID]";
        public const string ModName = "[ModName]";
        public const string ModVersion = "[ModVersion]";
        public void Initialize()
        {
            var harmony = new Harmony(ModID);
            harmony.PatchAll();

            //Your code here:
            
        }
    }
}

Now go up to Project and click add Class, then name that class to be the card you want to make without spaces followed by Creator, ex: MyAwesomeCharacterCreator.

Take this code and replace the bracketed information with the following:

[Project Name] with your projects name

[Class Name] with the name of the class when you added this class.

[CardId] with your mods' name followed by an underscore then your cards name, for example, myAwesomeMod_myAwesomeCharacter

[CardName] with your cards' name

[CharacterID] with your mods' name followed by an underscore followed by Character followed by your cards name, for example, myAwesomeMod_Character_myAwesomeCharacter

[CharacterName] with your character's name.

[Bundlepath] should include your bundle's path, if it is in the plugin folder that would be just your bundle's name, else it should be something similar to "myFolder/myBundleName"

[Assetname_Sprite] the name of the sprite that you bundled

[Assetname_Skeleton] the name of the Skeleton Animation you bundled

Feel free to play around with other settings

using System;
using MonsterTrainModdingAPI.Builders;
using MonsterTrainModdingAPI.Managers;
using MonsterTrainModdingAPI.Enums.MTCardPools;
using System.Collections.Generic;
using HarmonyLib;
using System.Text;

namespace [Project Name]
{
    [HarmonyPatch(typeof(SaveManager), "SetupRun")]
    class AddToStartingDeck
    {
        static void Postfix(ref SaveManager __instance)
        {
            __instance.AddCardToDeck(CustomCardManager.GetCardDataByID("[CardID]"));
        }
    }
    class [Class Name]
    {
        public static void RegisterCard()
        {
            new CardDataBuilder
            {
                CardID = "[CardID]",
                Name = "[CardName]",
                Cost = 2,
                CardType = CardType.Monster,
                TargetsRoom = true,
                Targetless = false,
                Rarity = CollectableRarity.Rare,
                BundleLoadingInfo = new CustomAssetManager.AssetBundleLoadingInfo("[Assetname_Sprite]","[BundlePath]"),
                CardPoolIDs = new List<string> { MTCardPoolIDs.GetIDForType(typeof(MTCardPool_UnitsAllBanner)) },
                EffectBuilders = new List<CardEffectDataBuilder>
                {
                    new CardEffectDataBuilder
                    {
                        EffectStateName = "CardEffectSpawnMonster",
                        TargetMode = TargetMode.DropTargetCharacter,
                        ParamCharacterDataBuilder = new CharacterDataBuilder
                        {
                            CharacterID = "[CharacterID]",
                            Name = "[CharacterName]",
                            SkeletonAnimationBundleLoadingInfo = new CustomAssetManager.AssetBundleLoadingInfo("[Assetname_Skeleton]","[BundlePath]"),
                            SpriteBundleLoadingInfo = new CustomAssetManager.AssetBundleLoadingInfo("[Assetname_Sprite]","[BundlePath]"),
                            Size = 2,
                            AttackDamage = 5,
                            Health = 15,
                        }
                    }
                },

            }.BuildAndRegister();
        }
    }
}

Go back to your Plugin folder and write the following under the line that says //Your code here

[Class Name].RegisterCard()

Finally, it time to make your mod, go over to Build and press Build Solution. Go over to the place where you made your visual studio project and press Bin, then Debug, then netstandard2.0, look for your mod's name and copy and paste the .dll into your plugins folder. Run the game and start a new run, at the beginning of the run you should get your card that summons your character that is animated in your way.

⚠️ **GitHub.com Fallback** ⚠️