React TSX game UI framework for Unity, powered by Puerts + UGUI.
Write game UI in TypeScript/TSX with React's component model, render natively on Unity UGUI. Designed for AI-assisted (Vibe Coding) game UI development.
- React TSX — Declarative UI with components, hooks, state management
- Unity UGUI Native — Renders to real UGUI elements, not WebView
- Flexbox Layout — Pure JS Flexbox engine (no WebAssembly dependency)
- Game Components —
BagGrid,SkillBar,ChatPanel,HpBar,BuffIcon,DamageNumber,TabBar, etc. - Animation — Tween engine, easing functions,
useFadeIn,useSlideIn,useBounceIn,useShake - Gestures —
useLongPress,useSwipe,usePinch,useRotation - Drag & Drop —
DragDropProvider,useDrag,useDrop - Global State —
createStore,useGameState+ C#DataBridgefor game data - Filters — Blur, grayscale, shadow, outline, brightness (custom shaders)
- i18n —
I18nProvider,useI18nwith parameter interpolation - Window Manager — Modal/popup stacking,
GameWindowcomponent - Web Preview — Browser-based preview with HMR, no Unity needed for iteration
- Hot Reload — WebSocket HMR in Unity Editor
- Type Safe — Full TypeScript strict mode, compile-time error detection
- AI-First — JSON Schema + CLI for AI-assisted UI generation
- Node.js 18+, pnpm 8+
- Unity 2021.3+ with Puerts v3.0+
- TextMeshPro (included in Unity)
git clone https://github.com/user/TowerGUI.git
cd TowerGUI
pnpm install# Local (monorepo)
pnpm tower-ui create my-game
# After publishing to npm (for external users)
# npx @tower-ui/cli create my-gameThis scaffolds:
apps/my-game/TsProject/— TypeScript project with build configapps/my-game/Assets/Scripts/TowerUISetup.cs— Unity scene auto-setup
- Create a Unity project at
apps/my-game/(or open an existing one) - Install the Puerts Unity plugin
- Add TowerUI runtime package to
Packages/manifest.json:"com.towerui.runtime": "file:../../packages/unity-runtime"
- Generate Puerts typings:
Unity → PuerTS → Generate - Copy typings to
TsProject/typings/
cd apps/my-game/TsProject
pnpm install
node build.mjsOpen Unity, press Play.
Edit TsProject/src/main.tsx, rebuild, see changes:
function GameHUD() {
const hp = useGameState(store, s => s.player.hp);
return (
<ui-view width={1920} height={1080} flexDirection="column">
<HpBar current={hp} max={100} width={300} height={30} />
<SkillBar skills={skills} width={600} height={80} />
<ChatPanel channels={channels} width={400} height={300} />
</ui-view>
);
}Use node build.mjs --watch for auto-rebuild on save.
TowerGUI/
├── packages/
│ ├── core/ # Core framework (reconciler, layout, components, hooks)
│ ├── unity-adapter/ # Unity UGUI adapter
│ ├── unity-runtime/ # Unity C# package (Bridge classes + Shaders)
│ ├── web-adapter/ # Browser DOM adapter (for preview)
│ ├── schema/ # UI JSON schema + validator + codegen
│ ├── cli/ # CLI tool (create, preview, validate, generate)
│ ├── preview/ # Web preview dev server
│ ├── animate/ # Animation extensions
│ └── components/ # Additional components
├── apps/
│ └── unity-demo/ # Demo app (HUD, bag, skills, chat)
├── docs/ # Architecture design documents
└── README.md
TSX Components (React)
│
React Reconciler
│
┌────┴────┐
│ Adapter │ ← IEngineAdapter interface
└────┬────┘
│
┌─────┴──────┐
│UnityAdapter│ → C# UIBridge → UGUI GameObjects
│ WebAdapter │ → DOM Elements (preview)
└────────────┘
- Core (
@tower-ui/core): React reconciler, Flexbox layout engine, component library, animation, gestures, state management - Adapter: Pluggable rendering backend.
UnityAdaptercreates real UGUI elements via C# Bridge;WebAdaptercreates DOM elements for browser preview - Unity Runtime (
com.towerui.runtime): C# static classes that create/manipulate UGUI, forward events, load assets, push game data
ui-view, ui-text, ui-image, ui-button, ui-input, ui-toggle, ui-slider, ui-progress, ui-scroll
BagGrid, SkillBar, ChatPanel, HpBar, BuffIcon, DamageNumber, GameTooltip, TabBar
PopupMenu, ComboBox, TreeView, VirtualList, GameWindow
| Hook | Purpose |
|---|---|
useGameState(store, selector) |
Subscribe to global game state |
useTween(config) |
Animate any value |
useFadeIn() / useSlideIn() |
Preset animations |
useLongPress(config) |
Long press gesture |
useSwipe(config) |
Swipe gesture |
useDrag(config) |
Drag source |
useDrop(config) |
Drop target |
useController(pages) |
Multi-page/tab state |
useWindowManager() |
Open/close windows |
useI18n() |
Internationalization |
useMovieClip(config) |
Frame animation |
useScreenTransition() |
Screen transition effects |
useSafeArea() |
Mobile safe area insets |
useScale(config) |
Responsive scaling |
# In the monorepo, use: pnpm tower-ui <command>
# After npm publish: npx @tower-ui/cli <command>
pnpm tower-ui create <name> # Scaffold new project
pnpm tower-ui dev [entry.tsx] # Start web preview server
pnpm tower-ui validate <schema.json> # Validate UI JSON
pnpm tower-ui generate <desc> -o <file> # Generate TSX from description
pnpm tower-ui schema # Print component schemaAll packages use TypeScript strict mode. Run type checks:
pnpm type-check # Check all packages via turboMIT