Files
beyond/Assets/Scripts/Powers/FlaskManager.cs

185 lines
6.1 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using Invector.vCharacterController;
using TMPro;
// We don't need the Invector vActions namespace here anymore since we use your custom Respawner
namespace Beyond
{
public class FlaskManager : MonoBehaviour
{
[Header("Flask Settings")]
[SerializeField] private int maxFlaskCharges = 5;
[SerializeField] private int healAmount = 50;
[SerializeField] private float cooldownTime = 3.0f;
[Tooltip("Time into the animation when the health is actually applied")]
[SerializeField] private float healDelay = 1.0f;
[Tooltip("Total time the player is locked in place")]
[SerializeField] private float totalAnimationDuration = 2.0f;
[Header("Animation")]
[SerializeField] private string animatorStateName = "DrinkFlask";
[SerializeField] private float transitionDuration = 0.1f;
[Tooltip("Audio clip to play when drinking")]
[SerializeField] private AudioClip drinkSound;
[Header("UI References")]
[SerializeField] private Button uiButton;
[SerializeField] private Image radialIconImage;
[SerializeField] private TextMeshProUGUI countText;
private int currentCharges;
private float lastDrinkTime;
private bool isDrinking;
// Dependencies
private Player playerRef;
private void Start()
{
// 1. Get Player Instance
playerRef = Player.Instance;
if (playerRef == null)
{
Debug.LogError("FlaskManager: No Player Instance found!");
return;
}
// 2. Initialize charges
ResetFlasks();
// 3. Hook into YOUR custom Respawner
// The previous error was looking for Invector.vActions.Respawner
// We now look for Beyond.Respawner
var respawner = playerRef.GetComponent<Beyond.Respawner>();
if (respawner != null)
{
respawner.m_onRespawned.AddListener(ResetFlasks);
}
else
{
Debug.LogWarning("FlaskManager: No Beyond.Respawner found on Player. Flasks won't refill on death.");
}
// 4. Hook up UI Button
if (uiButton)
{
uiButton.onClick.AddListener(AttemptDrinkFlask);
}
}
private void OnDestroy()
{
if (playerRef != null)
{
var respawner = playerRef.GetComponent<Beyond.Respawner>();
if (respawner != null)
{
respawner.m_onRespawned.RemoveListener(ResetFlasks);
}
}
}
private void Update()
{
UpdateUI();
// Optional: Input for drinking (e.g. 'R')
if (Input.GetKeyDown(KeyCode.R))
{
AttemptDrinkFlask();
}
}
public void ResetFlasks()
{
currentCharges = maxFlaskCharges;
lastDrinkTime = -cooldownTime; // Ensure cooldown is ready immediately
isDrinking = false;
UpdateUI();
}
public void AttemptDrinkFlask()
{
// Validation
if (isDrinking) return;
if (currentCharges <= 0)
{
playerRef.PlayICantDoThatYet();
return;
}
float timeSinceLast = Time.time - lastDrinkTime;
if (timeSinceLast < cooldownTime) return;
StartCoroutine(DrinkRoutine());
}
private IEnumerator DrinkRoutine()
{
isDrinking = true;
lastDrinkTime = Time.time;
// Lock Input
playerRef.PlayerInput.SetLockAllInput(true);
// Stop movement
playerRef.ThirdPersonController.input = Vector2.zero;
// --- UNITY VERSION FIX ---
// If you are on Unity 6 (Preview/Beta), keep 'linearVelocity'.
// If you are on Unity 2022 LTS or older, change 'linearVelocity' to 'velocity'.
#if UNITY_6000_0_OR_NEWER
playerRef.ThirdPersonController._rigidbody.linearVelocity = Vector3.zero;
#else
playerRef.ThirdPersonController._rigidbody.velocity = Vector3.zero;
#endif
// Trigger Animation
if (playerRef.ThirdPersonController.animator)
{
playerRef.ThirdPersonController.animator.CrossFadeInFixedTime(animatorStateName, transitionDuration);
}
// Play Sound
if (drinkSound) playerRef.PlaySingleSound(drinkSound);
// Wait for heal moment
yield return new WaitForSeconds(healDelay);
// Apply Heal
currentCharges--;
// Accessing Invector controller health directly
playerRef.ThirdPersonController.AddHealth(healAmount);
// Wait remaining animation time
float remainingTime = totalAnimationDuration - healDelay;
if (remainingTime > 0) yield return new WaitForSeconds(remainingTime);
// Unlock Input
playerRef.PlayerInput.SetLockAllInput(false);
isDrinking = false;
}
private void UpdateUI()
{
if (countText) countText.text = currentCharges.ToString();
if (radialIconImage)
{
if (currentCharges == 0)
{
radialIconImage.fillAmount = 0;
}
else
{
float timeSinceLast = Time.time - lastDrinkTime;
float pct = Mathf.Clamp01(timeSinceLast / cooldownTime);
radialIconImage.fillAmount = pct;
}
}
}
}
}