Transformation System

v1.0.0

Core Concepts

What a disguise actually builds, why detection uses the prop's own shape, and how a round is shaped.

The Four Pillars

The package is four independent systems that happen to combine into prop hunt. None of them requires any of the others, and the components are deliberately split along that line — the pieces on a hider are not the pieces on a hunter.

Player disguise

Transform Controller clones a world prop onto the character and hides its renderers.

Visual feedback

Prop Highlight marks what you can become; Transform FX plays particles and sound at the moment you do.

Hunter gameplay

Hunter Interaction inspects by raycast or melee hit, and fires correct / wrong guess events.

Round management

Round System runs the phases, the registration roster, the eliminations and the win conditions.

Prop Highlight belongs on prop players, not hunters. It is the hider's targeting affordance — it exists so a player can confirm which prop they are about to become. A hunter has nothing to aim into. It is safe to add anyway: a disguised player highlights exactly like the prop they are imitating, so a room of glowing crates never contains one crate that gives itself away by not glowing.

What a Disguise Builds

Nothing on your character is replaced. Transforming adds two children and hides your renderers; reverting destroys them and shows the renderers again.

Player  (your character - not modified)
|
+-- Collider ............ stays active and stays its original size.
|                         The motor keeps walking. Physics.IgnoreCollision
|                         keeps the hitbox from shoving it out of the disguise.
+-- Renderers ........... hidden while disguised, restored on revert
|
+-- PropHitbox .......... added on transform, destroyed on revert
|   +-- Rigidbody ....... kinematic, so this is its own physics island:
|   |                     no ground contact reaches your character's solver,
|   |                     which is what stops the disguise from shaking
|   +-- Collider(s) ..... copied from the PROP's own colliders. Solid to
|                         queries - this is the shape a hunter has to hit
|
+-- Prop clone .......... the whole world prop, instantiated and parented
    +-- Renderers ....... the prop's authored meshes and materials, at the
    |                     prop's authored world size - not your character's
    +-- Collider(s) ..... set isTrigger. Visual only. Never detected

The split is the point: one child is seen and the other is hit. The clone carries every mesh, material and script the prop had, so anything you attached to that prop keeps working while a player wears it — audio, custom interaction scripts, particle effects. The hitbox carries only shape.

Ground Snap (on by default) plants the disguise on the surface under the player rather than on the character's own foot level, which keeps props sitting correctly on slopes and steps. Switch it off for props that should float.

The Detection Shape

By default the hitbox reproduces the prop's own colliders, so a tree stays tree-shaped:

   Authored colliders (default)          Computed box (fallback)

           /\                            +----------------------+
          /  \                           |         /\           |
         /____\                          |        /  \          |
           ||     <- capsule              |       /____\         |
           ||        only                 |         ||           |
           ||                             |         ||           |
       ----++----                         +---------++-----------+

   A shot beside the trunk MISSES.       A shot beside the trunk HITS.

Computed Box — one box around everything the prop renders — is available on the Transform Controller's Hitbox Source field, and is used automatically for a prop that carries no colliders at all. For anything narrower than its own bounding box, the authored shape is what makes a hunter's aim mean something.

Highlighting

Prop Highlight reads a Highlight Settings asset: an optional outline material, a highlight colour, a max range, a layer mask and an emission boost used when no outline material is assigned. It also answers the Can Clone Prop condition, so the same component decides both what glows and what the transform key will do.

Two consequences of disguise parity worth knowing. Aiming at somebody's disguise and pressing your transform key copies the real prop they are wearing, sourced honestly — you end up as the same prop. And an undisguised character never highlights, or the highlight would mark every player in the level.

The Hunter Inspect

The inspect takes the nearest hit of anything, then asks whether it was a prop. That ordering is deliberate: it means you cannot target a prop through a wall. It also means a crosshair a few pixels off finds whatever is behind the prop instead — usually the floor.

Aim Assist Radius

