Forum begins after the advertisement:


[Part 8] Mana orb and canvas problem

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 8] Mana orb and canvas problem

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #15417
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    the mana orb fill doesn’t work and my UI canvas has problem, whenever i collect them, the canvas show up but does not turn off
    #15418
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    using System.Collections; using System.Collections.Generic; using UnityEngine;

    public class AddManaOrb : MonoBehaviour { bool used; [SerializeField] GameObject particals; [SerializeField] GameObject canvasUI;

    [SerializeField] OrbShard orbShard;
    // Start is called before the first frame update
    void Start()
    {
        if (Player.Instance.manaOrbs >=3)
        {
            Destroy(gameObject);
        }
    }
    
    // Update is called once per frame
    private void OnTriggerEnter2D(Collider2D _collision)
    {
        if (_collision.CompareTag("Player") & !used)
        {
            used = true;
            GameObject _particals = Instantiate(particals, transform.position, Quaternion.identity);
            Destroy(_particals, 0.5f);
            StartCoroutine(ShowUI());
    
        }
    }
    IEnumerator ShowUI()
    {
        GameObject _particals = Instantiate(particals, transform.position, Quaternion.identity);
        Destroy(_particals, 0.5f);
        yield return new WaitForSeconds(0.5f);
    
        canvasUI.SetActive(true);
        orbShard.initialFillAmount = Player.Instance.heartShards * 0.34f;
        Player.Instance.orbShard++;
        orbShard.targetFillAmount = Player.Instance.heartShards * 0.34f;
    
        StartCoroutine(orbShard.LerpFill());
    
        yield return new WaitForSeconds(2.5f);
        Player.Instance.unlockWallJump = true;
        SaveData.Instance.SavePlayerData();
        canvasUI.SetActive(false);
        Destroy(gameObject);
    }

    }

    #15419
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    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;
    
    void Start()
    {
    
    }
    
    // Update is called once per frame
    void Update()
    {
    
    }
    public IEnumerator LerpFill()
    {
        float elapsedTime = 0f;
        while (elapsedTime < lerpDuration)
        {
            elapsedTime += Time.deltaTime;
            float t = Mathf.Clamp01(elapsedTime / lerpDuration);
    
            float lerpedFillAmount = Mathf.Lerp(initialFillAmount, targetFillAmount, t);
            fill.fillAmount = lerpedFillAmount;
    
            yield return null;
        }
    
        fill.fillAmount = targetFillAmount;
    
        if (fill.fillAmount == 1)
        {
            Player.Instance.manaOrbs++;
            Player.Instance.orbShard = 0;
        }
    }

    }

    #15420
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    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()
    {
    
    }
    void Update()
    {
        for (int i = 0; i < Player.Instance.manaOrbs; i++)
        {
            manaOrbs[i].SetActive(true);
        }
        CashInMana();
    }
    // Update is called once per frame
    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 && Player.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 -Player.Instance.Mana;
            if (manaNeeded > 0)
            {
                if(totalManaPool > manaNeeded)
                {
                    Player.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
                {
                    Player.Instance.Mana += totalManaPool;
                    for (int i = 0; i < orbFills.Count; i++)
                    {
                        orbFills[i].fillAmount = 0;
                    }
                }
            }
        }
    }

    }

    #15421
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    Update: my bad when im not replace all the heartShard to orbShard in AddManaOrb.cs, now the Mana orb can fill but the canvas is still having prob, it doesnt turn off

    #15425
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Hey there, There could be a few different issues for why the canvas is not disappearing so let’s try to find out what may be wrong first.

    Currently your code for ShowUI() [Which is what controls the ui for all the scripts that do so (AddManaOrbs & others)] is identical to ours:

        IEnumerator ShowUI()
        {
            GameObject _particles = Instantiate(particles, transform.position, Quaternion.identity);
            Destroy(_particles, 0.5f);
            yield return new WaitForSeconds(0.5f);
            gameObject.GetComponent<SpriteRenderer>().enabled = false;
    
            canvasUI.SetActive(true);
            orbShard.initialFillAmount = PlayerController.Instance.orbShard * 0.34f;
            PlayerController.Instance.orbShard++;
            orbShard.targetFillAmount = PlayerController.Instance.orbShard * 0.34f;
    
            StartCoroutine(orbShard.LerpFill());
    
            yield return new WaitForSeconds(2.5f);
            SaveData.Instance.SavePlayerData();
            canvasUI.SetActive(false);
            Destroy(gameObject);
        }

    Although it appears that you still have another code that you need to clean up there: Player.Instance.unlockWallJump = true; near the bottom of the coroutine.


    Now that you’ve fixed the fill issue, could you see if there is any different error showing up? Considering that your heart fill was able to play the fill animation, it’s likely only the section after the LerpFill() coroutine is called that causes the canvas to not set itself off. Thus, that would most probably leave the SavePlayerData() code to be the line that is failing and stopping the canvas from disappearing. that or something else is having an error.

    For now, you can move all canvas lines in the final section of ShowUI() above the SavePlayerData() line.

    yield return new WaitForSeconds(2.5f);
    canvasUI.SetActive(false);
    SaveData.Instance.SavePlayerData();
    canvasUI.SetActive(false);
    Destroy(gameObject);

    If you do find any error messages, do send another video on how you got them or what they are, as well as what code they direct to if any.

    #15426
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    I did as you told and got some problems: 1.the spell collect still have that problem 2.the heart fill start from 3/4 3.i have collect 3 mana shard but the orb doesn’t show (do i need to drag the mana orb to the list of ManaOrbsHandler.cs ?)
    #15427
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.SceneManagement; using Unity.Mathematics;

    [System.Serializable] public struct SaveData { public static SaveData Instance;

    //map stuff
    public HashSet<string> sceneNames;
    
    //bench stuff
    public string benchSceneName;
    public Vector2 benchPos;
    
    //player stuff
    public int playerHealth;
    public int playerHeartShards;
    public float playerMana;
    public bool playerHalfMana;
    public int playerManaOrbs;
    public int playerOrbShard;
    public float playerOrb0Fill, playerOrb1Fill, playerOrb2Fill;
    public Vector2 playerPos;
    public string lastScene;
    
    public bool playerUnlockWallJump;
    public bool playerUnlockDash;
    public bool playerUnlockVarJump;
    
    public bool playerUnlockSideSpell, playerUnlockUpSpell, playerUnlockDownSpell;
    
    //enemy stuff
    //Shade stuff
    public Vector2 shadePos;
    public string sceneWithShade;
    public Quaternion shadeRot;
    
    public void Initialize()
    {
        if(!File.Exists(Application.persistentDataPath + "/save.bench.data"))//if file doesnt exist , create new file
        {
            BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.bench.data"));
        }
        if(!File.Exists(Application.persistentDataPath + "/save.player.data"))//if file doesnt exist , create new file
        {
            BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
        }
        if(!File.Exists(Application.persistentDataPath + "/save.shade.data"))//if file doesnt exist , create new file
        {
            BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.shade.data"));
        }
    
        if (sceneNames == null)
        {
            sceneNames = new HashSet<string>();
        }
    }
    
    public void SaveBench()
    {
        using(BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.bench.data")))
        {
            writer.Write(benchSceneName);
            writer.Write(benchPos.x);
            writer.Write(benchPos.y);
        }
    }
    
    public void LoadBench()
    {
        if(File.Exists(Application.persistentDataPath + "/save.bench.data"))
        {
    
            using(BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.bench.data")))
            {
                benchSceneName = reader.ReadString();
                benchPos.x = reader.ReadSingle();
                benchPos.y = reader.ReadSingle();
            }
        }
    }
    public void SavePlayerData()
    {
        using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
        {
            playerHealth = Player.Instance.Health;
            writer.Write(playerHealth);
            playerHeartShards = Player.Instance.heartShards;
            writer.Write(playerHeartShards);
            playerHalfMana = Player.Instance.halfMana;
            writer.Write(playerHalfMana);
            playerMana = Player.Instance.Mana;
            writer.Write(playerMana);
            playerManaOrbs = Player.Instance.manaOrbs;
            writer.Write(playerManaOrbs);
            playerOrbShard = Player.Instance.orbShard;
            writer.Write(playerOrbShard);
            playerOrb0Fill = Player.Instance.manaOrbsHandler.orbFills[0].fillAmount;
            writer.Write(playerOrb0Fill);
            playerOrb1Fill = Player.Instance.manaOrbsHandler.orbFills[1].fillAmount;
            writer.Write(playerOrb1Fill);
            playerOrb2Fill = Player.Instance.manaOrbsHandler.orbFills[2].fillAmount;
            writer.Write(playerOrb2Fill);
    
    
            playerUnlockWallJump = Player.Instance.unlockWallJump;
            writer.Write(playerUnlockWallJump);
    
            playerUnlockDash = Player.Instance.unlockDash;
            writer.Write(playerUnlockDash);
    
            playerUnlockVarJump = Player.Instance.unlockVarJump;
            writer.Write(playerUnlockVarJump);
    
            playerUnlockSideSpell = Player.Instance.unlockSideSpell;
            writer.Write(playerUnlockSideSpell);
            playerUnlockUpSpell = Player.Instance.unlockUpSpell;
            writer.Write(playerUnlockUpSpell);
            playerUnlockDownSpell = Player.Instance.unlockDownSpell;
            writer.Write(playerUnlockDownSpell);
    
            playerPos = Player.Instance.transform.position;
            writer.Write(playerPos.x);
            writer.Write(playerPos.y);
    
            lastScene = SceneManager.GetActiveScene().name;
            writer.Write(lastScene);    
        }
    }
    public void LoadPlayerData()
    {
        if (File.Exists(Application.persistentDataPath + "/save.player.data"))
        {
            using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
            {
                playerHealth = reader.ReadInt32();
                playerHeartShards = reader.ReadInt32();
                playerHalfMana = reader.ReadBoolean();
                playerMana = reader.ReadSingle();
                playerManaOrbs = reader.ReadInt32();
                playerOrbShard = reader.ReadInt32();
                playerOrb0Fill = reader.ReadSingle();
                playerOrb1Fill = reader.ReadSingle();
                playerOrb2Fill = reader.ReadSingle();
    
                playerUnlockWallJump = reader.ReadBoolean();
                playerUnlockDash= reader.ReadBoolean();
                playerUnlockVarJump= reader.ReadBoolean();
    
                playerUnlockSideSpell = reader.ReadBoolean();
                playerUnlockUpSpell= reader.ReadBoolean();
                playerUnlockDownSpell= reader.ReadBoolean();
    
                playerPos.x = reader.ReadSingle();
                playerPos.y = reader.ReadSingle();
                lastScene = reader.ReadString();
    
    
                Player.Instance.Health = playerHealth;
                Player.Instance.heartShards = playerHeartShards;
                Player.Instance.halfMana = playerHalfMana;
                Player.Instance.Mana = playerMana;
                Player.Instance.manaOrbs = playerManaOrbs;
                Player.Instance.orbShard = playerOrbShard;
                Player.Instance.manaOrbsHandler.orbFills[0].fillAmount = playerOrb0Fill;
                Player.Instance.manaOrbsHandler.orbFills[1].fillAmount = playerOrb1Fill;
                Player.Instance.manaOrbsHandler.orbFills[2].fillAmount = playerOrb2Fill;
    
    
                Player.Instance.unlockWallJump = playerUnlockWallJump;
                Player.Instance.unlockDash = playerUnlockDash;
                Player.Instance.unlockVarJump = playerUnlockVarJump;
    
                Player.Instance.unlockSideSpell = playerUnlockSideSpell;
                Player.Instance.unlockUpSpell = playerUnlockUpSpell;
                Player.Instance.unlockDownSpell = playerUnlockDownSpell;
    
                Player.Instance.transform.position = playerPos;
                SceneManager.LoadScene(lastScene);
            }
        }
        else
        {
            Debug.Log("file doesn't exist");
    
            Player.Instance.Health = Player.Instance.maxHealth;
            Player.Instance.heartShards = 0;
            Player.Instance.halfMana = false;
            Player.Instance.Mana = 0.5f;
    
    
            Player.Instance.unlockWallJump = false;
            Player.Instance.unlockDash = false;
            Player.Instance.unlockVarJump= false;
    
            Player.Instance.unlockSideSpell = false;
            Player.Instance.unlockUpSpell = false;
            Player.Instance.unlockDownSpell = false;
        }
    }
    
    public void SaveShadeData()
    {
        using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.shade.data")))
        {
            sceneWithShade = SceneManager.GetActiveScene().name;
            shadePos = Shade.Instance.transform.position;
            shadeRot = Shade.Instance.transform.rotation;
    
            writer.Write(sceneWithShade);
    
            writer.Write(shadePos.x);
            writer.Write(shadePos.y);
    
            writer.Write(shadeRot.x);
            writer.Write(shadeRot.y);
            writer.Write(shadeRot.z);
            writer.Write(shadeRot.w);
        }
    }
    public void LoadShadeData()
    {
        if (File.Exists(Application.persistentDataPath + "/save.shade.data"))
        {
            using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.shade.data")))
            {
                sceneWithShade= reader.ReadString();
                shadePos.x = reader.ReadSingle();
                shadePos.y = reader.ReadSingle();
    
                float rotationX = reader.ReadSingle(); 
                float rotationY = reader.ReadSingle();
                float rotationZ = reader.ReadSingle();
                float rotationW = reader.ReadSingle();
                shadeRot = new Quaternion( rotationX, rotationY, rotationZ,rotationW);
    
            }
        }
        else
        {
            Debug.Log("shade doesnt exist");
        }
    }
    public void DeletePlayerData()
    {
        string path = Application.persistentDataPath + "/save.player.data";
        if (File.Exists(path))
        {
            File.Delete(path);
            Debug.Log("Player save data deleted.");
        }
    }
    
    public void DeleteShadeData()
    {
        string path = Application.persistentDataPath + "/save.shade.data";
        if (File.Exists(path))
        {
            File.Delete(path);
            Debug.Log("Shade save data deleted.");
        }
    }
    
    public void DeleteAllSaveData()
    {
        //DeleteBenchData();
        DeletePlayerData();
        DeleteShadeData();
    }

    } here are my saveData.cs

    #15428
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    the shard didn’t disapear also

    #15429
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::
    1. The Spell collects still have the issue, because you likely have yet to put the code in ShowUI() as instructed, or there is another code directly above it that causes the error, so if you could check that this code is always directly below the WaitForSeconds() line:
    yield return new WaitForSeconds(2.5f);
    canvasUI.SetActive(false);

    1. This is likely because of the fact that your last saved heart shard amount is 3 in the SaveData.cs, or that you’ve set your heart shards to 3 on your player’s inspector/prefab.

    1. Yes, please do drop in the correct mana orbs as i do not believe the mana orbs handler is meant to automatically find them.

    As for the shards not disappearing, that’s because, again, the error you are receiving from SaveData.cs is stopping the process of ShowUI from completing, that’s why you should move the turn off canvas code above the line for SaveData.cs.

    Thus, until we solve the errors, they will not disappear since the code is still next in order after the error.


    So when you get errors in the console, you can see where the error goes to as it’s directed in the console.

    You can find the error by double clicking the error message, or following it’s direction. In which case can you help me find the lines 171 and 104 in your SaveData.cs? Those 2 are the ones listed in each of the errors and it would help to know which ones they are.

    The errors you are recieving should be the cause behind why the canvas’ did not disappear before.

    #15431
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    here are the line 104 and 171, and idk what object need to drag into the Mana Orbs Handler(the video didn’t show that) , am i doing right in the 1st picture ?
    #15432
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Yes, that’s the right assignment, though you should rename your mana image to give them their corresponding numbers 1, 2 and 3 for better identification. [Sorry for the fact that the video didn’t show it]

    The errors in question are regarding the mana fills. Which should mean that once you’ve assigned them correctly with the Mana Orb Handler, the problem should be fixed.

    #15433
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    it still has the same issue, console log show the line 104 and 171, maybe it relate to the value of Orb Shard and Mana orbs in the picture?
    #15434
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Due to the nature of the error, NullReferenceException error, it’s likely that it’s either your Player cannot find the ManaOrbsHandler, or the image fills you are using for the mana orbs is not right. I don’t believe that changing the values will do anything considering the error is trying to call data from the SaveData but being unable to.

    Do check that your image fills are set to the correct image type of filled, and try reinputting the mana orbs handler into the player’s inspector. Also do check that in the Canvas Prefab, the image fills are set active while the parent, mana orbs, are set to inactive.

    #15435
    Hoang Nguyen
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    i figure it out, the Mana orbs and fill need to set active while the Orb is inactive cus the ManaOrbsHandle.cs won’t work if the canvas is set to inactive.

Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: