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
- This topic has 15 replies, 2 voices, and was last updated 3 months ago by Joseph Tang.
-
AuthorPosts
-
July 30, 2024 at 3:11 am #15417Hoang NguyenParticipant::
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 offJuly 30, 2024 at 3:11 am #15418Hoang NguyenParticipant::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);
}
}July 30, 2024 at 3:12 am #15419Hoang NguyenParticipant::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;
}
}
}July 30, 2024 at 3:12 am #15420Hoang NguyenParticipant::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;
}
}
}
}
}
}July 30, 2024 at 3:51 pm #15421Hoang NguyenParticipant::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
July 30, 2024 at 5:22 pm #15425Joseph TangModerator::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
().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 theSavePlayerData()
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 theSavePlayerData()
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.
July 30, 2024 at 6:22 pm #15426Hoang NguyenParticipant::
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 ?)July 30, 2024 at 6:23 pm #15427Hoang NguyenParticipant::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.csJuly 30, 2024 at 6:24 pm #15428Hoang NguyenParticipantJuly 30, 2024 at 6:39 pm #15429Joseph TangModerator::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 theWaitForSeconds()
line:yield return new WaitForSeconds(2.5f); canvasUI.SetActive(false);
2. 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.
3. 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.
July 30, 2024 at 7:08 pm #15431Hoang NguyenParticipant::
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 ?July 30, 2024 at 7:17 pm #15432Joseph TangModerator::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.
July 30, 2024 at 7:38 pm #15433Hoang NguyenParticipant::
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?July 30, 2024 at 8:18 pm #15434Joseph TangModerator::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.
July 31, 2024 at 12:06 am #15435Hoang NguyenParticipant::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.
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: