| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- using UdonSharp;
- using UnityEngine;
- using VRC.SDK3.Components;
- using VRC.SDKBase;
- [UdonBehaviourSyncMode(BehaviourSyncMode.NoVariableSync)]
- [DisallowMultipleComponent]
- [AddComponentMenu("Artyom Scripting System/Pickup Following Mover Fix")]
- public class PickupMovementFixer : UdonSharpBehaviour
- {
- public GameObject targetObject; // The object to follow
- private int pickupLayer = 13; // The layer assigned to pickup objects
- private Collider triggerCollider;
- private Vector3 previousTargetPosition;
- private Vector3 targetVelocity;
- private bool carrying; // While the target moves, and for one frame after it stops
- private bool ready;
- private void Start()
- {
- triggerCollider = GetComponent<Collider>();
- if (triggerCollider == null || !triggerCollider.isTrigger)
- {
- Debug.LogError("[AUMSS] Pickup Following Mover Fix: Collider must be set as a trigger.");
- }
- if (targetObject == null)
- {
- Debug.LogError("[AUMSS] Pickup Following Mover Fix: Target Object isn't assigned.");
- enabled = false;
- return;
- }
- previousTargetPosition = targetObject.transform.position;
- ready = true;
- }
- // LateUpdate runs after Update scripts and Animators have moved the target this frame,
- // so the movement measured here matches this frame's deltaTime
- private void LateUpdate()
- {
- if (!ready) return; // Not set up (enabled = false only takes effect next frame)
- Vector3 currentTargetPosition = targetObject.transform.position;
- Vector3 newVelocity = (currentTargetPosition - previousTargetPosition) / Time.deltaTime;
- previousTargetPosition = currentTargetPosition;
- // A still target leaves the pickups to their own physics, so they can fall and slide.
- // The frame it stops still applies (zero), so the pickups stop with it instead of sliding off.
- bool moving = newVelocity.sqrMagnitude > 0.0001f;
- carrying = moving || targetVelocity.sqrMagnitude > 0.0001f;
- targetVelocity = newVelocity;
- }
- private void OnTriggerEnter(Collider other)
- {
- Carry(other);
- }
- private void OnTriggerStay(Collider other)
- {
- Carry(other);
- }
- private void Carry(Collider other)
- {
- if (!ready || !carrying || other == null || other.gameObject.layer != pickupLayer) return;
- VRC_Pickup pickup = other.GetComponent<VRC_Pickup>();
- if (pickup == null || pickup.IsHeld) return;
- // A synced pickup is moved by its owner; anyone else setting its velocity just fights the sync
- if (other.GetComponent<VRCObjectSync>() != null && !Networking.IsOwner(other.gameObject)) return;
- Rigidbody pickupRigidbody = other.GetComponent<Rigidbody>();
- if (pickupRigidbody != null)
- {
- pickupRigidbody.velocity = targetVelocity;
- }
- }
- }
|