Voxel Playground Mod Documentation - v0.4.0
    Preparing search index...

    Tutorial: SpiderMan

    This tutorial covers the current SpiderMan avatar sample in Assets/Samples/com.cydream.spiderman. The active implementation is written in TypeScript and drives the assembled player character through JsComponentProxy, ModAPI, and the runtime EntityCharacter object.

    Before importing the .vox file, separate the character into individual limbs and give every part a clear name. The character importer uses those child voxel objects to build the generated character prefab and map them to the skeleton.

    Use names that match the body parts you want to assign later, such as:

    • head
    • chest
    • pelvis
    • arm_upper_l
    • arm_lower_l
    • hand_l
    • arm_upper_r
    • arm_lower_r
    • hand_r
    • leg_upper_l
    • leg_lower_l
    • foot_l
    • leg_upper_r
    • leg_lower_r
    • foot_r

    SpiderMan voxel part naming in MagicaVoxel

    Open Vox Assets Processor and follow the import flow:

    1. Drag the SpiderMan .vox file into the processor.
    2. Set Convert Type to Avatar.
    3. Click Convert.
    4. The tool creates a GameObject in the scene with the imported voxel parts under the root transform.

    After conversion, select the generated GameObject and configure Avatar Proxy:

    1. Click Auto Assign to map the imported voxel parts to the body slots. Verify that each slot points to the correct voxel limb, and fix any mismatches manually.
    2. (Optional) Add script hooks for any custom behavior in Avatar Proxy.

    SpiderMan character conversion and auto assign workflow

    After the voxel parts are assigned, use the scene view to line them up with the generated skeleton before you continue with gameplay logic.

    1. Select the generated avatar root in the scene.
    2. Preview the assigned voxel body parts and skeleton together.
    3. Move and rotate each voxel limb until it matches the target bone position.
    4. Check the silhouette from the front and side views so the arms, hands, legs, and feet sit naturally on the rig.

    This alignment pass is important because the SpiderMan script assumes the runtime avatar is already assembled on a cleanly matched skeleton.

    SpiderMan voxel limb alignment with skeleton

    When setting up the avatar prefab with AvatarProxy and the required avatar content, note that you do not add EntityCharacter directly to the prefab in the authoring step.

    At runtime, the game instantiates another character prefab and assembles the content referenced by AvatarProxy into the actual player character. That assembled runtime object exposes EntityCharacter, which is why the TypeScript script can resolve and use it.

    Because the authored objects under the mod's AvatarProxy are not automatically attached to the runtime character's body parts, you must move them manually in your TypeScript script's onStart lifecycle method. Use ModAPI.GetCharacterBody to locate the target body part and re-parent your custom objects.

    For example, to attach an authored particle system to the character's hip:

    private onStart(): void {
    if (this.smokeParticles) {
    // Get the runtime character's Hip body part
    const hip = ModAPI.GetCharacterBody(ModAPI.ControlledCharacter, "Hip");
    if (hip) {
    // Re-parent and reset transform
    this.smokeParticles.transform.SetParent(hip.transform);
    this.smokeParticles.transform.localPosition = Vec3.zero;
    this.smokeParticles.transform.localRotation = Quat.identity;
    this.smokeParticles.transform.localScale = Vec3.one;
    }
    }
    }

    To enable the grappling behavior:

    1. Export Spiderman from Scripts/index.ts.
    2. Setup "ModId" and "ClassName" to AvatarProxy in the avatar prefab.
    3. Set the proxy class name to Spiderman.
    4. Keep AvatarProxy on the prefab as the avatar authoring component.
    5. Add JsProperties entries for any optional sound hooks:
      • moveJetSound
      • reelRopeSound
      • hookShotSound

    The script resolves EntityCharacter from the assembled runtime player object and then manages the rest of the feature from TypeScript.

    The sample creates two grappling states, one per hand, and updates them every frame:

    • It reads fire and ability input through ModAPI.Input.
    • It raycasts or sphere-casts from the controller direction to find grapple targets.
    • It attaches joints to the character with mod API helpers.
    • It renders the rope with runtime-created LineRenderer objects.
    • It applies pull forces, reel-in behavior, and swing assist in onFixedUpdate.

    That means you do not need to author extra MonoBehaviours for rope rendering or joint management. The TypeScript class owns all of it.

    The script works best when:

    • The game can resolve left and right controller transforms.
    • The avatar is assembled correctly from AvatarProxy into a runtime player character.
    • The target objects expose the expected rigidbody or voxel collision data.

    If a VR controller transform is not available, the sample falls back to the main camera direction for some calculations, but the intended experience is controller-driven.

    The top-level structure is:

    export class Spiderman {
    private bindTo: VX.Mod.JsComponentProxy;
    private character: VX.Entity.EntityCharacter | null;

    constructor(bindTo: VX.Mod.JsComponentProxy) {
    this.bindTo = bindTo;
    this.character = bindTo.GetComponent(
    puerts.$typeof(VX.Entity.EntityCharacter)
    ) as VX.Entity.EntityCharacter | null;

    this.bindTo.onUpdate = (dt) => this.onUpdate(dt);
    this.bindTo.onFixedUpdate = (dt) => this.onFixedUpdate(dt);
    }
    }

    In authoring, you configure the avatar through AvatarProxy. In runtime, the script interacts with the assembled EntityCharacter. That is the current pattern for advanced avatar logic in the toolkit.

    Add the avatar prefab to manifest.asset, then validate the mod:

    npm run lint:mod -- com.cydream.spiderman
    

    Testing checklist:

    • Both hands can acquire grapple targets.
    • Rope visuals appear and disappear correctly.
    • Reeling and ability pull affect the character as expected.
    • Continuous rope / movement sounds stop correctly when grapples are released.