Forum begins after the advertisement:


[part 8] heart shards dont update

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [part 8] heart shards dont update

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #12711
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    So unlockable items work fine and the heart shards are picked up and dissapear but…. they dont increase my health when 4 are picked up and the canvas that appears doesnt show the heart filling up animation – it defaults to whatever i already have the heart fill set to in the prefab. When picking up a heart shard – the heart shard counter will increase so ik its working somehow

    the video doesnt go over all values you are meant to add to the insepctor – maybe its that issue player: health – 0(sets to 5 when played) maxhealth – 5 totalMaxHealth – 10

    increase max Health canvas: fill – fill image under the canvas – ive set its fill amount to 1(ive tried other values but nothing changes) target fill amount – 0.25 lerp duration – 1.5 initial fill amount – 0

    ive changed these values tons and nothing seems to change it so i thinks its a script error but i cant seem to pinpoint it

    for my heart shards script – all debug logs play except for “fill amoont” and “maxHealthIncrease”

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class HeartShards : MonoBehaviour
    {
        public Image Fill;
    
        public float targetFillAmount;
        public float LerpDuration = 1.5f;
        public float initialFillAmount;
        // Start is called before the first frame update
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        public IEnumerator LerpFill()
        {
            float elapsedTime = 0f;
    
            while (elapsedTime < LerpDuration)
            {
                Debug.Log("filled?");
                elapsedTime += Time.deltaTime;
                float t = Mathf.Clamp01(elapsedTime / LerpDuration);
                Debug.Log("filled1");
                float lerpedFillAmount = Mathf.Lerp(initialFillAmount, targetFillAmount, t);
                Fill.fillAmount = lerpedFillAmount;
                Debug.Log("filled2");
                yield return null;
    
            }
    
            Fill.fillAmount = targetFillAmount;
            Debug.Log("fillamoont?");
    
            Fill.fillAmount = targetFillAmount;
            Debug.Log("fillamoont?");
    
            if (Fill.fillAmount == 1)
            {
                PlayerController.Instance.maxHealth++;
                Debug.Log("max health increase");
                PlayerController.Instance.onHealthChangedCallBack();
                PlayerController.Instance.heartShards = 0;
            }
        }
    }

    all debugs logs play in my increase MaxHealth script

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class IncreaseMaxHealth : MonoBehaviour
    {
        [SerializeField] GameObject particles;
        [SerializeField] GameObject canvasUI;
    
        [SerializeField] HeartShards heartShards;
        bool used;
        // Start is called before the first frame update
        void Start()
        {
            if (PlayerController.Instance.maxHealth >= PlayerController.Instance.maxTotalHealth)
            {
                Destroy(gameObject);
            }
        }
    
        private void OnTriggerEnter2D(Collider2D _collision)
        {
            if (_collision.CompareTag("Player") && !used)
            {
    
                used = true;
                StartCoroutine(ShowUI());
    
            }
        }
    
        IEnumerator ShowUI()
        {
            GameObject _particles = Instantiate(particles, transform.position, Quaternion.identity);
            Destroy(_particles, 0.5f);
            yield return new WaitForSeconds(0.5f);
    
            canvasUI.SetActive(true);
            heartShards.initialFillAmount = PlayerController.Instance.heartShards * 0.25f;
            PlayerController.Instance.heartShards++;
            heartShards.targetFillAmount = PlayerController.Instance.heartShards * 0.25f;
            Debug.Log("heartshards");
    
            yield return new WaitForSeconds(2.5f);
    
            StartCoroutine(heartShards.LerpFill());
            Debug.Log("lerpy fill");
            SaveData.Instance.SavePlayerData();
            canvasUI.SetActive(false);
            Destroy(gameObject);
        }
    }
    using UnityEngine;
    using UnityEngine.UI;
    
    public class HeartController : MonoBehaviour
    {
        private GameObject[] heartContainers;
        private Image[] heartFills;
        public Transform heartsParent;
        public GameObject heartContainerPrefab;
        // Start is called before the first frame update
    
        void Start()
        {
    
                heartContainers = new GameObject[PlayerController.Instance.maxTotalHealth];
                heartFills = new Image[PlayerController.Instance.maxTotalHealth];
    
                PlayerController.Instance.onHealthChangedCallBack += UpdateHeartsHUD;
                InstantiateHeartContainers();
                UpdateHeartsHUD();
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
        void SetHeartContainers()
        {
    
                for (int i = 0; i < heartContainers.Length; i++)
                {
                    if (i < PlayerController.Instance.maxHealth)
                    {
                        heartContainers[i].SetActive(true);
                    }
                    else
                    {
                        heartContainers[i].SetActive(false);
                    }
                }
    
    
        }
        void SetFilledHearts()
        {
            for (int i = 0; i < heartFills.Length; i++)
            {
                if (i < PlayerController.Instance.health)
                {
                    heartFills[i].fillAmount = 1;
                }
                else
                {
                    heartFills[i].fillAmount = 0;
                }
            }
        }
        void InstantiateHeartContainers()
        {
            for (int i = 0; i < PlayerController.Instance.maxTotalHealth; i++)
            {
                GameObject temp = Instantiate(heartContainerPrefab);
                temp.transform.SetParent(heartsParent, false);
                heartContainers[i] = temp;
                heartFills[i] = temp.transform.Find("HeartFill").GetComponent<Image>();
            }
        }
        void UpdateHeartsHUD()
        {
    
                SetHeartContainers();
                SetFilledHearts();
        }
    }
    #12712
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Can’t help you much here. Check your Inspector to see if everything is referenced, or if there are duplicate / misreferenced GameObjects.

    #12714
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    The video didn’t properly mention all values that are to be assigned in the inspector – these are the ones ive changed – are there any more things i need to change?

    View post on imgur.com
    #12715
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    i think it might be a code error as my max health won’t increase when collecting 4 heart shards? ive checked the vied a few times and cant find a difference?

    #12717
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    now my hearts increase – seems like an eror in the video – however the canvas animation doesnt show the heart filling up

    my changes to the IEnumeraaotr LerpFill()

    
        public IEnumerator LerpFill()
        {
            float elapsedTime = 0f;
    
            while (elapsedTime < LerpDuration)
            {
                Debug.Log("filled?");
                elapsedTime += Time.deltaTime;
                float t = Mathf.Clamp01(elapsedTime / LerpDuration);
                Debug.Log("filled1");
    
                float lerpedFillAmount = Mathf.Lerp(initialFillAmount, targetFillAmount, t);
                fill.fillAmount = lerpedFillAmount;
                Debug.Log("filled2");
    
                fill.fillAmount = targetFillAmount;
                Debug.Log("fillamoont?");
    
                if (fill.fillAmount == 1)
                {
                    PlayerController.Instance.maxHealth++;
                    Debug.Log("max health increase");
                    PlayerController.Instance.onHealthChangedCallBack();
                    PlayerController.Instance.heartShards = 0;
                }
    
                yield return null;
                Debug.Log("returned null");
    
    
    
            }
    
        }
    #12718
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    im having the same issue with the mana orbs – they dont appear on the canvas – there was a moment when it was working but then it stopped when i restarted to test it out

    also the new mini mana containers wont appear when i get 3 mana orbs – i tried the same fix as last time but doesnt seem to do the trick

    #12719
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    highly convinced this is a code problem but im unaware of any errors???

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class OrbShard : MonoBehaviour
    {
        public Image fill;
    
        public float targetFillAmount;
        public float LerpDuration = 1.5f;
        public float initialFillAmount;
        // Start is called before the first frame update
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        public IEnumerator LerpFill()
        {
            float elapsedTime = 0f;
    
            while (elapsedTime < LerpDuration)
            {
                Debug.Log("filled?");
                elapsedTime += Time.deltaTime;
                float t = Mathf.Clamp01(elapsedTime / LerpDuration);
                Debug.Log("filled1");
    
                float lerpedFillAmount = Mathf.Lerp(initialFillAmount, targetFillAmount, t);
                fill.fillAmount = lerpedFillAmount;
                Debug.Log("filled2");
    
    
    
                yield return null;
    
                fill.fillAmount = targetFillAmount;
    
               Debug.Log("fillamoont?");
    
                if (fill.fillAmount == 1)
                {
                    PlayerController.Instance.manaOrbs++;
    
                    PlayerController.Instance.orbShards = 0;
                }
            }
    
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AddManaOrb : MonoBehaviour
    {
        [SerializeField] GameObject particles;
        [SerializeField] GameObject canvasUI;
    
        [SerializeField] OrbShard orbShards;
        bool used;
        // Start is called before the first frame update
        void Start()
        {
            if (PlayerController.Instance.manaOrbs >= 3)
            {
                Destroy(gameObject);
            }
        }
    
        private void OnTriggerEnter2D(Collider2D _collision)
        {
            if (_collision.CompareTag("Player") && !used)
            {
    
                used = true;
                StartCoroutine(ShowUI());
    
            }
        }
    
        IEnumerator ShowUI()
        {
            GameObject _particles = Instantiate(particles, transform.position, Quaternion.identity);
            Destroy(_particles, 0.5f);
            yield return new WaitForSeconds(0.5f);
    
            canvasUI.SetActive(true);
            orbShards.initialFillAmount = PlayerController.Instance.orbShards * 0.34f;
            PlayerController.Instance.orbShards++;
            orbShards.targetFillAmount = PlayerController.Instance.orbShards * 0.34f;
            Debug.Log("orbshards");
    
            yield return new WaitForSeconds(2.5f);
    
            StartCoroutine(orbShards.LerpFill());
            Debug.Log("lerpy fill");
    
            canvasUI.SetActive(false);
            SaveData.Instance.SavePlayerData();
    
    
            Destroy(gameObject);
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class ManaOrbsHandler : MonoBehaviour
    {
        public bool usedMana;
        public List<GameObject> manaOrbs;
        public List<Image> orbFills;
    
        public float countDown = 3f;
        float totalManaPool;
        // Start is called before the first frame update
        void Start()
        {
            for(int i = 0; i < PlayerController.Instance.manaOrbs; i++)
            {
                manaOrbs[i].SetActive(true);
            }
        }
    
        // Update is called once per frame
        void Update()
        {
            for (int i = 0; i < PlayerController.Instance.manaOrbs; i++)
            {
                manaOrbs[i].SetActive(true);
            }
            CashInMana();
        }
    
        public void UpdateMana(float _manaGainFrom)
        {
            for(int i = 0; i < manaOrbs.Count; i++)
            {
                if (manaOrbs[i].activeInHierarchy && orbFills[i].fillAmount < 1)
                {
                    orbFills[i].fillAmount += _manaGainFrom;
                    break;
                }
            }
        }
    
        void CashInMana()
        {
            if(usedMana && PlayerController.Instance.Mana <= 1)
            {
                countDown -= Time.deltaTime;
            }
    
            if(countDown <= 0)
            {
                usedMana = false;
                countDown = 3;
    
                totalManaPool = (orbFills[0].fillAmount += orbFills[1].fillAmount += orbFills[2].fillAmount) * 0.33f;
                float manaNeeded = 1 - PlayerController.Instance.Mana;
    
                if (manaNeeded > 0)
                {
                    if(totalManaPool >= manaNeeded)
                    {
                        PlayerController.Instance.Mana += manaNeeded;
                        for (int i = 0; i < orbFills.Count; i++)
                        {
                            orbFills[i].fillAmount = 0;
                        }
    
                        float addBackTotal = (totalManaPool - manaNeeded) / 0.33f;
    
                        while(addBackTotal > 0)
                        {
                            UpdateMana(addBackTotal);
                            addBackTotal -= 1;
                        }
                    }
                    else
                    {
                        PlayerController.Instance.Mana += totalManaPool;
                        for (int i = 0; i < orbFills.Count; i++)
                        {
                            orbFills[i].fillAmount = 0;
                        }
                    }
                }
    
            }
        }
    }
    #12720
    Niyam Shah
    Level 8
    Participant
    Helpful?
    Up
    0
    ::

    the mana orbs work as my mana will increase but it will not create a new mini mana container on the side despite me setting it in the inspector – also the animation of the mana orb filling in the canvas doesnt play – it was working but then stopped when i clicked play again?

    View post on imgur.com
    #12722
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Hi Niyam, you will have to figure this out on your end. Don’t check against the video to see if your code is the same, check to see which parts of the code are not running. E.g. if the mana orb is not increasing, check if ShowUI() in AddManaOrbs is firing using a Debug.Log().

    If it is not, then you have to find the function(s) responsible for calling ShowUI(), and check if it is running. If it is not, head one level up and find the script that calls it, etc…

    Eventually, you will find a script with an if conditional that is not set up properly, or a coroutine that is not called / running when it is supposed to be.

    #13456
    Allan Valin
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    I had the same problem and I can say that it is a simple matter of going to the Increase Maxhealth Prefab and adding values to the HeartShards script (attached to the canvas). However I have no clue about what these values should be since it isn’t mentioned in the video. I tried with Target Fill Amount 0.25, Lerp Duration 1.5, Initial Fill Amount 0. Adding the heart image to the Fill field makes so that the heart increases always from 0 to 0.25 because every heart shard counts as one entire piece for some reason.

    In order to solve the problem I just started cutting what I didn’t deem necessary (I don’t use HeartShard.cs anymore because I’d always get an error on line 35 fill.fillAmount = lerpedFillAmount; even when I assigned a value to it) and ended up with the code below. Now the gathering four pieces gives only one heart instead of four total, and since there’s no UI animation, there’s no wrong animation lol

    (I changed from heartShards to heartPieces because it sounds better to me, there’s that Papa Roach song, Last Resort, that goes “cut my heart into pieces, this is my last resort (…)”) IncreaseMaxHealth.cs

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class IncreaseMaxHealth : MonoBehaviour
    {
        [SerializeField] GameObject particles;
        [SerializeField] GameObject canvasUI;
    
        [SerializeField] HeartPieces heartPieces;
    
        bool used;
    
    
        // Start is called before the first frame update
        void Start()
        {
            if (PlayerController.Instance.maxHealth >= PlayerController.Instance.maxTotalHealth)
            {
                Destroy(gameObject);
            }
        }
    
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.CompareTag("Player") && !used)
            {
                used = true;
                StartCoroutine(ShowUI());
    
            }
        }
    
        IEnumerator ShowUI()
        {
            GameObject _particles = Instantiate(particles, transform.position, Quaternion.identity);
            Destroy(_particles, 0.5f);
            yield return new WaitForSecondsRealtime(0.5f);
    
            //canvasUI.SetActive(true);
            //heartPieces.initialFillAmount = PlayerController.Instance.heartPieces * 0.25f;
            PlayerController.Instance.heartPieces++;
            //heartPieces.targetFillAmount = PlayerController.Instance.heartPieces * 0.25f;
    
            //StartCoroutine(heartPieces.LerpFill());
            if(PlayerController.Instance.heartPieces == 4)
            {
                PlayerController.Instance.maxHealth++;
                PlayerController.Instance.onHealthChangedCallback();
                PlayerController.Instance.heartPieces = 0;
            }
    
            yield return new WaitForSecondsRealtime(2f);
    
            SaveData.Instance.SavePlayerData();
            //canvasUI.SetActive(false);
            Destroy(gameObject);
        }
    }
    </code>
Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: