Estoy tratando de que mi GameObject (asteroide) aparezca continuamente en el juego. Busqué y seguí este tutorial: https://pressstart.vip/tutorials/2018/09/25/58/spawning-obstacles.html . Para hacer que el asteroide se mueva, creé este script (AsteroidObject) y para generar los objetos, creé este script (DeployAsteroids). No hay errores y Debug.Log aparece en la consola. Pero el objeto del juego de asteroides no se puede ver y no se generará. ¿Alguien puede ayudar? ¡Gracias por adelantado!
Códigos de objetos de asteroides:
public class AsteroidObject : MonoBehaviour { public float speed = 10.0f; //how fast the asteroid will move private Rigidbody2D rb; private Vector2 screenBounds; //screenbounds calculation // Start is called before the first frame update void Start() { rb = this.GetComponent<Rigidbody2D>(); //find rigidbody 2d and set it to rb reference by using the getcomponent rb.velocity = new Vector2(-speed, 0); //moving the asteroid from right to left by setting the x value, leaving the y value 0 so that it will not move up and down screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z)); //defines the boundaries of the screen on the x and y axis } // Update is called once per frame void Update() { //transform.position = new Vector3(Mathf.Clamp(transform.position.x, -9f, 9f), //Mathf.Clamp(transform.position.y, -4f, 4f), transform.position.z); if (transform.position.x < screenBounds.x) //check if it is moving to the left of the screen { Destroy(this.gameObject); Debug.Log("hello world"); } } }Implementar códigos de asteroides:
public class DeployAsteroids : MonoBehaviour { public GameObject asteroidPrefab; public float respawnTime = 1.0f; private Vector2 screenBounds; // Start is called before the first frame update void Start() { screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z)); StartCoroutine(asteroidWave()); } private void spawnEnemy() { GameObject a = Instantiate(asteroidPrefab) as GameObject; a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y)); } IEnumerator asteroidWave() { while (true) { yield return new WaitForSeconds(respawnTime); spawnEnemy(); //Debug.Log("Hello World"); } } }hasta lo dices tu mismo
el Debug.Log aparece en la consola.
Bueno, inicias sesión en el momento en que destruyes tu objeto => ya se ha ido.
Destroy(this.gameObject); Debug.Log("hello world");A menos que se refiera al registro comentado después del método de generación. Todavía destruyes inmediatamente el objeto. Creo que lo detectaría de inmediato si usara registros útiles y no dos veces el mismo
Debug.Log("Spawned a new object");y
Debug.Log("Destroyed an object");Entonces, ¿qué está pasando exactamente entonces?
¡Inmediatamente destruyes los nuevos objetos generados!
tú haces
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));que almacena la posición en el borde derecho de la pantalla.
Digamos, por ejemplo, en algún lugar en x = 2; (número de ejemplo imaginario aleatorio total).
Luego, justo después del desove, lo configuras en
a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y)); Entonces, para la x, la establece en (usando nuestro valor de ejemplo) x = -4;
¡Este ni siquiera es el borde izquierdo de la pantalla, sino incluso más allá!
Además le dices al asteroide que se mueva
rb.velocity = new Vector2(-speed, 0); por lo que suponiendo que el valor de la speed es positivo aún más en la dirección x negativa.
y finalmente lo haces
// Even without the Rigidbody this is already comparing // if(-2 * screenBounds.x < screenBounds.x) // Or with our example numbers // if(-4 < 2) if (transform.position.x < screenBounds.x) { Destroy(this.gameObject); Debug.Log("hello world"); }=> Esta condición siempre será verdadera e inmediatamente destruirá tus objetos en el siguiente cuadro.
Entonces, ¿qué debo hacer en su lugar?
Supongo que está tratando de generar el asteroide en el borde derecho .
Y quiero destruirlo después de que pasó el borde izquierdo . Así que probablemente debería ser
private void spawnEnemy() { GameObject a = Instantiate(asteroidPrefab); Vector3 rightEdgeWorldPoint = Camera.main.ScreenToWorldPoint( new Vector3(Screen.width, Random.Range(0, Screen.height), Camera.main.nearClipPlane); rightEdgeWorldPoint.z = 0f; a.transform.position = rightEdgeWorldPoint; }Y en el asteroide
if (Camera.main.WorldToScreenPoint(transform.position).x < 0) { Destroy(this.gameObject); Debug.Log("Left the screen -> destroyed"); }Nota: escrito en el teléfono inteligente, pero espero que la idea se aclare
Vaya a la jerarquía de escenas y verifique si los asteroides se pueden ver allí. Puede ser que no los veas dentro del juego o en la cámara de escena, pero si están en la escena, se generan en algún lugar. Sería interesante información para actualizar en la pregunta.
No profundicé en el código, pero si están allí, debe verificar o establecer la posición en la que se generan con respecto a la cámara, para que los asteroides estén en el campo de visión.
Compruebe la posición dada en esta línea: a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y)); y si cabe en el campo de visión de la cámara.