using UdonSharp; using UnityEngine; using VRC.SDK3.Components; using VRC.SDKBase; [UdonBehaviourSyncMode(BehaviourSyncMode.NoVariableSync)] [DisallowMultipleComponent] [AddComponentMenu("Artyom Scripting System/Pickup Speed Limiter")] public class PickupSpeedLimiter : UdonSharpBehaviour { public float maxSpeed = 5.0f; // Maximum allowed speed for the pickup public bool debugSpeed; private VRC_Pickup pickup; // Reference to the VRC_Pickup component private Rigidbody rb; private bool synced; // Has VRCObjectSync: only its owner limits it void Start() { pickup = GetComponent(); rb = GetComponent(); synced = GetComponent() != null; if (pickup == null || rb == null) { Debug.LogError("[AUMSS] Pickup Speed Limiter: needs a VRC_Pickup and a Rigidbody on this GameObject."); enabled = false; } } // FixedUpdate: once per physics step, so no step runs over the limit void FixedUpdate() { if (pickup == null || rb == null) return; // Not set up (enabled = false only takes effect next frame) if (pickup.IsHeld) return; if (synced && !Networking.IsOwner(gameObject)) return; // Anyone else would fight the sync Vector3 velocity = rb.velocity; if (velocity.sqrMagnitude > maxSpeed * maxSpeed) { if (debugSpeed) Debug.LogWarning("[AUMSS] Pickup Speed Limiter: " + gameObject.name + " at " + velocity.magnitude.ToString() + ", limited to " + maxSpeed.ToString()); rb.velocity = velocity.normalized * maxSpeed; } } }