Props are furniture. A table is a thin top on four thin legs; an armchair has gaps between its arms and its back. A crosshair over a table is mostly gap. An aim assist radius of 0.15 sweeps a 15 cm probe instead of a line, which forgives that without letting anyone shoot through a wall — whatever is nearest still wins. The trade: a nearer object slightly off the crosshair can now beat the one under it, so keep the radius near the size of the gaps you mean to forgive rather than as large as it will go.

What counts as a miss

With Wrong Guess Requires A Prop off, anything that is not a disguised player is a wrong guess. Combined with an Interaction Layer of Everything that includes the ground: a hunter who shoots grass pays the penalty for it. Switch it on and only a hit carrying a Prop World Object counts — scenery becomes a plain miss, while shooting the wrong crate still costs. It is off by default so no existing wiring changes behaviour on upgrade.

Interaction Range is measured from the character's origin — at the feet — not from the camera. Aiming at something 3 m away but 1.5 m up costs about 3.35 m of the budget, so a range that looks generous can reject a target that appears well within reach. Start at 6 rather than 3; a rejected inspect prints both numbers in a development build.

The Round State Machine

Four states. Two transitions are timers, two are things you call, and one is the hunters winning.

                     Start Round
       +-----------------------------------------+
       |                                         v
  +---------+                              +-----------+
  | Waiting |                              | PrepPhase |   hiders choose props
  +---------+                              +-----------+
       ^                                         |
       |                                         | Prep Duration elapses
       | Reset Round                             v
       |                                   +-----------+
       |                                   | HuntPhase |   hunters hunt
       |                                   +-----------+
       |                                         |
       |                    Hunt Duration elapses|  ... or the last prop
       |                     (props win)         |      is eliminated
       |                                         |      (hunters win)
       |                                         v
       |                                   +----------+
       +---------------------------------- | RoundEnd |
                                           +----------+
                                                 |
                                    Start Round  |  begins round 2 directly -
                                                 +-> no Reset needed, so one
                                                     button can run a session

End Round forces RoundEnd from either active phase. Waiting is only entered by Reset Round, for lobbies that need it — a session that plays rounds back to back never returns there.

The durations live on the asset, not on the component. They were on both once, 0 silently meant "inherit", and a scene displayed 30/180 while running 1/20. One number, one home. Props Alive follows the same rule: it is computed as registered − eliminated, never stored, so two copies of it cannot drift apart.

Stats & Damage

Prop Stat Sheet is a lightweight stat system that ships with the package — a list of stats, each with a current value, a maximum and an Is Vital flag. When a vital stat reaches its hard minimum, the sheet fires On Vital Depleted and clears Is Alive. Stat types are their own assets (Create → Transformation System → Stat Type), so "Health" is a thing you can point at rather than a string you retype.

This exists so a hunter can hurt a hider on day one without the paid GC2 Stats module. If you own GC2 Stats, use it instead — moving over is a one-instruction swap, since the damage lives on the instruction rather than inside the hunter.

Damage is authored where it is applied. Not on Hunter Settings — on the Deal Damage instruction in your graph. Two editable copies of a value do not stay equal, and the one on screen is not necessarily the one that runs: the demo's asset once said a wrong guess cost 10 while the scene dealt 50, and the asset's number was dead.

Persistence

Nothing in the Transformation System is saved. All of its state is session-scoped. That is a decision, not an omission — it is written down because "does my disguise survive a save?" is a question you should be able to answer before you buy.

StateLifetime
Whether a character is disguised, and as whatThe play session
Round number, phase and timerThe play session
Registered players, eliminations, Props AliveThe play session
Stat values on a Prop Stat SheetThe play session — reset to base on load
Whistle and hunter cooldownsThe play session

The asset models a round-based game mode, and a match in progress is not a thing that survives being put down and picked up a week later. Restoring a player mid-hunt into a round whose other participants no longer exist produces a broken session, not a resumed one.

What you probably do want to save is your own content — which props a player has unlocked, cosmetics, match history. The extension point is PropDefinition.Id: a stable GUID, generated once, guarded against duplication, and safe in a save file or a network payload. Store the IDs, look the definitions back up through the registry, and restore a disguise with Transform Into Prop (by ID). See Workflows.