using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.Interactables;
namespace XRMultiplayer.MiniGames
{
///
/// Represents a mini-game called "Whack-A-Pig" where the player needs to hit pigs with a hammer.
///
public class MiniGame_Whack : MiniGameBase
{
///
/// The time to wait before resetting the hammer's position.
///
[SerializeField] float m_HammerResetTime = .25f;
///
/// The interactable objects to use for the mini-game.
///
readonly Dictionary m_InteractablePoses = new();
///
/// The networked gameplay to use for handling the networked gameplay logic.
///
NetworkedWhackAPig m_NetworkedGameplay;
///
/// The current score of the mini-game.
///
int m_CurrentScore = 0;
///
public override void Start()
{
base.Start();
TryGetComponent(out m_NetworkedGameplay);
foreach (var interactable in m_GameInteractables)
{
if (!m_InteractablePoses.ContainsKey(interactable))
{
m_InteractablePoses.Add(interactable, new Pose(interactable.transform.position, interactable.transform.rotation));
interactable.selectExited.AddListener(HammerDropped);
}
}
}
///
void OnDestroy()
{
foreach (var kvp in m_InteractablePoses)
{
kvp.Key.selectExited.RemoveListener(HammerDropped);
}
}
///
/// Sets up the game by resetting the current score.
///
public override void SetupGame()
{
base.SetupGame();
m_CurrentScore = 0;
m_NetworkedGameplay.ResetGame();
}
///
/// Starts the game by spawning pigs if the player is the server.
///
public override void StartGame()
{
base.StartGame();
if (m_NetworkedGameplay.IsServer)
{
m_NetworkedGameplay.SpawnProcessServer();
}
}
///
/// Finishes the game and ends the networked gameplay.
///
/// Whether to submit the score or not.
public override void FinishGame(bool submitScore = true)
{
base.FinishGame(submitScore);
m_NetworkedGameplay.EndGame();
}
///
/// Called when the hammer is dropped on an interactable object.
///
/// The interaction event arguments.
void HammerDropped(BaseInteractionEventArgs args)
{
XRBaseInteractable interactable = (XRBaseInteractable)args.interactableObject;
if (m_InteractablePoses.ContainsKey(interactable))
{
StartCoroutine(DropHammerAfterTimeRoutine(interactable));
}
}
///
/// Coroutine that drops the hammer after a specified time and resets the interactable's position.
///
/// The interactable object.
IEnumerator DropHammerAfterTimeRoutine(XRBaseInteractable interactable)
{
yield return new WaitForSeconds(m_HammerResetTime);
if (!interactable.isSelected)
{
Rigidbody body = interactable.GetComponent();
bool wasKinematic = body.isKinematic;
body.isKinematic = true;
interactable.transform.SetPositionAndRotation(m_InteractablePoses[interactable].position, m_InteractablePoses[interactable].rotation);
yield return new WaitForFixedUpdate();
body.isKinematic = wasKinematic;
foreach (var collider in interactable.colliders)
{
collider.enabled = true;
}
}
}
///
/// Updates the local player's score and submits it to the server.
///
/// The point value to add to the score.
public void LocalPlayerScored(int pointValue)
{
m_CurrentScore += pointValue;
if (m_CurrentScore < 0) m_CurrentScore = 0;
m_MiniGameManager.SubmitScoreServerRpc(m_CurrentScore, XRINetworkPlayer.LocalPlayer.OwnerClientId);
}
}
}