Unity Game Manager. Script Works Only One Time

Unity game manager. Script works only one time

In every Unity project you must have A PRELOAD SCENE.

It is quite confusing that Unity does not have a preload scene "built-in".

They will add this concept in the future.

Fort now you have to click to add a preload scene yourself.

This is the SINGLE GREATEST MISUNDERSTANDING for new programmers trying Unity!


Fortunately, it is extremely easy to have a preload scene.

Step 1.

Make a scene named "preload". It must be scene 0 in Build Manager.

Sample Image

Step 2.

In the "preload" scene make an empty GameObject called, say, "__app".

Simply, put DontDestroyOnLoad on '__app'.

Note:

This is the only place in the whole project you use DontDestroyOnLoad.

It's that simple.

Sample Image

In the example: the developers have made a one-line DDOL script.

Put that script on the "__app" object.

You never have to think about DDOL again.

Step 3

Your app will have (many) "general behaviors". So, things like database connectivity, sound effects, scoring, and so on.

You must, and can only, put your general behaviors on "_app".

It's really that simple.

The general behaviors are then - of course - available everywhere in the project, at all times, and in all scenes.

How else could you do it?

In the image example above, notice "Iap" ("in-app purchase") and the others.

All of your "generally-needed behaviors" - sound effects, scoring, and so on - are right there on that object.

Important...

This means that - of course, naturally -

...your general behaviors will have ordinary Inspectors, just like everything else in Unity.

You can use all the usual features of Unity, which you use on every other game object. Inspector variables, drag to connect, settings, and so on.

(Indeed: say you've been hired to work on an existing project. The first thing you will do, is glance at the preload scene. You will see all the "general behaviors" in the preload scene - sound effects, scoring, AI, etc etc. You will instantly see all the settings for those things as Inspector variables ... speech volume, playstore ID, etc etc.)

Here's an example "Sound effects" general behavior:

Sample Image

Looks like there's also a "voice over" general behavior, and a "music" general behavior".

To repeat. Regarding your "general behaviors". (Sound effects, scoring, social, etc etc.) These CAN ONLY GO on a game object in the preload scene.

This is not optional: there's no alternative!

It's that easy.

Sometimes engineers coming from other environments get caught up on this, because it seems like "it can't be that easy".

To repeat, Unity just plain forgot to "build-in" a preload scene. So, you simply click to add your preload scene. Don't forget to add the DDOL.

So, during development:

Always start your game from Preload scene.

It's that simple.

Important: Your app will certainly have "early" scenes. Examples:

  • "splash screen"
  • "menu"

Note. Tou CAN NOT use splash or menu as the preload scene. You have to literally have a separate preload scene.

The preload scene will then load your splash or menu or other early scene.



The central issue: "finding" those from other scripts:

So you have a preload scene.

All of your "general behaviors" are simply on the preload scene.

You next have the problem of, quite simply, finding say "SoundEffects".

You have to be able to find them easily, from, any script, on any game object, in any of your scenes.

Fortunately it is dead easy, it is one line of code.

Sound sound = Object.FindObjectOfType<Sound>();
Game game = Object.FindObjectOfType<Game>();

Do that in Awake, for any script that needs it.

It's honestly that simple. That's all there is to it.

Sound sound = Object.FindObjectOfType<Sound>();

Tremendous confusion arises because of the 100s of absolutely wrong code examples seen online.

It really is that easy - honest!

It's bizarre that Unity forgot to add a built-in "preload scene" - somewhere to attach your systems like SoundEffects, GameManager, etc. It's just one of those weird thing about Unity. So, the first thing you do in any Unity project is just click once to make a preload scene.

That's it!



A Detail...

Note that, if you really want to type even less (!) lines of code, it's remarkably easy - you can just use a global for each of these things!

This is explained in detail here , many folks now use something like this, a Grid.cs script ...

 using Assets.scripts.network;
using UnityEngine;

static class Grid
{
public static Comms comms;
public static State state;
public static Launch launch;
public static INetworkCommunicator iNetworkCommunicator;
public static Sfx sfx;

static Grid()
{
GameObject g = GameObject.Find("_app");

comms = g.GetComponent<Comms>();
state = g.GetComponent<State>();
launch = g.GetComponent<Launch>();
iNetworkCommunicator = g.GetComponent<INetworkCommunicator>();
sfx = g.GetComponent<Sfx>();
}
}

Then, anywhere in the project you can say

Grid.sfx.Explosions();

It's just that easy, that's the whole thing.

Don't forget that each of those "general systems" is on, and can only be on, the DDOL game object in the preload scene.


DylanB asks: "During development it's quite annoying that you have to click to the preload scene every time before you click "Play". Can this be automated?"

Sure, every team has a different way to do this. Here's a trivial example:

// this should run absolutely first; use script-execution-order to do so.
// (of course, normally never use the script-execution-order feature,
// this is an unusual case, just for development.)
...
public class DevPreload:MonoBehaviour
{
void Awake()
{
GameObject check = GameObject.Find("__app");
if (check==null)
{ UnityEngine.SceneManagement.SceneManager.LoadScene("_preload"); }
}
}

But don't forget: what else can you do? Games have to start from a preload scene. What else can you do, other than click to go to the preload scene, to start the game? One may as well ask "it's annoying launching Unity to run Unity - how to avoid launching Unity?!" Games simply, of course, absolutely have to start from a preload scene - how else could it be? So sure, you have to "click to the preload scene before you click Play" when working in Unity - how else could it be?

Script code only seems to work on single instance of prefb

I understood from your post that you are always calling PlatformFall instance assigned from inspector. I think this changes will solve your problem.

public class CharacterController2D : MonoBehaviour {
private PlatformFall platfall;
private RaycastHit2D isFallingPlatform;

void FixedUpdate(){
isFallingPlatform = Physics2D.Linecast(_transform.position, groundCheck.position, WhatIsFallingPlatform);
if (isFallingPlatform)
{
Debug.Log("Here");
platfall = isFallingPlatform.transform.GetComponent<PlatformFall>();
platfall.startFall();
}
}
}

By the way, i assume that you put prefab to proper position to cast. And one more thing, you should make physics operations ,which affect your rigidbody, in FixedUpdate.

When I use this script, it crashes my game. What am i doing wrong?

The call to

Time.timeScale = 0;

in Start() function stops game time i.e. pauses the game. Remove that.

WaitAndTurnOn should be invoked as a Coroutine:

StartCoroutine(WaitAndTurnOn());

Update function not needed if you are using Coroutines.

void Start()
{
StartCoroutine(WaitAndTurnOn());
}

IEnumerator WaitAndTurnOn()
{
yield return new WaitForSeconds(2);
TurnLightsOn();
}

void TurnLightsOff()
{
Destroy(GetComponent<Light>());
StartCoroutine(WaitAndTurnOn());
}

void TurnLightsOn()
{
gameObject.AddComponent<Light>();
gameObject.GetComponent<Light>().type = 0;
gameObject.GetComponent<Light>().intensity = 1 / 3;
gameObject.GetComponent<Light>().range = 15 / 2;
gameObject.GetComponent<Light>().spotAngle = 165;
}


Related Topics



Leave a reply



Submit