Puis-je exécuter mon propre script de chargement pendant l'écran de démarrage Unity?

10

Puis-je charger des données en arrière-plan pendant que l'écran de démarrage Unity est activé? Si c'est le cas, comment?

J'essaie d'exécuter du code pendant l'écran de démarrage, pas seulement de charger des actifs.

Je n'ai trouvé aucune information à ce sujet dans Google ou dans la documentation Unity .

Evorlor
la source
2
Je pense que Unity charge déjà toute votre application lorsque l'écran de démarrage est visible. Je ne pense pas que ce que vous voulez faire soit possible, mais j'aimerais me tromper cette fois.
Hellium
2
Cela ressemble un peu à un problème XY: pourquoi voulez-vous charger des trucs pendant cet écran?
doppelgreener
1
Tout ce que vous mettez dans la première scène de votre jeu est chargé pendant que l'écran de démarrage est en place, non? Alors, ne suffirait-il pas d'inclure le contenu que vous souhaitez charger dans cette première scène (hors caméra, désactivé ou simplement référencé si vous ne voulez pas que ce contenu soit visible immédiatement)? Ou essayez-vous de charger du contenu à partir d'une autre source, comme un serveur Web?
DMGregory
@DMGregory Grand point. J'ai mis à jour la question. J'essaie d'exécuter du code.
Evorlor
Nous comprenons que vous essayez d'exécuter du code (les scripts de chargement sont nécessairement du code) - mais quel code et pourquoi? Vous avez un problème et vous avez décidé que la solution consiste à exécuter ce code pendant l'écran de démarrage Unity; pourquoi donc?
doppelgreener

Réponses:

9

Je viens de faire quelques tests et j'ai découvert que le constructeur des objets de la première scène était en fait appelé alors que l'écran de démarrage était toujours affiché.

Voici quelques timings que j'ai mesurés avec un chronomètre statique:

Constructed  0     s
Awake        2.118 s
OnEnable     2.12  s
Start        2.744 s
First Update 2.919 s

Il semble donc que nous pouvons déclencher un script pour qu'il s'exécute près de 3 secondes avant la fin de l'écran de démarrage (avec les paramètres par défaut) en le déclenchant depuis le constructeur. Vous pouvez essayer de déclencher votre code de chargement (éventuellement sur son propre thread) à partir de là.

Sachez simplement que cela est probablement appelé depuis le thread de chargement, donc comme nous ne sommes pas sur le thread principal, nous serons un peu plus limités avec ce que nous sommes autorisés à faire ici. S'il y a une chose spécifique que vous essayez de faire qui n'est pas prise en charge sur le fil de chargement, pensez à publier une nouvelle question avec les détails de votre application et nous pouvons essayer de trouver une solution de contournement pour ce cas.

DMGregory
la source
1
3 secondes avant la fin, tu veux dire, une seconde avant le début?
Jacob
Dans mes expériences, mon script obtient son premier Update()tick 2,9 secondes après le tir du constructeur. C'est à peu près tout ce que je peux discerner avec l'instrumentation actuelle.
DMGregory
2

Votre meilleur pari est de créer votre propre écran de chargement et de le définir comme scène initiale. Ensuite, à partir de cette scène simple, utilisez le gestionnaire de scènes pour charger la scène suivante en arrière-plan, de manière asynchrone .

Je ne trouve aucune information pour le confirmer, mais d'après mon observation, il semble que Unity charge votre scène initiale pendant que l'écran de démarrage est affiché.

Sur certaines plates-formes, le jeu commence à s'exécuter avant que l'écran de démarrage ne disparaisse, si le chargement est assez rapide.

Tout cela peut changer à tout moment, sur toute plateforme, sur toute mise à jour de version. Il n'y a aucune garantie que cela soit cohérent, il est donc préférable d'utiliser votre propre écran de chargement.

Stéphane Hockenhull
la source
Des écrans à double chargement, c'est ce que vous proposez?
Evorlor
Essentiellement oui. C'est la façon de le faire avec Unity. Mettez un écran de démarrage / chargement pour votre jeu ou une animation de logo de studio pendant qu'il charge la scène suivante.
Stephane Hockenhull
1
@Evorlor c'est ce que je fais avec mon jeu et ça marche parfaitement bien. Bien que cela ne vous laisse pas utiliser le temps que prend l'intro Unity, car cette intro peut être assez courte, vous pouvez simplement créer un écran de chargement (même générique) et l'utiliser pour le vôtre.
John Hamilton
-1

La réponse courte est non , vous ne pouvez pas faire ça.

Les deux réponses ci-dessus sont correctes en termes de gestion de scène. Vous pouvez utiliser Scene Manager pour charger la scène et comme il s'agit de la synchronisation, vous pouvez exécuter d'autres codes en parallèle.

Consultez la documentation de SceneManager.LoadScene pour plus de détails.

Le plus proche possible de l'exécution de votre code le plus rapidement possible après le démarrage du jeu est de l'exécuter à partir de la première scène avec une empreinte minuscule. Appelons ça Splash Scene . La seule chose qu'il contiendrait est votre image de démarrage et votre contrôleur exécutant le code nécessaire et chargeant une autre scène.

Puisqu'il a une faible empreinte, il se chargera très rapidement et fera ainsi fonctionner votre code presque instantanément. Vous pouvez ensuite faire ce que vous avez à faire et charger ensuite Autre scène .

Une autre chose que vous pouvez essayer est de supprimer "écran de démarrage", de supprimer toutes les images que vous souhaitez y afficher. Ce sera juste un peu plus rapide car il ne sera pas chargé initialement.

Donc, le flux serait quelque chose comme ceci:

  1. Écran de démarrage (pas d'image ici, il suffit de le rendre noir)
  2. Scène Splash (petite empreinte avec votre code initial et le chargeur de scène suivant)
  3. Scène d'intro (scène d'intro régulière)
  4. .... (autres scènes comme d'habitude)

Plus la scène est petite, plus elle se charge rapidement. Vous pouvez utiliser quelque chose comme un contrôleur Splash attaché à n'importe quel objet dans l' écran Splash chargé .

using UnityEngine;
using UnityEngine.SceneManagement;

public class SplashController: MonoBehaviour
{
    void Start()
    {

        // RunSomeSyncMethod();

        SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive);
    }
}
IndieForger
la source