terminalCode Example

Physgun Grab State with Permission Checks

calendar_today May 3, 2026 schedule ~1 min read person patrickjr verified 50

Physgun Grab State Pattern

Implementation pattern for physgun object grabbing with ownership checks and IPhysgunEvent permissions.

CSHARP
public partial class Physgun : BaseCarryable
{
    [Sync] public GrabState _state { get; set; } = default;

    public struct GrabState
    {
        public bool Active { get; set; }
        public bool Pulling { get; set; }
        public GameObject GameObject { get; set; }
        public Vector3 LocalOffset { get; set; }
        public Vector3 LocalNormal { get; set; }
        public Rotation GrabOffset { get; set; }
        public float GrabDistance { get; set; }

        public readonly Vector3 EndPoint => GameObject.WorldTransform.PointToWorld(LocalOffset);
        public readonly bool IsValid() => GameObject.IsValid();
        public readonly Rigidbody Body => GameObject?.GetComponent<Rigidbody>();
    }

    bool FindGrabbedBody(out GrabState state, Transform aim, float yaw, bool isPulling)
    {
        state = default;

        var tr = Scene.Trace.Ray(aim.Position, aim.Position + aim.Forward * Range)
            .IgnoreGameObjectHierarchy(GameObject.Root)
            .Run();

        // Check IPhysgunEvent permission
        var grabEvent = new IPhysgunEvent.GrabEvent { Grabber = Network.Owner };
        go.Root.RunEvent<IPhysgunEvent>(x => x.OnPhysgunGrab(grabEvent));
        if (grabEvent.Cancelled) return false;

        // Verify body ownership
        if (state.Body.IsProxy) return false;
        if (!state.Body.MotionEnabled) return false;

        return true;
    }

    [Rpc.Broadcast]
    void Freeze(Rigidbody body)
    {
        if (!body.IsValid()) return;
        body.MotionEnabled = false;
    }

    void Launch(Rigidbody body, Vector3 force)
    {
        body.MotionEnabled = true;
        body.ApplyImpulse(force);
    }
}

Key Features

  • Sync'd GrabState struct - Networked grab state
  • IPhysgunEvent permission checks - Ownable integration
  • IsProxy validation - Only move owned bodies
  • Freeze/Launch RPCs - Broadcast physics state changes
Was this helpful?