This page covers the internal structure of APreds UI for anyone who wants to understand how the mod works or extend it. The codebase is small — four files across two namespaces — but each plays a distinct role in the BepInEx and Unity lifecycle.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ASTRA228b/APreds-UI/llms.txt
Use this file to discover all available pages before exploring further.
Project structure
Plugin entry point (Plugin.cs)
Plugin is the BepInEx plugin class, identified by the [BepInPlugin] attribute. BepInEx instantiates it as a Unity MonoBehaviour when the game loads.
Plugin.cs
Awake() runs first. It creates a new GameObject named AUIOBJ, attaches the Main MonoBehaviour to it, and calls DontDestroyOnLoad so the object — and all mod state — survives scene transitions (such as entering or leaving a room).
Start() runs after Awake(), once all objects in the scene are initialized. It calls PatchLoader.Apply() to register HarmonyX patches with the runtime.
Main MonoBehaviour (Core/Main.cs)
Main is the heart of the mod. It extends MonoBehaviour and lives on the AUIOBJ GameObject for the lifetime of the game session.
OnGUI() is Unity’s immediate-mode GUI callback, called every frame when the GUI is being rendered. On its first invocation, Main calls INIT() to build the custom GUIStyle objects (dark window background, styled sliders and buttons) and sets StylesLoaded = true so INIT() only runs once. If IsOpen is true, it then renders the floating window via GUILayout.Window.
Update() runs every frame. It does three things:
- Detects a change in the
IsPredOntoggle. WhenIsPredOntransitions fromfalsetotrueit callsEnablePreds(); when it transitions fromtruetofalseit callsDisablePreds(). A separatelastPredStatefield tracks the previous value to detect the transition. - Calls
MakePreds()each frame whileIsPredOnistrue. - Checks whether the U key was pressed this frame (
Keyboard.current.uKey.wasPressedThisFrame) and togglesIsOpenaccordingly.
EnablePreds() creates two invisible cube GameObjects (LT for left hand, RT for right hand). For each cube it removes the BoxCollider and Rigidbody using Obliterate() (so they have no physics presence), disables the Renderer, and attaches a GorillaVelocityTracker component so the game’s own velocity-tracking logic can sample each hand’s movement.
DisablePreds() calls Destroy on both LT and RT and sets them to null, cleaning up all resources.
MakePreds() is the per-frame prediction loop. Each frame it:
- Guards against null references (
LT/RT,GTPlayer.Instance,GorillaTagger.Instance, and the hand/head transforms). - Mirrors the left and right hand transform positions onto the tracker cubes so
GorillaVelocityTrackersamples the correct locations. - Reads average velocity from each tracker and clamps it to a magnitude of
5to prevent runaway values. - For each hand, if velocity magnitude exceeds
movementThreshold, computes a target position ascurrentPosition + velocity * PredSrengthand Lerps the hand transform toward that target usingsmoothnessas thetfactor. - Clamps both hand positions to within
maxArmLengthunits of the head center usingVector3.ClampMagnitude.
HarmonyX patches (Stuff/PatchLoader.cs)
PatchLoader.Apply() instantiates a Harmony instance keyed to the plugin GUID and calls PatchAll().
Stuff/PatchLoader.cs
PatchAll() scans every type in the calling assembly for [HarmonyPatch] attributes and applies any patches it finds. In version 0.0.2 there are no explicit [HarmonyPatch] attributes anywhere in the codebase, so PatchAll() currently registers nothing. The infrastructure is in place for future patches without requiring changes to Plugin.cs.
Component helper (Core/Extensions.cs)
Extensions provides a single extension method on Unity’s Component base class:
Core/Extensions.cs
Obliterate() is a null-safe wrapper around UnityEngine.Object.Destroy. It is used in EnablePreds() to remove the BoxCollider and Rigidbody from the tracker cubes — components that Unity adds automatically when you call CreatePrimitive(PrimitiveType.Cube). Destroying them prevents the cubes from interacting with the physics simulation or triggering collisions while they shadow the hand positions.
APreds UI targets .NET 4.8 (
net48) to match the Unity runtime version used by Gorilla Tag. If you add dependencies, ensure they also target net48 or a compatible profile.