| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- using UdonSharp;
- using UnityEngine;
- using VRC.SDKBase;
- using VRC.SDK3.Components;
- using System;
- [Obsolete("Component under review for further dubugging... Pardon our dust!")]
- [UdonBehaviourSyncMode(BehaviourSyncMode.NoVariableSync)]
- [DisallowMultipleComponent]
- [AddComponentMenu("Artyom Scripting System/Pickup Fizzler")]
- public class PickupFizzler : UdonSharpBehaviour
- {
- public AudioSource fizzlerSound; // Sound to play when a pickup is fizzled
- public AudioSource playerEnterSound; // Sound to play when a player enters the collider
- public int pickupLayer = 13; // Layer number for the pickup (VRChat's Pickup layer)
- public float fizzleDuration = 2.0f; // Duration for the fizzle effect
- public Material fizzleMaterial; // Material to apply during the fizzle effect
- private Material[][] originalMaterials;
- private VRC_Pickup pickup;
- private VRCObjectSync objectSync;
- private Renderer[] renderers;
- private Collider pickupCollider;
- private Rigidbody pickupRigidbody;
- private bool isFizzling = false;
- private float fizzleTimer = 0.0f;
- private Vector3 storedVelocity;
- private Vector3 storedAngularVelocity;
- private Transform soundParent; // Where the fizzle sound goes back to after following a pickup
- private Vector3 soundLocalPosition;
- private Quaternion soundLocalRotation;
- private void Start()
- {
- // Ensure the AudioSource is initially inactive
- if (fizzlerSound != null)
- {
- fizzlerSound.Stop();
- soundParent = fizzlerSound.transform.parent;
- soundLocalPosition = fizzlerSound.transform.localPosition;
- soundLocalRotation = fizzlerSound.transform.localRotation;
- }
- if (playerEnterSound != null)
- {
- playerEnterSound.Stop();
- }
- }
- private void OnTriggerEnter(Collider other)
- {
- // Check if the collider is on the pickup layer and not already fizzling
- if (other == null || other.gameObject.layer != pickupLayer || isFizzling) return;
- // Check if the collider has a VRC_Pickup component
- pickup = other.GetComponent<VRC_Pickup>();
- if (pickup == null) return;
- // Get the VRCObjectSync component
- objectSync = pickup.GetComponent<VRCObjectSync>();
- if (objectSync == null)
- {
- Debug.LogError("[AUMSS] Pickup Fizzler: no VRCObjectSync on " + pickup.gameObject.name + ", so it can't be respawned.");
- return;
- }
- // Get the pickup's collider and rigidbody
- pickupCollider = pickup.GetComponent<Collider>();
- pickupRigidbody = pickup.GetComponent<Rigidbody>();
- // Store the current velocity and angular velocity
- if (pickupRigidbody != null)
- {
- storedVelocity = pickupRigidbody.velocity;
- storedAngularVelocity = pickupRigidbody.angularVelocity;
- }
- // Swap every material for the fizzle material. sharedMaterials: .materials would copy them all each time
- renderers = pickup.GetComponentsInChildren<Renderer>();
- originalMaterials = new Material[renderers.Length][];
- for (int i = 0; i < renderers.Length; i++)
- {
- originalMaterials[i] = renderers[i].sharedMaterials;
- Material[] newMaterials = new Material[originalMaterials[i].Length];
- for (int j = 0; j < newMaterials.Length; j++)
- {
- newMaterials[j] = fizzleMaterial;
- }
- renderers[i].sharedMaterials = newMaterials;
- }
- // Play the fizzler sound
- if (fizzlerSound != null)
- {
- fizzlerSound.transform.SetParent(pickup.transform);
- fizzlerSound.transform.localPosition = Vector3.zero;
- fizzlerSound.Play();
- }
- // Disable the pickup's collider
- if (pickupCollider != null)
- {
- pickupCollider.enabled = false;
- }
- // Force the player to drop the pickup
- pickup.Drop();
- // Start the fizzling process
- isFizzling = true;
- fizzleTimer = fizzleDuration;
- }
- public override void OnPlayerTriggerEnter(VRCPlayerApi player)
- {
- if (playerEnterSound != null && player.isLocal)
- {
- playerEnterSound.Play();
- }
- }
- private void Update()
- {
- if (!isFizzling) return;
- if (!Utilities.IsValid(pickup))
- {
- // The pickup was destroyed mid-fizzle: put the sound back and wait for the next one
- ResetSound();
- isFizzling = false;
- return;
- }
- fizzleTimer -= Time.deltaTime;
- // Only the owner moves and respawns it; anyone else would fight the sync
- bool isOwner = Networking.IsOwner(pickup.gameObject);
- // Apply the stored velocity and angular velocity
- if (isOwner && pickupRigidbody != null)
- {
- pickupRigidbody.velocity = storedVelocity;
- pickupRigidbody.angularVelocity = storedAngularVelocity;
- }
- pickup.Drop();
- if (fizzleTimer <= 0.0f)
- {
- // Respawn the pickup using VRCObjectSync
- if (isOwner && objectSync != null)
- {
- objectSync.Respawn();
- }
- ResetSound();
- // Re-enable the pickup's collider
- if (pickupCollider != null)
- {
- pickupCollider.enabled = true;
- }
- // Reset the original materials
- for (int i = 0; i < renderers.Length; i++)
- {
- if (renderers[i] != null) renderers[i].sharedMaterials = originalMaterials[i];
- }
- isFizzling = false;
- }
- }
- private void ResetSound()
- {
- if (fizzlerSound == null) return;
- fizzlerSound.Stop();
- fizzlerSound.transform.SetParent(soundParent);
- fizzlerSound.transform.localPosition = soundLocalPosition;
- fizzlerSound.transform.localRotation = soundLocalRotation;
- }
- }
|