This is isn’t a tutorial any more! It definitely my own game. I can’t believe I wasted so many hours stressing and worrying about how I could link the text to the code. Running it over and over in my head. When all I had to do was to take ACTION! Simply by making the variable public I wouldn’t have to worry about assigning the text as I could drag and drop – so bloody simple!! Why on earth didn’t I realise this before. Learning C# is full of aha! moments like that, though this was more like a groan of relief/annoyance/tired happiness and this means it doens’t matter where my script will go! I can also make a Pipe Script for this (I’ll be using the Pipe Trigger script I had already started) as this seems the most logical. Currently filling it out with static variables etc so I can see if it works and how to work it. I won’t be getting clever with expansions and arrays I just want a simple level. Hell I might even add a timer to it to see if others can get as low a time as possible. Another stretch goal if I remember it later. I might make a page on just this game. Done.
I’m working on the text atm – here are notes talking about how to connect text to a real world object (https://forum.unity.com/threads/anchor-ui-image-to-gameobject.364584/) – Sure it would look great but that’s at least another week just to learn how to do it. Right now I’ll settle for text on the side of the screen (or a graphical representation that doesn’t show the numbers. There would be a mathematical way of increasing/decreasing the graphical/distortion of an object and hence do the same job but right now I’ll go for the numbers 🙂 Wow, OK looks like I didn’t need to do it if I lock off a 2D view – but when I work in 3 or 4D I definitely will need it (BTW I’m using my own definition here; 4D is 3D with an additional dimension of time. I don’t care if you aren’t on board – deal with it 😄). Nope, it makes the canvas go crazy- I’ll just have them on the side of the screen. I can probably have all of the pipe stats in the same text but I don’t want to go through that trouble too. I’m going to keep it simple and have the stats on the right hand side of the screen. This page helped me show the name of the tag in game (https://answers.unity.com/questions/697725/debuglogname-where-name-is-string.html).
It’s not pretty but the text is up for pipe 1. Wow! It worked with all of them!! Nice! Now to make a timer. Nope- that’s a stretch goal not a main one. The next important thing is a restart button. Dang it. I’m just getting into this but I know I should let poor Yuka sleep… I wish I had my own room for this.
Next day – I’m starting comparatively early. I’ve got life stuff to do as well (covered in an external diary- compartmentalise is the way forward. A ticket to productivity and happiness – after all one can’t be happy if one knows how close one is to death all the time and one cannot seriously focus if one is always thinking about a happy memory with a loved one. Compartmentalise 🙂 ). Currently brainstorming potential thesis, study fields for University.
I would like the button(s) to have a “pipe theme” to them but that is another stretch goal I guess. Fixed the lighting again- restart inside game always comes up darker so you’ve gotta click Window/Rendering/Lighting and then “New Lighting Settings” and Auto Generate (under Lightmapping setting).
Interesting I’ve gotta load up the library differently for the buttons instead of the text even though both come from TMP – I’ll test… Small bug with collider with rat = fixed. Yep, it works with the steps in the tute; there’s probably a more elegant way (as with everything) but that will do. OK, now the main menu I think. I know I don’t need to but I REALLY want to have a counter so each play through might mean something. I would also like the game name down the left side with my name in itty bitty letters there too. In the time taken I want it to be measured in seconds initially then when it’s larger than 60 seconds I want a new field in minutes than a new field in hours than a new field in days 🙂 Cute! It’ll be like a hidden trolling thing – an Easter Egg if you will 🙂
Yep I can do it but I won’t just yet. I’ll leave the code inside it (commented out) – I’ll also duplicate the Pipe Scripts (one for each) to make it easier to know if the pipe was empty and then Boolean each which will allow a winnable game state.
The more I explore and do the more I realise how much I need to learn. For some reason I turned on my box colliders for my pipes, water, and plane. Why?! Habit I guess. As it turned out they were playing with my colliders and creating problems. True I’d need to be more than less in VR but not in a 3D looking like 2D game. It may have been the reason my code was screwing up so much. That being said I will go ahead and make a separate script for each pipe trigger as I don’t care to be clever I just want things to work. Thank heavens for Debug.Log – it allows me to check almost every single line of code to see if it works!! Things have changed so much since BASIC when I was 5.5 years old. A line like “
Debug.Log("Status of pipeCompleteA is " + pipeCompleteA);
is soooo useful!
After days of fruitless trying it seems this script has gotten the better of me – the values kept resetting to 0. But, after a quick snooze, I worked it out. I’ll keep the variable to be stored/switched OUTSIDE of the code… I’ll simply start the scene with an element unactivated and activate it if a series of conditions are met. There is no way the element can be unactivated during the play session so it’s foolproof!! Another way might be to set the conditions in “Awake” but I don’t think it will work as I don’t think I can initialise variables there. Aah, this means I have an easier access to graphical changes as graphical changes are logical switches 🙂 Aah, now the && statements worked but they didn’t work before – annoying. But now I can finish the game. Success! The game can be played to completion now!! I just need to destroy all spawned animals and recharges (I got it from https://forum.unity.com/threads/how-to-destroy-all-objects-with-a-certain-tag.124954/). I should move this destruction code from PlayerController script to Game Controller (and call the method from the Player controller script. Note I can use this to RTF text (https://stackoverflow.com/questions/57462217/how-to-underline-and-bold-button-text-through-script-unity3d
). Later I would still like to add a timer (https://gamedevbeginner.com/how-to-make-countdown-timer-in-unity-minutes-seconds/)…
// private int seconds = 0;
// private int minutes = 0;
// private int hours = 0;
// private int days = 0;
Dang it. I’ll need to use the IEnumerator to create a game loop otherwise the end will keep repeaing over and over again. Seems like there are a number of ways to remove all objects with a certain tag (https://answers.unity.com/questions/1143629/destroy-multiple-gameobjects-with-tag-c.html) but I used (https://forum.unity.com/threads/how-to-destroy-all-objects-with-a-certain-tag.124954/) earlier… But there is a better option for timing (and one I was looking for)- (https://answers.unity.com/questions/692905/c-timer-that-displays-in-mins-and-seconds-1.html).
public void DestroyAllSpawnables()
{
GameObject[] gos = GameObject.FindGameObjectsWithTag("Enemy");
foreach (GameObject go in gos)
{
Destroy(go);
}
GameObject[] pos = GameObject.FindGameObjectsWithTag("AmmoRecharge");
foreach (GameObject sho in pos)
{
Destroy(sho);
}
Debug.Log("wipe out");
}
Destroying GameObjects was surprisingly difficult (https://answers.unity.com/questions/1414048/destroy-specific-gameobject-with-name.html) had the code I needed:
Destroy (GameObject.Find("Player"));
Debug.Log("wipe out");
To hide the pipe information on winning I used the comment by “Recluse” on (https://forum.unity.com/threads/calling-function-from-other-scripts-c.57072/)..
/* at start of script, then put all the things I wanted vanish in one empty parent, and dragged the script onto an object, then dragged the parent onto the component of that script on that game object */
public GameObject folderForAllPipeTexts;
// then called it in script
folderForAllPipeTexts.gameObject.SetActive(false);
// seems the easiest!!
Done! Now a menu to start with… Done! And now I have a working game! Now sounds and effects.
I’ve had a great idea with the death animation! I’ll have a skull come out (increase in scale on all axis simulatiously), while raising its head (rotates on the X axis from 180 to 280 [approx.]) so it looks like it’s coming directly out to the player! It’ll disappear as it goes. There’s probably a complicated way to make it a percentage of the play window but I don’t know atm so I’ll just give it a number.
I’m putting a skull of the player but when it’s game over the skull gets destroyed (as it’s a child of the parent). So I might use page (https://forum.unity.com/threads/c-get-transform-of-another-gameobject.177216/) to get a temporary transform of the skull if it were part of the head (I’ll use a simple cube as a placeholder) of the player and then I’ll activate the skull and give it those coordinates.
Good, Now I’ve just gotta match the game over, you won, and title screens in terms of placements (especially with the skull, victory picture, and restart buttons), then I can move on to sound effects. Actually before that I’ve gotta set the skull to match the… Nah. I think I’d rather a skull coming up from the centre of the screen instead (better placement with text etc). Done. There was some problems with nesting and inheritance vs being free. It may be nice to nest but it makes placement a pain in the ass. I couldn’t sleep (worried about money and future) so I just worked on this. I’ve got a thematic winning and loosing screen and shared restart button(s) for both. The intro/title screen is workable. Now the audio.
Game Manager: startingGameAudio, restartingGameAudio, winningGameAudio
Spawn Manager: ammoSpawnedAudio, enemySpawnedAudio
Ammo Behaviour: ammoTossedAsideAudio
Player Controller: throwAmmoAudio, noAmmoAudio, ammoPickUpAudio, enemyBitMeAudio
Ammo Pickup Object: ammoTossedAsideAudio
Pipe Trigger: pipeHitAudio, pipeCompleteAudio
OK, that’s not as bad as I feared but definitely longer than I was expecting. If this works and doesn’t take too much time I would like audio for close encounters with animals (probably not going to happen). Found the audio- now to import it. Would be nice to have different pipes at different tones (and even different tones based on how full they are – ie. first hit low resonant, second last hit = high and nearly full pip sound). Also would’ve been nice to connect sounds in script instead of in Unity – as with the pipes sometimes there are multiple targets (though I could’ve easily made the pipe triggers as prefabs).
There was an error in my reading of the steps but luckily there was a kind person in the comments who coded a way around it. Here is to put FX Audio in C#…
// declare all
public AudioClip startingGameAudio;
public AudioClip restartingGameAudio;
public AudioClip winningGameAudio;
private AudioSource gameManagerAudio;
// initiate it in start
playerAudio = GetComponent<AudioSource>();
// Trigger them in code
gameManagerAudio.PlayOneShot(winningGameAudio, 1.0f);
Then in Unity drag the audios into the scripted object, add a Audio Source as well (can keep it blank). If you add the audio source to the wrong object (like I did) or don’t have access to an object to attach it to you can avoid the “null errors” I kept getting by changing the “initiate” part of the script above to… This adds the component 🙂
gameManagerAudio = GetComponent<AudioSource>();
if(gameManagerAudio==null)
{
gameManagerAudio = gameObject.AddComponent<AudioSource>();
}
So far the audio definitely makes a difference – especially if I got the levels right. OK, I still didn’t hear it but that method is doubled up anyway so I should just remove the duplicated “enemy running over a powerup” method. Aaah, no they are different- AmmoBehaviour is for flying draino while AmmoPickupObject is for the stationary ammo (two very different objects). Done, it turned out my ammo didn’t have a big enough collider so it wasn’t colliding. Aah- it turns out you can’t play a sound on a prefab if that prefab is being destroyed (ie. it won’t play if it’s attached). So I’ll remove it from the prefab ammo and never add a sound to a ammo object or anything that will be destroyed 🙂 Another bug squashed – I’m getting good at this! I’m also preferring the scripting to add the Audio Source as it’s one less thing to worry about. Still the audio of being brushed aside doesn’t continue if the animal or object gets destroyed. Best if I add the audio to a static object. Like the Game Controller. There would be multiple ways of doing this but with it’s destruction it’s probably best just to call a function/method. Nope,this seems like a waste of time- I could fix it if I had to but it’s not worth it. That being said the death audio should be included outside of the object. Nice, sounds perfectly awful. It sounds so much better with audio.
I can now delete one of my scripts as the collision it contained is now being handled inside a larger one. I exported my project first just to be safe. I think I can ship with this 🙂 There are more than a few comments but I think that’s fine. I’ve gotta make the triggers less wide, increase the time it takes for a pipe to be full (20), and check the ammo isn’t too wide in terms of a collider. Yes! Complete!