Making The Northsong Rift in RPG Maker Unite - Part 2
I am thrilled to announce that I came in 1st place in the RPG Maker Themed Game Jam #6: Journey to the Underworld - itch.io!
To start Devlog Part 2, I want to congratulate everyone who participated in the game jam. A huge thank you to the Theme Jam community. Playing your fantastic games and seeing your progress was both inspiring and motivating. Lastly, I want to give a big shoutout to everyone who checked out Northsong Rift, thank you!
It is recommended that you read Part 1 first: Making The Northsong Rift in RPG Maker Unite - Part 1 - The Northsong Rift by Lochraleon
Player Sprites in a 3D World
Let’s revisit the Player and NPC setup I touched on in Part 1.
To control the player, I parented a camera to the Player GameObject. I used Unity’s Character Controller component and a custom Player Controller component for movement. Additionally, I added a child GameObject called Visuals, which included:
- Animator
- SpriteRenderer
- SpriteLibrary
- SpriteResolver
Overview of the Player GameObject with all components:
Components Breakdown:
- Character Controller: A built-in Unity component that simplifies movement by connecting the object to Unity’s 3D physics system.
- Player Controller: A custom script that interprets player input and ties into the battle system for seamless integration.
The Visuals GameObject showing the SpriteRenderer, Animator, SpriteLibrary, and SpriteResolver components:
You might notice that I am not just using Unity’s SpriteRenderer and Animator components. Adding the SpriteLibrary and SpriteResolver, lets me create multiple unique characters by simply dragging and dropping a new sprite sheet into a library. This setup allows me to reuse animations and configurations efficiently, somewhat similar to RPG Maker’s traditional approach but utilizing Unity’s built-in tools.
What’s even better? These libraries can be swapped at runtime, enabling dynamic sprite changes!
For more details on sprite swapping, check out Unity’s Sprite Swap | 2D Animation | 10.1.4 documentation.
Character Animations
The Animator uses Unity’s Animator Controller, which I configured for movement and in-battle animations.
Animator setup with blend trees and states for character movement and battles:
How the Animation States and Blend Trees Work
The “move” state (see in orange above) actually contains 2 blend trees, one for walking and one for idle animations. The blend trees automatically handle the animations for all 4 directions based on the player’s input. The “idleb” state contains the in-battle idle animation which branches off into in-battle attacks and casting states.
The PlayerAnimate script updates the Animator’s parameters based on player input.
- The “move” state continuously listens for the JUMP tigger. When X and Y are both 0, the “idle” blend tree is active, and uses the LASTX and LASTY parameters to determine the last direction the player faced. Otherwise, the “walk” blend tree is active.
- If BATTLEON is set to true the “idleb” state becomes active and listens for ATTACK and CAST triggers.
This organized approach of using multiple blend trees within a single state prevents the Animator from becoming a tangled mess of individual animations and transitions.
Close-up of the “move” state, showing walk and idle blend trees:
Battles!
Don’t forget I made this game for a jam, I needed a quick way to implement 3D battles. So don’t expect anything too elegant here lol!
The RMU handles all battle logic in an additive scene (Unity - Scripting API: SceneManagement.LoadSceneMode.Additive) called Battle, which runs on top of the SceneMap scene when a battle is activated. That means to integrate battles in 3D I really just needed to hide the 2D RMU character battle visuals in the Battle scene and add my own visuals in the existing 3D scene I initiated in Part 1. The Battle scene will continue to work as expected to display the battle UI and handle all the battle logic based on all the RMU spells, enemy stats, etc which was set up in the RMU editor.
The quick and easy way to hide the 2D battle visuals was to hide the RMU’s 2D battle visuals by setting the Battle Camera’s viewports to 0 and disabling the Canvas component on the Canvas GameObject (Yes, for some reason RMU uses a Canvas for battlers). DO NOT disable the Canvas UI GameObject’s Canvas (seen in the screenshot below), you need it for the built-in Battle UI which will still work without issue.
Unity editor showing quick and easy way to hide the 2D battlers:
Using CodeEvents and C# Actions
I created a static C# class called CodeEvents, which serves as a mini event system. This allows any part of my game to react to specific triggers by subscribing to Actions like my onBattleAction C# Action.
In Part 1, I explained how my CodeEvents class also works as an RMU addon so I can leverage RMU commands from the RMU eventing system to send notifications and information to all of my unity scripts. Here’s an example of how I used onBattleAction action to bridge the RMU battle system with my 3D world:
- I declared my C# Actions in the CodeEvents class.
- I added an event invocation to the WindowBattleLog class (RMU source code) on line 231, which handles battle messages like “Goblin attacks!”. I also added the Debug.Log on line 230 to monitor the text in the console (optional). As you can see the onBattleAction invocation takes a parameter “text” in the brackets. That parameter will pass the text from the WindowBattleLog to any “listeners” or scripts wherein a reaction is required.
- I set up the “listeners” by subscribing to the onBattleAction action in the scripts that need to react based on the message text. To prevent errors, I use Unity’s OnEnable and OnDisable methods to manage subscriptions:
- OnEnable: Subscribes to the onBattleAction Action when the component is active.
- OnDisable: Unsubscribes from the Action when the component is deactivated.
PlayerController script showing the OnEnable and OnDisable methods.
This ensures that only active components listen to events, preventing null references or unexpected behavior. The += OnBattleAction above in the PlayerController line 64 means that when the OnBattleAction is invoked the PlayerController will call the OnBattleAction method its line 190 seen below.
Here’s how the PlayerController script reacts to battle messages from OnBattleAction :
- If the message is “Leon casts Heal!” I use the EffekseerSystem API to play an Effekseer effect I declared as healEffect at the player's x, y, and z coordinates in 3D space using a Vector3 (Unity - Scripting API: Vector3).
- If the message is “Leon collapsed!”, the playerVisuals GameObject is deactivated, and the playerVisualDead GameObject is enabled.
You can customize this further. For example:
- The player casting the Lamenting Death spell with Unity’s particle system:
- Triggering the ATTACK animation trigger in the PlayerAnimate script:
- RMU’s damage formula is incredibly robust, but with the time constraints of the game jam, I couldn’t explore all its capabilities. Instead, I took a shortcut to implement a poison effect that reduces the enemy’s remaining HP by half. To achieve this, I leveraged the RMU API to modify the enemy’s health directly within the runtime data using the DataManager class. Since my battles involve only one enemy at a time, I simply updated the health of the enemy at index [0] using the SetHp method provided by RMU. This allowed me to quickly apply the desired health when triggered by the appropriate OnBattleAction invocation:
Enemy Health Bar
To add the enemy HP bar, I simply included it as part of the 3D model by adding a child Canvas GameObject with Render Mode set to World Space in the Canvas component. This ensures the health bar follows the enemy in the scene.
Enemy health bar setup with a world-space Canvas:
During battles, I dynamically update the health bar’s fill amount and text using the enemy’s current HP.
That’s all for now! Let me know if you have questions, and happy 2025! 🎉
Get The Northsong Rift
The Northsong Rift
When our world is torn asunder, we are reminded that our reality is but a thin veil over the abyss.
Status | Released |
Author | Lochraleon |
Genre | Role Playing |
Tags | 3D, RPG Maker, Unity |
Languages | English |
Leave a comment
Log in with itch.io to leave a comment.