|
|
@@ -1,19 +1,17 @@
|
|
|
-using UdonSharp;
|
|
|
+using UdonSharp;
|
|
|
using UnityEngine;
|
|
|
using VRC.SDKBase;
|
|
|
using VRC.SDK3.Components;
|
|
|
-using VRC.Udon;
|
|
|
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 fizzlerLayer = 8; // Layer number for the fizzler
|
|
|
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
|
|
|
@@ -27,6 +25,9 @@ public class PickupFizzler : UdonSharpBehaviour
|
|
|
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()
|
|
|
{
|
|
|
@@ -34,6 +35,9 @@ public class PickupFizzler : UdonSharpBehaviour
|
|
|
if (fizzlerSound != null)
|
|
|
{
|
|
|
fizzlerSound.Stop();
|
|
|
+ soundParent = fizzlerSound.transform.parent;
|
|
|
+ soundLocalPosition = fizzlerSound.transform.localPosition;
|
|
|
+ soundLocalRotation = fizzlerSound.transform.localRotation;
|
|
|
}
|
|
|
|
|
|
if (playerEnterSound != null)
|
|
|
@@ -45,72 +49,65 @@ public class PickupFizzler : UdonSharpBehaviour
|
|
|
private void OnTriggerEnter(Collider other)
|
|
|
{
|
|
|
// Check if the collider is on the pickup layer and not already fizzling
|
|
|
- if (other.gameObject.layer == pickupLayer && !isFizzling)
|
|
|
+ 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++)
|
|
|
{
|
|
|
- // Check if the collider has a VRC_Pickup component
|
|
|
- pickup = other.GetComponent<VRC_Pickup>();
|
|
|
- if (pickup != null)
|
|
|
+ originalMaterials[i] = renderers[i].sharedMaterials;
|
|
|
+ Material[] newMaterials = new Material[originalMaterials[i].Length];
|
|
|
+ for (int j = 0; j < newMaterials.Length; j++)
|
|
|
{
|
|
|
- // Get the VRCObjectSync component
|
|
|
- objectSync = pickup.GetComponent<VRCObjectSync>();
|
|
|
- if (objectSync == null)
|
|
|
- {
|
|
|
- Debug.LogError("No VRCObjectSync component found on the pickup object.");
|
|
|
- return;
|
|
|
- }
|
|
|
- UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
|
|
|
- behaviour.DisableInteractive = true;
|
|
|
-
|
|
|
- // 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;
|
|
|
- }
|
|
|
-
|
|
|
- // Get the renderers and materials of the pickup
|
|
|
- renderers = pickup.GetComponentsInChildren<Renderer>();
|
|
|
- originalMaterials = new Material[renderers.Length][];
|
|
|
- for (int i = 0; i < renderers.Length; i++)
|
|
|
- {
|
|
|
- originalMaterials[i] = renderers[i].materials;
|
|
|
- Material[] newMaterials = new Material[renderers[i].materials.Length];
|
|
|
- for (int j = 0; j < newMaterials.Length; j++)
|
|
|
- {
|
|
|
- newMaterials[j] = fizzleMaterial;
|
|
|
- }
|
|
|
- renderers[i].materials = 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
|
|
|
- if (Networking.LocalPlayer != null)
|
|
|
- {
|
|
|
- pickup.Drop(Networking.LocalPlayer);
|
|
|
- }
|
|
|
-
|
|
|
- // Start the fizzling process
|
|
|
- isFizzling = true;
|
|
|
- fizzleTimer = fizzleDuration;
|
|
|
+ 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)
|
|
|
@@ -123,52 +120,60 @@ public class PickupFizzler : UdonSharpBehaviour
|
|
|
|
|
|
private void Update()
|
|
|
{
|
|
|
- if (isFizzling)
|
|
|
+ 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)
|
|
|
{
|
|
|
- fizzleTimer -= Time.deltaTime;
|
|
|
+ pickupRigidbody.velocity = storedVelocity;
|
|
|
+ pickupRigidbody.angularVelocity = storedAngularVelocity;
|
|
|
+ }
|
|
|
+ pickup.Drop();
|
|
|
|
|
|
- // Apply the stored velocity and angular velocity
|
|
|
- if (pickupRigidbody != null)
|
|
|
+ if (fizzleTimer <= 0.0f)
|
|
|
+ {
|
|
|
+ // Respawn the pickup using VRCObjectSync
|
|
|
+ if (isOwner && objectSync != null)
|
|
|
{
|
|
|
- pickupRigidbody.velocity = storedVelocity;
|
|
|
- pickupRigidbody.angularVelocity = storedAngularVelocity;
|
|
|
+ objectSync.Respawn();
|
|
|
}
|
|
|
- if (Networking.LocalPlayer != null)
|
|
|
+
|
|
|
+ ResetSound();
|
|
|
+
|
|
|
+ // Re-enable the pickup's collider
|
|
|
+ if (pickupCollider != null)
|
|
|
{
|
|
|
- pickup.Drop(Networking.LocalPlayer);
|
|
|
+ pickupCollider.enabled = true;
|
|
|
}
|
|
|
|
|
|
- if (fizzleTimer <= 0.0f)
|
|
|
+ // Reset the original materials
|
|
|
+ for (int i = 0; i < renderers.Length; i++)
|
|
|
{
|
|
|
- // Respawn the pickup using VRCObjectSync
|
|
|
- if (objectSync != null)
|
|
|
- {
|
|
|
- objectSync.Respawn();
|
|
|
- }
|
|
|
-
|
|
|
- // Stop and detach the sound
|
|
|
- if (fizzlerSound != null)
|
|
|
- {
|
|
|
- fizzlerSound.Stop();
|
|
|
- fizzlerSound.transform.SetParent(null);
|
|
|
- }
|
|
|
-
|
|
|
- // Re-enable the pickup's collider
|
|
|
- if (pickupCollider != null)
|
|
|
- {
|
|
|
- pickupCollider.enabled = true;
|
|
|
- }
|
|
|
-
|
|
|
- // Reset the original materials
|
|
|
- for (int i = 0; i < renderers.Length; i++)
|
|
|
- {
|
|
|
- renderers[i].materials = originalMaterials[i];
|
|
|
- }
|
|
|
-
|
|
|
- isFizzling = false;
|
|
|
- UdonBehaviour behaviour = (UdonBehaviour)GetComponent(typeof(UdonBehaviour));
|
|
|
- behaviour.DisableInteractive = false;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|