using System.Collections; using System.Collections.Generic; using System.Data; using TMPro; using UnityEngine; using UnityEngine.UI; public class WorldUIObserver : MonoBehaviour, IObserver { [SerializeField] private GameObject damageDisplayPrefab; [SerializeField] private NotificationType notificationType; [SerializeField] private float barSpeed = 0.5f; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } private void UpdateHealthBar(int newHealth, Image healthBar) { // Start coroutine for smooth health bar animation StartCoroutine(SmoothHealthBarUpdate(newHealth, healthBar)); } // Coroutine for smooth health bar animation private IEnumerator SmoothHealthBarUpdate(int newHealth, Image healthBar) { Debug.Log("Health Bar Image: " + healthBar.name); float targetFillAmount = (float)newHealth / 100; // Normalize new health value (0 to 1) while (Mathf.Abs(healthBar.fillAmount - targetFillAmount) > 0.01f) { healthBar.fillAmount = Mathf.Lerp(healthBar.fillAmount, targetFillAmount, Time.deltaTime * barSpeed); yield return null; } // Ensure the fill amount is set exactly to the target at the end healthBar.fillAmount = targetFillAmount; } //Notify the observer public void OnNotify(ObserverNotification notification) { //Check if the notification is compatible with the observer if (notification.NotificationType == notificationType) { // Check if the notification contains the NPCController and DamageAmount if (notification.ContainsKey("NPCController") && notification.ContainsKey("DamageAmount")) { //Access the necessary provided data of Observer notification NPCController controller = notification.GetData<NPCController>("NPCController"); int amount = notification.GetData<int>("DamageAmount"); //Calculate the fill amount //float fillAmount = (float)controller.CurrentHealth() / controller.MaxHealth; //Checks if the controller has a health bar if (controller.HealthBarImage != null) { UpdateHealthBar(controller.CurrentHealth(), controller.HealthBarImage); //Display damage when hit Vector2 targetPosition = new Vector2(controller.transform.position.x, controller.transform.position.y); GameObject obj = Instantiate(damageDisplayPrefab, targetPosition, Quaternion.identity, transform); TextMeshProUGUI tmp = obj.GetComponentInChildren<TextMeshProUGUI>(); tmp.text = "-" + amount; // Display the damage amount StartCoroutine(DestroyUIObject(obj, 0.7f)); } } } } //Destroy UI GameObjects private static IEnumerator DestroyUIObject(GameObject obj, float time) { while (true) { yield return new WaitForSeconds(time); Destroy(obj); break; } } }