unity una tiempo scripts script posicion para otro obtener objeto llamar functions funcion español destruir deltatime contador c# unity3d

c# - una - time.deltatime unity español



Unity manager de juegos. El script solo funciona una vez (3)

Estoy haciendo un simple administrador de juegos. Tengo un script, al que se podrá acceder desde todas las escenas del juego. Y necesito verificar los valores de sus variables después de cargar una nueva escena. Pero mi código se ejecuta solo una vez después de comenzar la simulación mientras existe un objeto con este script en todas las escenas. ¿Qué está mal? ¿Por qué no funciona después de cargar una nueva escena?


En cada proyecto de Unity debes tener una ESCENA DE PRELIGENCIA.

Es bastante confuso que Unity no tenga una escena de precarga "incorporada".

Agregarán este concepto en el futuro.

Para repetir, literalmente debes tener una escena de precarga.

Es así de simple.

¡Este es el ENTENDIMIENTO MÁS GRANDE PARA LOS nuevos programadores que prueban Unity!

Afortunadamente, es extremadamente fácil tener una escena de precarga.

Paso 1.

Haz una escena llamada "precarga". Debe ser la escena 0 en Build Manager.

Paso 2.

En la escena de "precarga", haga un GameObject vacío llamado, digamos, "__app".

Simplemente, coloque DontDestroyOnLoad en ''__app''.

Nota:

Este es el único lugar en todo el proyecto que utiliza DontDestroyOnLoad .

Es así de simple.

En el ejemplo: los desarrolladores han creado un script DDOL de una línea.

Pon ese script en el objeto "__app".

Nunca más tendrás que pensar en DDOL.

Paso 3

Su aplicación tendrá (muchos) "comportamientos generales". Entonces, cosas como la conectividad de la base de datos, efectos de sonido, puntuación, etc.

Debe, y solo puede, poner sus comportamientos generales en "_app".

Es realmente así de simple.

Los comportamientos generales están entonces, por supuesto, disponibles en todas partes del proyecto, en todo momento y en todas las escenas .

¿De qué otra manera podrías hacerlo?

En el ejemplo de imagen anterior, observe "Iap" ("compra en la aplicación") y los demás.

Todos sus "comportamientos generalmente necesarios" - efectos de sonido, puntuación, etc. - están ahí en ese objeto.

Importante...

Esto significa que, por supuesto, naturalmente

... sus comportamientos generales, por supuesto, tendrán inspectores comunes como todo lo demás en Unity.

Puedes usar todas las características habituales de Unity, que usas en cualquier otro objeto del juego.

Por supuesto, puede usar las variables habituales del Inspector (arrastrar para conectar), configuraciones, etc.

(De hecho: supongamos que lo contrataron para trabajar en un proyecto existente. Lo primero que hará es echar un vistazo a la escena de precarga. Verá todos los "comportamientos generales" del proyecto en un solo lugar. Efectos de sonido , puntuación, AI, etc. Verá instantáneamente todas las configuraciones para esas cosas como variables de Inspector ... volumen de voz, ID de tienda de juegos, etc.)

Aquí hay un ejemplo de comportamiento general de "Efectos de sonido":

Parece que también hay un comportamiento general de "voz en off" y un comportamiento general de "música".

Repetir. Con respecto a sus "comportamientos generales". (Efectos de sonido, puntuación, social, etc., etc.) SOLO PUEDEN IR en un objeto del juego en la escena de precarga.

Esto no es opcional: ¡no hay alternativa!

Ya terminaste

Honestamente es así de simple.

¡Literalmente no hay nada!

Muchos ingenieros que vienen de otros entornos quedan atrapados en esto, porque parece que "no puede ser tan fácil".

Solo para repetir: todo el problema es que (extrañamente) Unity simplemente se olvidó de "construir" una escena de precarga. Entonces, simplemente haga clic para agregar una escena de precarga, y no olvide agregar DDOL en la escena de precarga.

Entonces, durante el desarrollo:

Siempre comienza tu juego desde la escena de precarga.

Es así de simple.

(Un punto importante: su aplicación ciertamente tendrá escenas "tempranas". Por ejemplo, una "pantalla de bienvenida" o un "menú". Tenga en cuenta que no puede usar "pantalla de bienvenida" o "menú" como la escena de precarga. Debe literalmente tiene "una escena de precarga" . La escena de precarga cargará su escena de bienvenida, menú de escena o lo que desee).

El tema central: "encontrar" los de otros scripts:

Entonces tienes una escena de precarga.

Todos sus "comportamientos generales" están simplemente en la escena de precarga.

A continuación, tiene el problema de encontrar, simplemente, "SoundEffects" o "GameManager".

Debes poder encontrarlos fácilmente, desde cualquier script en cualquier objeto del juego en cualquiera de tus escenas.

Afortunadamente es muy fácil , es una línea de código.

