using System.Collections;
using Unity.Netcode;
using UnityEngine;
namespace XRMultiplayer.MiniGames
{
///
/// A networked slingshot that shoots projectiles.
///
[RequireComponent(typeof(SlingshotVisualUpdater))]
public class Slingshot : MonoBehaviour
{
///
/// The projectile prefab to shoot from the slingshot.
///
[SerializeField] GameObject m_ProjectilePrefab;
///
/// The projectile proxy object to show when the bucket is held.
///
[SerializeField] GameObject m_ProjectileProxyObject;
///
/// The bucket interactable to use for setting the power of the slingshot.
///
[SerializeField] NetworkPhysicsInteractable m_BucketInteractable;
///
/// The time to wait before resetting the proxy object.
///
[SerializeField] float m_ResetTime = 1.0f;
///
/// The colliders to ignore when shooting the projectile.
///
[SerializeField] Collider[] m_CollidersToIgnore;
///
/// The slingshot visual updater to use for updating the slingshot visuals.
///
SlingshotVisualUpdater m_SlingshotVisualUpdater;
///
/// The slingshot mini game to use for handling the mini game logic.
///
MiniGame_Slingshot m_MiniGame;
///
/// Called when the script instance is being loaded.
///
private void Start()
{
TryGetComponent(out m_SlingshotVisualUpdater);
m_MiniGame = GetComponentInParent();
}
///
/// Called when the bucket's held state changes.
///
/// The previous held state.
/// The current held state.
public void OnBucketHeldChanged(bool current)
{
if (!current)
{
ShootProjectile();
}
else
{
if (m_BucketInteractable.IsOwner)
{
m_SlingshotVisualUpdater.trajectoryLineRenderer.enabled = true;
}
}
}
///
/// Shoots a projectile from the slingshot.
///
private void ShootProjectile()
{
m_ProjectileProxyObject.SetActive(false);
SlingshotProjectile projectile = Instantiate(m_ProjectilePrefab, m_BucketInteractable.transform.position, Quaternion.identity).GetComponent();
XRINetworkGameManager.Instance.GetPlayerByID(m_BucketInteractable.OwnerClientId, out XRINetworkPlayer player);
projectile.LaunchProjectile(m_SlingshotVisualUpdater.GetShotForce(), player.IsLocalPlayer, player.playerColor);
foreach (var collider in m_CollidersToIgnore)
{
Physics.IgnoreCollision(projectile.GetComponent(), collider);
}
if (m_BucketInteractable.IsOwner)
{
projectile.localPlayerHitTarget += OnLocalPlayerHitTarget;
m_SlingshotVisualUpdater.ResetBucketPosition();
ResetProxyObjectServerRpc();
m_SlingshotVisualUpdater.trajectoryLineRenderer.enabled = false;
}
}
///
/// Resets the proxy object on the server.
///
[ServerRpc(RequireOwnership = false)]
private void ResetProxyObjectServerRpc()
{
ResetProxyObjectClientRpc();
}
///
/// Resets the proxy object on the clients.
///
[ClientRpc]
private void ResetProxyObjectClientRpc()
{
StartCoroutine(ResetProxyAfterTime());
}
///
/// Resets the proxy object after a specified time.
///
/// An enumerator to control the coroutine.
private IEnumerator ResetProxyAfterTime()
{
yield return new WaitForSeconds(m_ResetTime);
m_ProjectileProxyObject.SetActive(true);
}
///
/// Called when the local player hits a target with the projectile.
///
/// The projectile that hit the target.
/// The value of the target hit.
private void OnLocalPlayerHitTarget(SlingshotProjectile projectile, int targetValue)
{
projectile.localPlayerHitTarget -= OnLocalPlayerHitTarget;
m_MiniGame.LocalPlayerHitTarget(targetValue);
}
}
}