How to Get Started with the Undertale-Changer-Template in Unity: Complete Setup Guide
Download the repository, open it in Unity 2021.3.15f1 LTS, launch the Title.unity scene, and press V to configure settings before extending the modular architecture through the MainControl singleton and ScriptableObject controllers.
The Undertale-Changer-Template (UCT) provides a production-ready Unity foundation for building Undertale-style fan games, featuring pre-built overworld and battle systems, external language-pack support, and configurable UI. This guide walks you through the exact import steps, initial verification, and key architectural components you will interact with to begin development immediately.
Prerequisites and Installation
Before opening the project, verify your environment matches the template requirements to avoid compilation errors.
- Unity Version: Install Unity 2021.3.15f1 LTS (or a newer 2021 LTS stream). The project dependencies and script compatibility target this specific version as noted in the documentation at
Documentation/readme.md. - File Path: Extract the repository to a path containing only ASCII characters (e.g.,
C:\UCT\or~/undertale-changer-template). Non-ASCII characters in the project path can cause Unity import failures. - Optional Asset Reference: While not strictly required for compilation, the template assumes you own a copy of Undertale for reference assets and naming conventions.
Clone or download the ZIP from arch-aik/undertale-changer-template, then add the root folder to Unity Hub via Add → Select Folder.
First Launch and Verification
Once imported, Unity will compile all C# scripts and import assets. Verify the installation by launching the entry scene.
- Navigate to
Assets/Scenes/and openTitle.unity. - Enter Play mode.
- The title screen should appear immediately, orchestrated by the
MainControlsingleton that initializes global services in itsAwake()method.
If the screen renders correctly, the core bootstrap in Assets/Scripts/UCT/Core/MainControl.cs has successfully loaded SettingsStorage and initialized the scene state manager.
Core Architecture Overview
Understanding three primary systems—MainControl, the settings layer, and the language-pack loader—lets you navigate the codebase efficiently.
The MainControl Singleton
MainControl is the persistent singleton that lives across every scene, handling the transition between Normal, Overworld, and Battle logical states.
- Location:
Assets/Scripts/UCT/Core/MainControl.cs - Key Methods:
Initialization()loads player preferences and language assets.InitializationScene()prepares the specific scene context (overworld or battle).StartWithSceneState()switches the active control logic based on the currentSceneStateenum.
In the source, the Awake() method (lines 22–48) instantiates services and calls InitializationLoad(), ensuring all subsystems are ready before the first frame renders.
Global Settings System
Settings are split between data storage and UI presentation to allow runtime changes without scene reloads.
- SettingsStorage: A static container class at
Assets/Scripts/UCT/Settings/SettingsStorage.csholding resolution, volume, key bindings, and language-pack IDs. - SettingsController: The UI manager at
Assets/Scripts/UCT/Settings/SettingsController.csthat renders the options menu and writes values back toSettingsStorage. - Access: Press
Vduring gameplay to invokeSettingsController.Instance.OpenSetting(), or use shortcutsTab(resolution),;(SFX toggle), andF4(fullscreen) handled inMainControl.SettingsShortcuts().
Language Pack Loader
UCT supports both internal and external localization without recompilation.
- Internal Packs: Bundled under
Assets/TextAssets/LanguagePacks/(default count:LanguagePackageInternalNumber = 3). - External Packs: Placed in
Assets/LanguagePacks/and enumerated at runtime. - Loading Logic:
MainControl.InitializationScene()(lines 90–100) callsDataHandlerServiceto loadsettingTexts,itemTexts, and scene-specific strings based on the activelanguagePackId.
Switch languages via the Language Pack section in the Settings UI, or programmatically by calling MainControl.Instance.Initialization(newLanguageId) to reload all text assets.
Extending the Template
Adding New Scenes
To transition between custom levels, use the utility service rather than direct SceneManager calls:
using UCT.Service;
using UnityEngine;
public class LevelPortal : MonoBehaviour
{
public void LoadCustomOverworld()
{
// Arguments: scene name, whether to force reload
GameUtilityService.SwitchScene("MyOverworld", false);
}
}
GameUtilityService.SwitchScene manages the fade-in/out animation and updates MainControl.sceneState to ensure the correct controller (OverworldControl or BattleControl) is active.
Modifying Game Logic
Controllers are implemented as ScriptableObjects, allowing you to swap behaviors without modifying core engine code.
- Overworld Logic: Defined in
Assets/Scripts/UCT/Control/OverworldControl.cs. Contains player movement, chase UI triggers, and collision detection. - Battle Logic: Referenced as
BattleControl(fallback toDemoBattle), holding encounter configuration and dialog assets. - UI Adaptation: Use
TextChangercomponents (found inAssets/Scripts/UCT/UI/TextChanger.cs) to adjustTMP_Textspacing and font size based onSettingsStorage.TextWidth.
Practical Code Examples
Toggling Settings from a Custom Script
using UCT.Settings;
using UnityEngine;
public class SettingsToggle : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.V))
{
// Opens the same UI as the in-game menu
SettingsController.Instance.OpenSetting();
}
}
}
This mirrors the logic found in SettingsController.cs (lines 54–73), which handles menu instantiation and focus management.
Cycling Language Packs Programmatically
using UCT.Core;
using UnityEngine;
public class LanguageCycler : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
int totalPacks = MainControl.LanguagePackageInternalNumber
+ MainControl.LanguagePackageExternalNumber;
int next = (MainControl.Instance.languagePackId + 1) % totalPacks;
// Reloads all language-specific assets
MainControl.Instance.Initialization(next);
}
}
}
The Initialization(int languageId) method in MainControl.cs (lines 43–55) refreshes the global text databases and updates UI elements bound to LanguagePackControl.
Summary
- Install Unity 2021.3.15f1 LTS and place the project in an ASCII-only file path to prevent import errors.
- Launch via
Title.unityto verify theMainControlbootstrap sequence initializes correctly. - Press V to access
SettingsController, or modifySettingsStoragedirectly for global configuration changes. - Switch languages at runtime through the Settings UI or by calling
MainControl.Instance.Initialization(). - Add scenes using
GameUtilityService.SwitchScene()to maintain proper state transitions and fade effects. - Extend logic by creating new
OverworldControlorBattleControlScriptableObjects rather than editing the coreMainControlsingleton.
Frequently Asked Questions
What Unity version is required for the Undertale-Changer-Template?
The template requires Unity 2021.3.15f1 LTS or a compatible 2021 LTS stream. This version is specified in Documentation/readme.md to ensure package compatibility and script compilation stability.
How do I change the language pack in-game?
Press V to open the Settings UI, navigate to the Language Pack section, and select your desired pack. Internally, this updates MainControl.languagePackId and triggers InitializationScene() to reload text assets from either Assets/TextAssets/LanguagePacks/ (internal) or Assets/LanguagePacks/ (external).
Where is the settings menu code located?
The UI logic resides in Assets/Scripts/UCT/Settings/SettingsController.cs, specifically the OpenSetting() method (lines 54–73). The static data container is Assets/Scripts/UCT/Settings/SettingsStorage.cs, which holds runtime values like resolution and volume.
How do I add a new overworld scene to the project?
Duplicate an existing scene file, add it to your build settings, then trigger a transition using GameUtilityService.SwitchScene("YourSceneName", false). This ensures MainControl updates the sceneState to Overworld and initializes the correct OverworldControl ScriptableObject for player logic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →