Table of Contents

Class ShieldVolume

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

The dimensions of a character's shield: a real volume standing in front of them, authored on the buff that raises it.

[Serializable]
public class ShieldVolume
Inheritance
ShieldVolume
Inherited Members

Remarks

Defined in the character's LOCAL space, and that is the whole trick. A shield described in world space would have to be moved, turned and — critically — REWOUND alongside the body it protects, because hits are resolved against where the attacker saw their target. Ability hits are dispatched after the rewind scope has closed (AbilityObject.ResolveSweptHits), so a world-space volume read at that moment would sit where the defender is NOW while the impact point it is being compared against came from where the defender WAS — metres apart at 200 ms, and a shield that blocks phantom hits and misses real ones. A local-space volume compared against a local-space impact point captured inside the scope has no such disagreement to have: the body and its shield moved together, so the relationship between them is the same in both worlds.

It replaces an angle with a shape. A facing cone is measured from the character's origin, so it says nothing about height or reach: a tower shield and a buckler protect identical arcs, and a shot at ankle height is "in front" of a shield held at the chest. Real dimensions make the two different objects, which is what a player expects to be true.

Both sides of the same shape. Contains(Vector3) answers "did this hit meet the shield" for an incoming projectile, and the world-space accessors below describe the identical volume to ShieldInterceptAction's overlap query. One authored shape, tested from whichever side is asking, so the thing that stops a projectile and the thing that sweeps one out of the air can never be different sizes.

Fields

Height

Total height, for Capsule. Floored at a full diameter.

[Tooltip("Total height for the Capsule shape. Values below a full diameter are treated as a sphere.")]
[Min(0)]
public float Height

Field Value

float

LocalCenter

Where the volume sits relative to the character, in the character's own space.

[Tooltip("Offset from the character, in the character's own space. +Z forward, +Y up.")]
public Vector3 LocalCenter

Field Value

Vector3

Remarks

+Z is forward, +Y is up. The default stands the shield at chest height, most of a metre in front — far enough out that a projectile meets it before the body, which is what makes the impact read as a block rather than as a hit that happened to do nothing.

Radius

Radius, for Sphere and Capsule.

[Tooltip("Radius for Sphere and Capsule shapes.")]
[Min(0)]
public float Radius

Field Value

float

Shape

The shape this shield occupies. None disables it.

[Tooltip("Shape of the shield. None disables the physical volume and leaves only the facing arc.")]
public ShieldShape Shape

Field Value

ShieldShape

Size

Full extents, for Box.

[Tooltip("Full width, height and depth for the Box shape.")]
public Vector3 Size

Field Value

Vector3

Remarks

Full size rather than half extents, because that is the number a designer measures off the shield model — the halving happens once, here, rather than in every author's head.

Properties

IsActive

True when this volume can stop anything at all.

public bool IsActive { get; }

Property Value

bool

Methods

Contains(Vector3)

True when localPoint — an impact point expressed in the character's own space — lies inside this shield.

public bool Contains(Vector3 localPoint)

Parameters

localPoint Vector3

Impact point in the character's local space.

Returns

bool

Remarks

Pure, and deliberately so: no transform is read, no physics is queried, and the answer depends on nothing but the two arguments. That is what lets the server and the attacker's own client reach the same verdict on the same hit without either of them having to agree about where anybody is standing.

Uses SQUARED distances throughout. The comparison is against an authored radius, so the square root buys nothing but rounding.

Describe()

A short designer-facing description, for tooltips.

public string Describe()

Returns

string

GetWorldBoundingRadius(Transform)

The radius of a sphere that fully contains this volume, in world units.

public float GetWorldBoundingRadius(Transform characterTransform)

Parameters

characterTransform Transform

Returns

float

Remarks

The broadphase bound ShieldInterceptAction queries with before testing candidates exactly through Contains(Vector3). Querying a sphere and then narrowing means the authored shape is honoured by ONE implementation — the local-space one that the gate also uses — instead of the physics overlap approximating it a second way.

GetWorldCenter(Transform)

Where this volume's centre sits in the world, for a character at characterTransform.

public Vector3 GetWorldCenter(Transform characterTransform)

Parameters

characterTransform Transform

Returns

Vector3

Remarks

For the outward-looking query only — ShieldInterceptAction, which sweeps the volume for objects in flight. The inward-looking test uses Contains(Vector3) and never needs a world position at all.