Weapons/ToolGun/ToolMode.SnapGrid.cs
public abstract partial class ToolMode
{
/// <summary>
/// When true (default), a SnapGrid overlay is shown on the hovered object surface.
/// Override to return false to opt out.
/// </summary>
public virtual bool UseSnapGrid => false;
/// <summary>
/// The active snap grid, updated every frame in <see cref="OnControl"/>.
/// Null when snap grid is disabled or the tool is inactive.
/// </summary>
protected SnapGrid SnapGrid { get; private set; }
private Vector3? _lockedSnapTarget;
private void DisableSnapGrid()
{
SnapGrid?.Destroy();
SnapGrid = null;
_lockedSnapTarget = null;
}
/// <summary>
/// While hovering an object, hold E to lock the camera aim onto the nearest snap corner.
/// </summary>
public virtual void OnCameraMove( Player player, ref Angles angles )
{
// Skip when the mode is absorbing mouse input for its own purposes (e.g. Weld rotation stage).
if ( AbsorbMouseInput || SnapGrid == null )
return;
if ( Input.Pressed( "use" ) )
_lockedSnapTarget = SnapGrid.LastSnapWorldPos;
if ( !Input.Down( "use" ) || _lockedSnapTarget == null )
return;
var eyePos = player.EyeTransform.Position;
var desiredAngles = Rotation.LookAt( _lockedSnapTarget.Value - eyePos ).Angles();
var currentAngles = player.Controller.EyeAngles;
angles = desiredAngles - currentAngles;
if ( Input.Released( "use" ) )
_lockedSnapTarget = null;
Input.Clear( "use" );
}
/// <summary>
/// Override to control which objects show the snap grid. Returns false for world and player geometry by default.
/// </summary>
protected virtual bool ShouldDisplaySnapGrid( GameObject go )
{
return !go.Tags.Has( "world" ) && !go.Tags.Has( "player" );
}
public virtual void OnControl()
{
DispatchActions();
if ( !UseSnapGrid ) return;
var preview = TraceSelect();
if ( preview.IsValid() && ShouldDisplaySnapGrid( preview.GameObject ) )
{
SnapGrid ??= new SnapGrid();
SnapGrid.Update( Scene.SceneWorld, preview.GameObject, preview.WorldPosition(), preview.WorldTransform().Rotation.Forward );
}
else
{
SnapGrid?.Hide();
}
}
}