En este tutorial vamos a crear un juego Fruit Ninja con Unity. Nuestro juego tendrá dos escenas:. Una escena título y una escena del juego, donde realmente se juega el juego

Con el fin de seguir este tutorial, que se espera que esté familiarizado con los siguientes conceptos:


  • programación C #
  • Uso inspector Unidad, como la importación de activos, la creación de casas prefabricadas y la adición de componentes

    Tabla de contenidos

    Creación de proyectos e importación de recursos

    Antes de comenzar a leer el tutorial, es necesario crear un nuevo proyecto de la Unidad e importar todos los sprites disponibles a través del código fuente. Con el fin de hacer eso, cree una carpeta llamada Sprites y copiar todos los sprites a esta carpeta. Unidad inspector les importará automáticamente a su proyecto.

    Sin embargo, algunos de esos sprites están en spritesheets, tales como los frutos spritesheet a continuación. En esos casos hay que cortar el spritesheet. Con el fin de hacer eso, tenemos que establecer el modo de Sprite como múltiple y abrir el Editor de Sprite.


    En el Editor de Sprite (que se muestra más abajo), es necesario abrir el menú rebanada y haga clic en el botón de la rebanada, con el tipo de sector tan automático. Por último, el golpe se aplica antes del cierre.

    No se pierda! extremos de la oferta en

    • Accede a los más de 200 cursos
    • Nuevos cursos añadió mensual
    • Cancelar en cualquier momento
    • Los certificados de terminación

      ACCESO ahora

      Pre-Order The Complete Realidad Virtual desarrollo del juego con Unity y aprender a crear juegos y experiencias de inmersión mediante la construcción de 10 juegos de realidad virtual. El curso asume ninguna experiencia previa Unidad o VR – Te enseñaremos C #, la Unidad y la programación 3D de la tierra-para arriba

      comprobarlo en Zenva Academia y obtener acceso temprano!

      archivos de código fuente

      Puede descargar los archivos de código fuente tutorial aquí.

      escena Título

      Vamos a empezar por crear la escena Título. Esta escena se mostrará el título del juego y el botón de reproducción. Una vez que el jugador golpea el botón, el juego comenzará.

      Empecemos creando un nuevo lienzo llama BackgroundCanvas. Este lienzo se mostrará la imagen de fondo, el título del juego y el botón de reproducción. En primer lugar, vamos a establecer su Render Mode ser espacio de pantalla – Cámara (recuerde que debe conectar la cámara principal a ella). A continuación, vamos a establecer su modo Escala de interfaz de usuario a escala con Tamaño de la pantalla. Al final, los BackgroundCanvas debe ser similar a la siguiente figura.


      Ahora vamos a añadir la imagen de fondo a este lienzo. Lo único que tenemos que hacer es definir su fuente de imagen y ajusta su tamaño original. El texto del título está también simple, sólo tenemos que añadir un texto a la lona, ​​configurar su tamaño y alineación, y cambiar el texto que se Fruit Ninja.


      Con el fin de crear el PlayButton tenemos que definir su devolución de llamada OnClick. El PlayButton debe comenzar la escena del juego cuando se hace clic. Por lo tanto, vamos a crear el siguiente script ChangeScene adjuntar a la misma. Este script simplemente tener un método para cargar otra escena le dio su nombre.
      ChangeScene clase pública: MonoBehaviour {public void changeScene (cadena sceneName) {SceneManager.LoadScene (sceneName); }} 1234567publicclassChangeScene: MonoBehaviour {publicvoidchangeScene (stringsceneName) {SceneManager.LoadScene (sceneName);}}

      Ahora que atribuimos este script para PlayButton, y establecer el método de devolución de llamada changeScene como el OnClick. El parámetro será juego, con el fin de iniciar la escena del juego.


      Por ahora, la escena Título debe ser similar a la siguiente figura. Con el fin de probar si el PlayButton está trabajando, es necesario crear otra escena llamada juego, y hay que añadirlo en Archivo -> configuración de generación -.> Escenas en la creación



      Juego escena

      Ahora que tenemos nuestra escena título, vamos a empezar a crear la escena del juego, en la que se realmente se juega el juego.

      Vamos a necesitar otro BackgroundCanvas en la escena del juego. Por ahora, sólo vamos a necesitar el lienzo y el BackgroundImage, que será exactamente el mismo que en el título de escena. Más adelante vamos a añadir algunos otros elementos para mostrar la puntuación del jugador, la vida y más de juego mensaje, pero eso es todo por ahora.

      Creación de frutas

      Lo primero que vamos a añadir en nuestro juego es la creación de la fruta. En nuestras frutas juego será constantemente creada con posiciones aleatorias y velocidades. Con el fin de hacer eso, vamos a necesitar una casa prefabricada de frutas. Por lo tanto, crear una nueva llamada GameObject frutas y hacer que sea una casa prefabricada.

      El prefabricada fruta tendrá un Sprite Renderizador, un Rigidbody2D para moverlo, un colisionador Box 2D para comprobar si hay colisiones con los cortes posteriores y un guión MoveObject. Este script MoveObject será responsable de establecer la velocidad de frutas y destruirlo después de algún tiempo. Por lo tanto, al agregar que necesitamos establecer velocidades máximas y mínimas de la fruta, así como el tiempo de destruir. Además, observe que la fruta se encuentra en una capa llamada Cuttable. Esto será utilizado más tarde para configurar correctamente las colisiones.


      El script MoveObject se muestra a continuación. En el método de inicio que va a seleccionar una velocidad aleatoria para la fruta, por la elección de un valor aleatorio entre la velocidad mínima y máxima (en ambas direcciones). Después de ajustar la velocidad, se llamará al método Destroy, que destruirá el objeto de la fruta después de algún tiempo. El tiempo se define por el atributo destroyTime.
      MoveObject clase pública: MonoBehaviour {[SerializeField] flotador privada minXSpeed, Maxxspeed, minYSpeed, maxYSpeed; [SerializeField] destroyTime flotador privado; // Usar esto para la inicialización de inicio void () {this.gameObject.GetComponent () = .velocity nueva Vector2 (Random.Range (minXSpeed, Maxxspeed), Random.Range (minYSpeed, maxYSpeed)); Destruye (this.gameObject, this.destroyTime); }} 123456789101112131415publicclassMoveObject:. MonoBehaviour {[SerializeField] privatefloatminXSpeed, Maxxspeed, minYSpeed, maxYSpeed; [SerializeField] privatefloatdestroyTime; // Usar esto para initializationvoidStart () {this.gameObject.GetComponent () velocidad = newVector2 (Random.Range ( minXSpeed, Maxxspeed), Random.Range (minYSpeed, maxYSpeed)); Destruye (this.gameObject, this.destroyTime);}}

      Ahora que tenemos la casa prefabricada de frutas, necesitamos frutos de regeneración. Con el fin de hacer eso, vamos a crear un objeto de análisis reproductor y que sea una casa prefabricada con un guión SpawnObjects. Este prefabricada será utilizada para las frutas y las bombas de regeneración, pero por ahora vamos a sólo crean un FruitSpawner (mediante la creación de una copia del mismo llama FruitSpawner en su juego). Como parámetros, necesitamos definir el prefabricada Fruit, el intervalo de desove, los posibles coordenadas a frutas de regeneración (X mínima, máxima X y coordenada Y) y los sprites posible frutales.


      El script SpawnObjects se muestra a continuación. En el método de inicio se llamará InvokeRepeating, para llamar al método spawnObject en cada intervalo de desove. El método spawnObject, por su vez, una instancia de un nuevo objeto (en este caso una fruta), establecer su posición a ser uno de los posibles y seleccionar un sprite azar a ella (a partir de la matriz fruitSprites).
      SpawnObjects clase pública: MonoBehaviour {[SerializeField] privada GameObject prefabToSpawn; [SerializeField] flotador privada spawnInterval, objectMinX, objectMaxX, objectY; [SerializeField] [] objectSprites privadas Sprite; // Usar esto para la inicialización de inicio void () {InvokeRepeating ( «spawnObject», this.spawnInterval, this.spawnInterval); } Privada spawnObject void () {GameObject newObject = Instantiate (this.prefabToSpawn); newObject.transform.position = new Vector2 (Random.Range (this.objectMinX, this.objectMaxX), this.objectY); Sprite objectSprite = objectSprites [Random.Range (0, this.objectSprites.Length)]; newObject.GetComponent () .sprite = objectSprite; }} 123456789101112131415161718192021222324publicclassSpawnObjects: MonoBehaviour {[SerializeField] privateGameObject prefabToSpawn; [SerializeField] privatefloatspawnInterval, objectMinX, objectMaxX, objectY; [SerializeField] privateSprite [] objectSprites; // utilizar esto para initializationvoidStart () {InvokeRepeating ( «spawnObject», this.spawnInterval, this.spawnInterval);} privatevoidspawnObject () {GameObject newObject = Instantiate (this.prefabToSpawn); newObject.transform.position = newVector2 (Random.Range (this.objectMinX, this.objectMaxX), this.objectY); Sprite objectSprite = objectSprites [Random.Range (0, this.objectSprites.Length)]; newObject.GetComponent () = sprites objectSprite;.}}

      a estas alturas, se puede tratar de jugar el juego para comprobar si los frutos están siendo adecuadamente creado en diferentes posiciones y con diferentes velocidades.


      Creación de bombas

      La creación de bombas es muy similar a la creación de las frutas. Vamos a crear una casa prefabricada de la bomba con los mismos componentes que la fruta (Sprite Renderer, MoveObject de guión, y Rigidbody2D BoxCollider2D). Puede cambiar los parámetros de los componentes para hacer el juego menos predecible también.


      A continuación, se crea otra copia del análisis reproductor prefabricada, nombrando la nueva copia como BombSpawner. En este caso, el prefabricada para desovar será la bomba prefabricada, y tendrá sólo una posible sprite.


      Antes de continuar, vamos a cambiar la configuración física de la unidad de hacer las frutas y bombas uncollidable entre sí. Esto se debe a que no queremos que interfieran en cada uno de los otros movimientos.

      Para hacerlo, necesitamos tanto de la fruta y de las casas prefabricadas bomba en la capa Cuttable. A continuación, vamos a la configuración de la Unidad Física 2D (Editar -> Ajustes del proyecto -> Física 2D) y cambiar la capa de colisión Matrix desmarcando la casilla que permite que las colisiones entre objetos de la capa Cuttable. Ahora, las frutas y las bombas no se chocan unos con otros.


      A estas alturas, se puede tratar de jugar el juego para comprobar si las bombas también están siendo creados al azar, y si las colisiones se aplican correctamente.


      frutas y bombas Cortar

      Ahora que tenemos las frutas y las bombas, el jugador debe ser capaz de cortarlos. En primer lugar, vamos a crear un objeto de cortar y lo convierten en una casa prefabricada. se creó esta prefabricada cuando el jugador pasa la pantalla, y chocará con las frutas y las bombas para cortarlas.

      El Corte prefabricada simplemente tendrá un procesador de línea para mostrar la corte y un borde Colisionador de 2D a chocar con las frutas y las bombas. La única cosa que necesitamos un cambio en esos componentes ahora es el color y el ancho de línea Procesador. Puede elegir los valores que prefiera para esos parámetros.


      Ahora vamos a crear un GameObject llamada Espada, que será responsable de la creación de cortes cuando el jugador pasa la pantalla. Este será un objeto invisible, que tiene solamente un script llamado CreateCuts. En este script es necesario definir la Corte prefabricada y el tiempo de cada corte vivirá después de haber sido creado (llamado Cut destruir el tiempo).


      El script CreateCuts se muestra a continuación. En el método de actualización se comprobará para eventos MouseButtonDown y MouseButtonUp. Cuando se hace clic en el ratón (MouseButtonDown), guarda el punto de inicio del golpe. Observamos que tenemos que convertirlo de coordenadas de pantalla a coordenadas mundo. Cuando se suelta el botón del ratón (MouseButtonUp y this.dragging es cierto), se llama al método createCut.

      El método createCut ahorra el punto final de la swipe y crear un objeto Cut (usando el prefabricada Cut). A continuación, se establece la posición de la línea de Procesador de acuerdo con los puntos de inicio y final del golpe. El EdgeCollider2D también está configurado en consecuencia, a excepción de sus coordenadas son en relación con la posición del objeto, por lo que el primer punto debe ser siempre (0, 0), y el punto final debe ser (swipeEnd – swipeStart). Por último, nos fijamos el corte que debe ser destruido después de algún tiempo.
      CreateCuts clase pública: MonoBehaviour {[SerializeField] corte GameObject privado; [SerializeField] cutDestroyTime flotador privado; arrastrando private bool = false; swipeStart Vector2 privado; // actualización se llama una vez por cuadro de actualización de vacío () {if (Input.GetMouseButtonDown (0)) {this.dragging = true; this.swipeStart = Camera.main.ScreenToWorldPoint (Input.mousePosition); } Else if (Input.GetMouseButtonUp (0) && this.dragging) {this.createCut (); }} CreateCut private void () {this.dragging = false; Vector2 swipeEnd = Camera.main.ScreenToWorldPoint (Input.mousePosition); GameObject corte = Instantiate (this.cut, this.swipeStart, Quaternion.identity) como GameObject; cut.GetComponent () .SetPosition (0, this.swipeStart); cut.GetComponent () .SetPosition (1, swipeEnd); Vector2 [] colliderPoints = new Vector2 [2]; colliderPoints [0] = new Vector2 (0.0f, 0.0f); colliderPoints [1] = swipeEnd – this.swipeStart; cut.GetComponent () .points = colliderPoints; Destruye (cut.gameObject, this.cutDestroyTime); }} 123456789101112131415161718192021222324252627282930313233publicclassCreateCuts: MonoBehaviour {[SerializeField] corte privateGameObject; [SerializeField] privatefloatcutDestroyTime; privatebooldragging = false; privateVector2 swipeStart; // actualización se llama una vez por framevoidUpdate () {if (Input.GetMouseButtonDown (0)) {this.dragging = true ; this.swipeStart = Camera.main.ScreenToWorldPoint (Input.mousePosition);} elseif (Input.GetMouseButtonUp (0) && this.dragging) {this.createCut ();}} privatevoidcreateCut () {this.dragging = false; Vector2 swipeEnd = Camera.main.ScreenToWorldPoint (Input.mousePosition); GameObject corte = Instantiate (this.cut, this.swipeStart, Quaternion.identity) asGameObject;. cut.GetComponent () SetPosition (0, this.swipeStart); . cut.GetComponent () SetPosition (1, swipeEnd); vector2 [] colliderPoints = newVector2 [2]; colliderPoints [0] = newVector2 (0.0f, 0.0f); colliderPoints [1] = swipeEnd-this.swipeStart ; cut.GetComponent () puntos = colliderPoints;. Destruye (cut.gameObject, this.cutDestro yTime);}}

      Ya se puede crear algunos cortes, pero no va a hacer nada. Todavía tenemos que comprobar las colisiones con las frutas y las bombas. Vamos a hacer que mediante la adición a las secuencias de comandos de frutas y casas prefabricadas bomba que cheque por colisiones con los recortes.

      Para el prefabricada de frutas, vamos a añadir el siguiente script llamado CutFruit. Este script simplemente poner en práctica el método OnCollisionEnter2D. Si el objeto tiene el chocó la etiqueta cortada (recuerde ajustar correctamente en el prefabricada Cut), que va a destruir la fruta. También es necesario aumentar la puntuación de jugador, pero vamos a hacer eso más tarde, cuando tenemos objetos para mostrar la puntuación.
      CutFruit clase pública: MonoBehaviour {void OnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); }}} 12345678publicclassCutFruit: MonoBehaviour {voidOnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject);}}}

      El script CutBomb (añadido a la casa prefabricada de bomba) será el mismo por el momento. Más adelante vamos a cambiarlo a disminuir el número de jugador de vidas.
      CutBomb clase pública: MonoBehaviour {void OnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); }}} 12345678publicclassCutBomb: MonoBehaviour {voidOnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject);}}}

      Por ahora se puede ya tratar de jugar el juego para frutas cortadas y bombas. Ellos deben ser destruidos cuando se corta.


      Mostrando puntuación y número de vidas

      El siguiente paso en nuestro juego será mostrar la puntuación del jugador y el número de vidas.

      En primer lugar, vamos a crear un objeto ScoreText para mostrar la puntuación del jugador. Este será un objeto de texto dentro de la BackgroundCanvas, con un guión llamado ShowScore.


      El script ShowScore será responsable de actualizar el texto con la puntuación actual. Como se muestra a continuación, esto se hará mediante la creación de un método llamado incrementScore, lo que permitirá actualizar la puntuación actual y el texto que lo muestra. En el método de inicio del texto puntuación se actualiza para mostrar la puntuación inicial.
      ShowScore pública de clase: MonoBehaviour {score private int = 0; // Usar esto para la inicialización de inicio void () {getComponent () .text = «Puntuación:» + this.score; } Public void incrementScore (int incrementValue) {this.score + = incrementValue; GetComponent () .text = «Puntuación:» + this.score; } Public int getScore () {return this.score; }} 123456789101112131415161718publicclassShowScore: MonoBehaviour {privateintscore = 0; // Usar esto para initializationvoidStart () {getComponent () text = «Puntuación:». + This.score;} publicvoidincrementScore (intincrementValue) {this.score + = incrementValue; getComponent . () text = «Puntuación:» + this.score;} publicintgetScore () {returnthis.score;}}

      Ahora tenemos que llamar correctamente el método incrementScore al cortar las frutas. Con el fin de hacer eso, vamos a cambiar el guión CutFruit para encontrar el objeto ScoreText y llamar a su método incrementScore, con un incremento de uno.
      CutFruit clase pública: MonoBehaviour {void OnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); GameObject scoreText = GameObject.Find ( «ScoreText»); scoreText.GetComponent () .incrementScore (1); }}} 12345678910publicclassCutFruit: MonoBehaviour {voidOnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); GameObject scoreText = GameObject.Find ( «ScoreText»); scoreText.GetComponent < ShowScore> () incrementScore (1);..}}}

      para mostrar el número de jugador de la vida, por el contrario, vamos a crear un objeto de imagen, lo llaman vida y que sea una casa prefabricada


      A continuación, vamos a crear un objeto llamado PlayerLives en los BackgroundCanvas. Este objeto tendrá un diseño de grupo de la rejilla, que será utilizado para mostrar la vida. Un Diseño de cuadrícula Grupo layout de forma automática a los niños objeto de acuerdo con algunas configuraciones predefinidas. En nuestro caso queremos que las vidas que se muestran en una sola fila, por lo que vamos a configurar como en la figura siguiente.


      El objeto PlayerLives también tendrá un guión ShowLives, que será responsable de la destrucción de las imágenes vida cuando los cortes jugador bombas. Además, se debe detectar cuando el jugador pierde para mostrar un juego más de mensaje. Con el fin de hacer eso, necesitará el número inicial de la vida, la vida prefabricada, y las referencias a la ScoreText, GameOverGroup y FinalScoreText. Los dos últimos que van a crear más adelante. Así que, por ahora, puede dejarlos en blanco.

      En el método de inicio de ShowLives, se creará una instancia de un objeto de imagen Vida por cada una de las vidas iniciales, guardándolos en una lista. Luego, en el método looseLife, se puede eliminar la última vida en la lista y destruirlo. Si el jugador no tiene más vidas, tenemos que mostrar el juego sobre el mensaje, estableciendo el objeto GameOverGroup como activa. Ya que todavía no tenemos la GameOverGroup simplemente podemos imprimir un mensaje en la consola por ahora. Más adelante vamos a terminar este método.
      ShowLives clase pública: MonoBehaviour {[] SerializeField privadas numberOfLives int; [SerializeField] privada GameObject lifePrefab; List <> GameObject vida privada; [SerializeField] privada GameObject scoreText, gameOverGroup, finalScoreText; // Usar esto para la inicialización de inicio void () {vidas = new List (); for (int lifeIndex = 0; lifeIndex vidas; [SerializeField] privateGameObject scoreText, gameOverGroup, finalScoreText; // Usar esto para initializationvoidStart () {vidas = newList ( ); para (intlifeIndex = 0; lifeIndex Por último, hay que actualizar el guión CutBomb para disminuir el número de vidas cuando una bomba es de corte, de la siguiente manera .
      CutBomb clase pública: MonoBehaviour {void OnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); GameObject playerLives = GameObject.Find ( «PlayerLives»); playerLives.GetComponent () .looseLife (); }}} 12345678910publicclassCutBomb: MonoBehaviour {voidOnCollisionEnter2D (Collision2D colisión) {if (collision.gameObject.tag == «Cut») {Destruir (this.gameObject); GameObject playerLives = GameObject.Find ( «PlayerLives»); playerLives.GetComponent < . ShowLives> () looseLife ();.}}}

      a estas alturas, se puede tratar de jugar el juego para ver si la puntuación y la vida se están actualizando correctamente


      Game over mensaje

      La última cosa que necesitamos hacer está mostrando el juego sobre el mensaje cuando el jugador pierde. Con el fin de hacer eso, vamos a crear un objeto vacío llamado GameOverGroup en los BackgroundCanvas con tres textos como los niños:. GameOverText, FinalScoreText y PlayAgainText


      Los dos primeros simplemente mostrará sus textos. El tercero tendrá también un guión RestartGame.


      Este script se compruebe clics del ratón para volver a la escena del título.
      RestartGame clase pública: MonoBehaviour {// actualización se llama una vez por cuadro de actualización de vacío () {if (Input.GetMouseButtonDown (0)) {SceneManager.LoadScene ( «Título»); }}} 123456789publicclassRestartGame: MonoBehaviour {// actualización se llama una vez por framevoidUpdate () {if (Input.GetMouseButtonDown (0)) {SceneManager.LoadScene ( «Título»);}}}

      Ahora que tenemos el objeto GameOverGroup , vamos a configurarlo como inactiva por defecto. Luego, en el guión ShowLives vamos a configurarlo como activo cuando el jugador pierde el juego (recuerde ajustar correctamente las referencias GameOverGroup y FinalScoreText en el guión).
      public void () {looseLife this.numberOfLives – = 1; GameObject vida = this.lives [this.lives.Count – 1]; this.lives.RemoveAt (this.lives.Count – 1); Destruir (la vida); si (this.numberOfLives == 0) {this.scoreText.SetActive (false); this.gameOverGroup.SetActive (true); this.finalScoreText.GetComponent () .text = «Su puntuación fue» + this.scoreText.GetComponent () .getScore (); }} 123456789101112publicvoidlooseLife () {this.numberOfLives- = 1; GameObject vida = this.lives [this.lives.Count-1]; this.lives.RemoveAt (this.lives.Count-1); Destruye (vida); si (this.numberOfLives == 0) {this.scoreText.SetActive (falsas); this.gameOverGroup.SetActive (true);. this.finalScoreText.GetComponent () text = «Su puntuación fue» + this.scoreText. getComponent () getScore ();..}}

      Por último, ahora se puede tratar de jugar el juego con todas sus características hasta que muestre el juego sobre el mensaje


      Y con esto concluye este tutorial. Que me haga saber en la sección de comentarios sus opiniones y preguntas!

      Mensajes relacionados
      > <img src =

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *