Forum begins after the advertisement:
[part 4] heart and mana UI problems
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [part 4] heart and mana UI problems
- This topic has 7 replies, 5 voices, and was last updated 7 months, 1 week ago by Terence.
-
AuthorPosts
-
April 13, 2024 at 3:26 am #13844::
When i die and respawn my heartfills are invisible but they appear once the player is hit once. like in the video below.
also after i die and respawn my mana container gets cut in half but once i restart the game it appears full(but still has half the mana)
April 13, 2024 at 8:29 pm #13846::Looking at it,
1) Heartfill is invisible
Can you take a video or screenshot of your PlayerController.cs
Respawned()
.
Check if you have a codeHealth = maxHealth;
in theRespawn()
method.My theory is that your health is not being updated or called to update when respawning.
2) Mana is not halved on reenter
Currently this is intentional as there is no code for the UI Manager to remember that your Player still has half mana. [You should be able to see on the Canvas Gameobject that it’s state is still FullMana on starting the game, regardless of your Player’s halfmana bool.]
To add this feature, I suggest to put a code under PlayerController.csStart()
.void Start() { pState = GetComponent
(); rb = GetComponent (); sr = GetComponent (); anim = GetComponent (); manaOrbsHandler = FindObjectOfType (); audioSource = GetComponent (); SaveData.Instance.LoadPlayerData(); gravity = rb.gravityScale; if (halfMana == true) { UIManager.Instance.SwitchMana(UIManager.ManaState.HalfMana); } else { UIManager.Instance.SwitchMana(UIManager.ManaState.FullMana); } //Mana = mana; //manaStorage.fillAmount = Mana; //Health = maxHealth; } April 13, 2024 at 8:49 pm #13847::you were right. the problem was in the respawn function. I have accidently written
health = maxHealth;
instead ofHealth = maxHealth;
.And the new mana container code works perfectly too. Thanks alot
April 14, 2024 at 3:19 pm #13851April 14, 2024 at 8:23 pm #13855::If you want them to be removed, you will have to create some new code for SaveData.cs as this is an intentionally caused issue by not creating the function.
A simple way to do this is by creating a bunch if
bool
s for specific heart unlocks and copying the structure for Unlocking abilities.For example,
1) In SaveData.cs, createpublic bool haveCcollectedHeartShard1, haveCcollectedHeartShard2, haveCollectedHeartShard3;
2) Create a seperate void in SaveData.cs for the Heart Shards. and follow the same format as the previous save and load data.
3) Similarly, In IncreaseMaxHealth.cs, addpublic bool collectedHeartShard1, collectedHeartShard2, collectedHeartShard3
4) In IncreaseMaxHealth.cs, create a way to identify which shard it is, likepublic int HeartShardNumber
.
5) In IncreaseMaxHealth.csStart()
, create seperate if else statements to check for yourHeartShardNumber
& the bool of SaveData.cs of the corresponding number. Then create a code to load the SaveData. For instance:void Start() { ;SaveData.Instance.LoadHeartShardData(); if (PlayerController.Instance.maxHealth >= PlayerController.Instance.maxTotalHealth) { Destroy(gameObject); } if (HeartShardNumber == 1) { if (collectedHeartShard1) { Destroy(gameObject); } } else if (HeartShardNumber == 1) { if (collectedHeartShard1) { Destroy(gameObject); } } else . . . else if (HeartShardNumber == 10) { if (collectedHeartShard10) { Destroy(gameObject); } } }
6) Finally, set a way to save the data by adding in a code like in step 5 for
ShowUI()
. Use the same code but changeDestroy()
forcollectedHeartShard1 = true
. AFter all theif
statements, put aSaveData.Instance.SaveHeartShardData();
.This will be a bit of tedious work but this is only one way to save what you collected and what hasn’t for the same type of object. This will not be sustainable for things like Chests where there can be hundreds, but this will suffice for things with little copies such as the shards.
April 17, 2024 at 9:35 am #13896::How would you go about doing this on a large scale like imagine you had hundreds of chests
April 17, 2024 at 7:57 pm #13923::This will require some testing, but we’ll get back to you on this when we find an efficient way to make this mechanic.
April 17, 2024 at 11:44 pm #13933::How would you go about doing this on a large scale like imagine you had hundreds of chests
Just to add on to Joseph’s comment, usually, for a large number of booleans, we will use bitmasks if we want to make it scalable. Bitmasks are basically integers used as booleans.
Computers store numbers in binary, not in decimal, which means 0, 1, 2, 3, 4, 5 etc… become 0, 1, 10, 11, 100, 101, 110, etc.
Integers are 32-bit numbers, which means they are stored as a series of 32 1s or 0s, like so:
00000000 00000000 00000000 00000000
Using it as a bitmask means treating the integer as a set of 32 booleans instead of a whole integer. For example, if I wanted to flip chest number 2 and 5, I would change the integer to this:
00000000 00000000 00000000 00010010
We can save a bitmask for treasure chests in each scene in
SaveData.cs
, in a dictionary, like so:Dictionary<string, int> pickedItemsRecord = new Dictionary<string, int>();
Where the key to the dictionary is a string, and the int is the bitmask. You will also need to give an ID property to every treasure chest that ranges between 0 to 32. Then, whenever a Scene is loaded, the treasure chest will check the bitmask for that particular scene to see if the chest has already been picked up, and make the chest hide itself if so.
The limitation to this system is that you can only have up to 32 items in a Scene, but you can change the
int
to along
(64-bit integer) so that you can hold 64 items instead.It’s a bit hard to implement, because you’ll need to learn about bitwise operations and dictionaries to be able to do this, but I hope this helps!
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: