Tools/ModelTuner.razor

A Razor UI component for a model tuner panel in the NZombies project. It defines a pinned card UI with sliders for body parts (head to legs), shows driving count and flags, and has buttons to reset, print, and close.

File Access
@using Sandbox.UI;
@using SWB.Editor;
@attribute [StyleSheet("/Tools/ModelTuner.cs.scss")]
@inherits PanelComponent
@namespace NZombies

@*
    MODEL TUNER — one signed slider per body part, live on the bodies already on screen.

    Deliberately a pinned card rather than a fullscreen overlay: it is used WHILE looking at a
    character, so it must not be the thing you are looking at. Sits bottom-right, out of the lobby's
    left column and away from the preview stage in the middle.

    ⚠️ ORDERED HEAD TO FOOT, not by how often they are touched. A body is judged top to bottom and
    the list should read the same way, so the slider you want is where you would point at it.
*@

<root>
    <div class="card">
        <text class="title">Model tuner</text>
        <text class="sub">@Driving bod@(Driving == 1 ? "y" : "ies") on screen</text>

        <div class="rows">
            <text class="group">Head</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="head" Value:bind=@Head></SliderEntry>

            <text class="group">Neck</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="neck" Value:bind=@Neck></SliderEntry>

            <text class="group">Chest</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="chest" Value:bind=@Chest></SliderEntry>

            <text class="group">Arms</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="arms" Value:bind=@Arms></SliderEntry>

            <text class="group">Hands</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="hands" Value:bind=@Hands></SliderEntry>

            <text class="group">Waist</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="waist" Value:bind=@Waist></SliderEntry>

            <text class="group">Hips</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="hips" Value:bind=@Hips></SliderEntry>

            <text class="group">Legs</text>
            <SliderEntry min="-0.06" max="0.06" step="0.001" name="legs" Value:bind=@Legs></SliderEntry>
        </div>

        @* The same string PRINT writes, so what you read is what you paste. *@
        <text class="flags">@Flags</text>

        <div class="buttons">
            @* ⚠️ NO SEPARATE "BAKED" BUTTON. Zero IS baked — every value here is an offset on
               top of whatever the model was built with, so a second button claiming to restore
               the bake would have to mean the same thing or be lying. *@
            <button class="reset" @onclick=@OnZero>AS BAKED</button>
            <button class="print" @onclick=@OnPrint>PRINT</button>
            <button class="close" @onclick=@OnClose>CLOSE</button>
        </div>

        <text class="hint">Offsets from the baked model, as fractions of body height; negative raises. Hands stack on arms.</text>
    </div>
</root>