No es un problema:

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

Haga eso en Awake , para cualquier script que lo necesite.

Honestamente es así de simple. Eso es todo al respecto.

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

Se produce una tremenda confusión debido a los cientos de ejemplos de código absolutamente incorrectos que se ven en línea. Además, los nuevos ingenieros de Unity "no pueden creer" ¡es así de fácil!

Realmente es así de fácil, ¡honesto!

Es totalmente extraño que Unity se haya olvidado de agregar una "escena de precarga" incorporada, en algún lugar para conectar sus sistemas como SoundEffects, GameManager, etc. Es solo una de esas cosas raras de Unity. Entonces, lo primero que debe hacer en cualquier proyecto de Unity es simplemente hacer clic una vez para crear una escena de precarga.

¡Eso es!

Un detalle...

Tenga en cuenta que, si realmente desea escribir incluso menos (!) Líneas de código, es notablemente fácil: ¡puede usar un global para cada una de estas cosas!

Esto se explica en detalle here (puede usar mi popular script Grid.cs) y en la respuesta @Frits a continuación.

(Ya sea que use un global, o simplemente tenga una variable local en cada componente que necesita ese particular, es solo una cuestión de estilo de código. En situaciones muy inusuales, el enfoque "global" puede ser eficaz (como con cualquier global).)

DylanB pregunta: " Durante el desarrollo es bastante molesto que tengas que hacer clic en la escena de precarga cada vez que hagas clic en" Reproducir ". ¿Se puede automatizar?"

Claro, cada equipo tiene una forma diferente de hacer esto. Aquí hay un ejemplo trivial:

// 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"); } } }

Pero no olvides: "¿qué más puedes hacer?" Los juegos tienen que comenzar desde una escena de precarga. ¿Qué más puedes hacer, aparte de ir a la escena de precarga, para comenzar el juego? También puede preguntar "es molesto iniciar Unity para ejecutar Unity, ¿cómo evitar iniciar Unity?" Los juegos, por supuesto, simplemente tienen que comenzar desde una escena de precarga, ¿cómo podría ser? Por lo tanto, debe trabajar con "hacer clic en la escena de precarga antes de hacer clic en Reproducir" cuando trabaje en Unity. ¿De qué otra manera podría ser?


@Fattie: Gracias por elaborar todo esto, ¡es genial! Sin embargo, hay un punto en el que las personas están tratando de comunicarse contigo, y yo también lo intentaré:

¡No queremos que cada instancia de todo en nuestros juegos móviles haga un "FindObjectOfType" para todas y cada una de las "clases globales"!

En cambio, puede hacer que use una instanciación de un estático / un Singleton de inmediato, ¡sin buscarlo!

Y es tan simple como esto: escriba esto en qué clase desea acceder desde cualquier lugar, donde XXXXX es el nombre de la clase, por ejemplo, "Sonido"

public static XXXXX Instance { get; private set; } void Awake() { if (Instance == null) { Instance = this; } else { Debug.Log("Warning: multiple " + this + " in scene!"); } }

Ahora en lugar de tu ejemplo

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

Simplemente utilícelo, sin mirar, y sin variables adicionales, simplemente así, desde cualquier lugar:

Sound.Instance.someWickedFunction();

Alternativamente (técnicamente idéntico), simplemente use una clase global, generalmente llamada Grid, para "mantener" cada una de ellas. here . Asi que,

Grid.sound.someWickedFunction(); Grid.networking.blah(); Grid.ai.blah();


Aquí es cómo puede comenzar cualquier escena que desee y asegúrese de reintegrar su escena _preload cada vez que presione el botón de reproducción en el editor de la unidad. Hay nuevos atributos disponibles desde Unity 2017 RuntimeInitializeOnLoadMethod , más sobre esto here .

Básicamente, tiene un plano simple clase c # y un método estático con RuntimeInitializeOnLoadMethod en él. Ahora, cada vez que inicies el juego, este método cargará la escena de precarga por ti.

using UnityEngine; using UnityEngine.SceneManagement; public class LoadingSceneIntegration { #if UNITY_EDITOR public static int otherScene = -2; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void InitLoadingScene() { Debug.Log("InitLoadingScene()"); int sceneIndex = SceneManager.GetActiveScene().buildIndex; if (sceneIndex == 0) return; Debug.Log("Loading _preload scene"); otherScene = sceneIndex; //make sure your _preload scene is the first in scene build list SceneManager.LoadScene(0); } #endif }

Luego, en su escena _preload, tiene otro script que volverá a cargar la escena deseada (desde donde comenzó):

... #if UNITY_EDITOR private void Awake() { if (LoadingSceneIntegration.otherScene > 0) { Debug.Log("Returning again to the scene: " + LoadingSceneIntegration.otherScene); SceneManager.LoadScene(LoadingSceneIntegration.otherScene); } } #endif ...