terminalCode Example
Physgun Grab State with Permission Checks
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?