PickupFizzler.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using UdonSharp;
  2. using UnityEngine;
  3. using VRC.SDKBase;
  4. using VRC.SDK3.Components;
  5. using VRC.Udon;
  6. using System;
  7. [Obsolete("Component under review for further dubugging... Pardon our dust!")]
  8. [DisallowMultipleComponent]
  9. [AddComponentMenu("Artyom Scripting System/Pickup Fizzler")]
  10. public class PickupFizzler : UdonSharpBehaviour
  11. {
  12. public AudioSource fizzlerSound; // Sound to play when a pickup is fizzled
  13. public AudioSource playerEnterSound; // Sound to play when a player enters the collider
  14. public int fizzlerLayer = 8; // Layer number for the fizzler
  15. public int pickupLayer = 9; // Layer number for the pickup
  16. public float fizzleDuration = 2.0f; // Duration for the fizzle effect
  17. public Material fizzleMaterial; // Material to apply during the fizzle effect
  18. private Material[][] originalMaterials;
  19. private VRC_Pickup pickup;
  20. private VRCObjectSync objectSync;
  21. private Renderer[] renderers;
  22. private Collider pickupCollider;
  23. private Rigidbody pickupRigidbody;
  24. private bool isFizzling = false;
  25. private float fizzleTimer = 0.0f;
  26. private Vector3 storedVelocity;
  27. private Vector3 storedAngularVelocity;
  28. private void Start()
  29. {
  30. // Ensure the AudioSource is initially inactive
  31. if (fizzlerSound != null)
  32. {
  33. fizzlerSound.Stop();
  34. }
  35. if (playerEnterSound != null)
  36. {
  37. playerEnterSound.Stop();
  38. }
  39. }
  40. private void OnTriggerEnter(Collider other)
  41. {
  42. // Check if the collider is on the pickup layer and not already fizzling
  43. if (other.gameObject.layer == pickupLayer && !isFizzling)
  44. {
  45. // Check if the collider has a VRC_Pickup component
  46. pickup = other.GetComponent<VRC_Pickup>();
  47. if (pickup != null)
  48. {
  49. // Get the VRCObjectSync component
  50. objectSync = pickup.GetComponent<VRCObjectSync>();
  51. if (objectSync == null)
  52. {
  53. Debug.LogError("No VRCObjectSync component found on the pickup object.");
  54. return;
  55. }
  56. UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
  57. behaviour.DisableInteractive = true;
  58. // Get the pickup's collider and rigidbody
  59. pickupCollider = pickup.GetComponent<Collider>();
  60. pickupRigidbody = pickup.GetComponent<Rigidbody>();
  61. // Store the current velocity and angular velocity
  62. if (pickupRigidbody != null)
  63. {
  64. storedVelocity = pickupRigidbody.velocity;
  65. storedAngularVelocity = pickupRigidbody.angularVelocity;
  66. }
  67. // Get the renderers and materials of the pickup
  68. renderers = pickup.GetComponentsInChildren<Renderer>();
  69. originalMaterials = new Material[renderers.Length][];
  70. for (int i = 0; i < renderers.Length; i++)
  71. {
  72. originalMaterials[i] = renderers[i].materials;
  73. Material[] newMaterials = new Material[renderers[i].materials.Length];
  74. for (int j = 0; j < newMaterials.Length; j++)
  75. {
  76. newMaterials[j] = fizzleMaterial;
  77. }
  78. renderers[i].materials = newMaterials;
  79. }
  80. // Play the fizzler sound
  81. if (fizzlerSound != null)
  82. {
  83. fizzlerSound.transform.SetParent(pickup.transform);
  84. fizzlerSound.transform.localPosition = Vector3.zero;
  85. fizzlerSound.Play();
  86. }
  87. // Disable the pickup's collider
  88. if (pickupCollider != null)
  89. {
  90. pickupCollider.enabled = false;
  91. }
  92. // Force the player to drop the pickup
  93. if (Networking.LocalPlayer != null)
  94. {
  95. pickup.Drop(Networking.LocalPlayer);
  96. }
  97. // Start the fizzling process
  98. isFizzling = true;
  99. fizzleTimer = fizzleDuration;
  100. }
  101. }
  102. }
  103. public override void OnPlayerTriggerEnter(VRCPlayerApi player)
  104. {
  105. if (playerEnterSound != null && player.isLocal)
  106. {
  107. playerEnterSound.Play();
  108. }
  109. }
  110. private void Update()
  111. {
  112. if (isFizzling)
  113. {
  114. fizzleTimer -= Time.deltaTime;
  115. // Apply the stored velocity and angular velocity
  116. if (pickupRigidbody != null)
  117. {
  118. pickupRigidbody.velocity = storedVelocity;
  119. pickupRigidbody.angularVelocity = storedAngularVelocity;
  120. }
  121. if (Networking.LocalPlayer != null)
  122. {
  123. pickup.Drop(Networking.LocalPlayer);
  124. }
  125. if (fizzleTimer <= 0.0f)
  126. {
  127. // Respawn the pickup using VRCObjectSync
  128. if (objectSync != null)
  129. {
  130. objectSync.Respawn();
  131. }
  132. // Stop and detach the sound
  133. if (fizzlerSound != null)
  134. {
  135. fizzlerSound.Stop();
  136. fizzlerSound.transform.SetParent(null);
  137. }
  138. // Re-enable the pickup's collider
  139. if (pickupCollider != null)
  140. {
  141. pickupCollider.enabled = true;
  142. }
  143. // Reset the original materials
  144. for (int i = 0; i < renderers.Length; i++)
  145. {
  146. renderers[i].materials = originalMaterials[i];
  147. }
  148. isFizzling = false;
  149. UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
  150. behaviour.DisableInteractive = false;
  151. }
  152. }
  153. }
  154. }