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(); 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(); 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; } } } } }