Skip to content

Narwhal Simulator 9: Narwhal Coins

Hi everyone! Since Wednesday, I have completed the Narwhal Coins card in Trello. This consisted of deciding on the name, making the UI for the coins, making blocks give the player coins, and making an icon. I completed all 4 of these and I will be talking about these. I will also be briefly talking about how the Unity UI system works and I’ll talk a bit about the script execution order as well.

So, let’s get right into what I’ve done. I decided that we will stick with the name Narwhal Coins. It’s a bit generic but I think it will be fine, and I can always change it later. If you have any better ideas, you can leave them in the comments. The symbol for a Narwhal Coin is ₦. This is also the symbol for the Nigerian Naira, but luckily under the sea I don’t think this coincidence will cause any issues. Also, if I ever say the player’s “score”, then unless I’ve implemented an actual score system, I’m talking about the number of Narwhal Coins the player has.

Next, I’ll talk about making the UI that displays the Narwhal Coins. First, this is what it looks like at the moment:

I’m considering removing the “₦: ” from the text, but I think it’s OK for now. With Narwhal Simulator’s development, I’ve been trying my best to do things as right as possible. It’s important to me that people on many different computers will be able to have a good experience playing Narwhal Simulator. This is why I’ve been working to make sure that the UI looks good at all resolutions. I want the text to be readable on all monitors, and I don’t want it to cover much of the screen. Luckily, Unity has a bunch of tools available for me to use that allows me to use percentages of the screen to control sizes, instead of pixel numbers. This means that the narwhal coin in the top will always be 8% of the screen’s height, and it will always be square. The text will always be the same size as the coin and no bigger or smaller. This is all true regardless of the player’s screen. Unity allows me to simulate different screen resolutions, so here’s what the UI looks like at 3 different resolutions: (Please note that these screenshots are not actually the resolution stated but the game is running at that resolution)

1366×768 (the most common resolution for computers right now https://gs.statcounter.com/screen-resolution-stats/desktop/worldwide)
1920×1080 (1080p, the second most common resolution for computers right now)
3840×2160 (4K, not a very common resolution for computers but probably the largest I need to accommodate for)

They all look almost exactly the same! That’s what I want. Finally, here’s a close-up of the Narwhal Coin image:

It’s not a Van Gogh but I think it’s pretty decent for the time being.

The blocks now give Narwhal Coins when you break them. The stone block gives 10, the ice block gives 5, and the gold block gives 150. This means that, although stone gives more coins than ice, ice is a more efficient method of getting coins until you’re able to instantly break both blocks on a reasonable hit. Gold is significantly better than both, and the player should want to break gold whenever they find it. 

I’m now going to talk for a bit about how I’ve made the UI and the Player interact. The UI and the player are 2 completely different scripts. It would be inefficient for the UI script to keep track of the player’s last score and keep asking the Player script every frame for the current score. I’ve fixed this by using a system of UnityEvents. For anyone who has used C# or another similar language, a UnityEvent is just a basic C# Event but specifically designed to work with the Unity editor. For people who haven’t used this kind of thing before, a UnityEvent is like a newsletter. Just like you can subscribe to my newsletter and get notified whenever I post something new (links to the right on desktop and below the article on mobile), with my current system, a function can subscribe to the coinsChanged event and get notified whenever the player’s number of coins changes. I have an event forcoinsChanged, coinsGained, coinsLost, and coinsReset. coinsChanged is called whenever the number of coins changed, whereas the coinsGained, coinsLost, and coinsReset events are only called in their specific circumstance. This is how the coinsChanged event is declared:

public UnityEvent coinsChanged { get; protected set; } = new UnityEvent();

Here is the GiveCoins function, a function which gives the specified number of coins to the player:

public void GiveCoins(int coins) {
	if (coins <= 0) {
		Debug.LogWarning("Can't subtract coins with GiveCoins "   coins);
		return;
	}
	Coins  = coins;
	coinsChanged.Invoke();
	coinsGained.Invoke();
}

coinsChanged.Invoke() notifies all the subscribed functions that the player’s coins value has changed.

This is how the UIManager class subscribes to the coinsChanged event:

p.coinsChanged.AddListener(CoinsChanged);

This will call the UIManager’s CoinsChanged function whenever the player’s coins value changes.

Finally, I’ll quickly discuss how the script execution order works in Unity. In Unity, there are several functions a component can have that will be called in certain situations. For example, the Start function will be called whenever the object is created, and the Update function will be called each frame of the game. At the start of the game, the Start function gets called on a lot of objects, since all the objects currently in the scene are all being created at once. These can’t, however, be called all at the same time. They get called in a certain order, the script execution order. For most scripts, this is an arbitrary order decided by Unity. It is seemingly random but consistently the same. This order wasn’t good enough for the UIManager. In the Start function of the Player, the coins get reset. The UIManager would then be notified since the coins changed, and then update its text accordingly. This didn’t happen, however, because the UIManager subscribes to the Player’s coinsChanged event in its Start function, which because of the random script execution order, was after the player’s Start function, so the UIManager never got the notification about the coins being changed (you could also miss a notification if you don’t subscribe to my newsletter quickly!), and the coins text would stay at the default, which is 123,456,798 for testing reasons. To fix thins, I changed the script execution order in the settings so that the UIManager would go before the default scripts. Here’s the new script execution order: (UIManager was put there by me, but everything else was there by default)

Well, that’s everything I have for you this week! Thanks for reading and I hope you had a good time. Next time I’ll be working on making the player more modular. You can read more about that in the last post or on Trello. See you Tuesday!

Links recap:

GitHub: https://github.com/AgentD1/NarwhalSimulator

Trello: https://trello.com/b/Nd7rNvWU/narwhal-simulator

Leave a Reply