El personaje y el controlador

1

Introducción: De la idea al desarrollo

2

Estructura de carpetas en Unity

3

Assets, Game Objects y Sprite Atlas

4

Animaciones desde un sprite map

5

Animation Controller y Transiciones

6

Plataformas y gravedad

7

Física en Unity

8

El script de control

9

Programando funciones en C# y Unity: Jump

10

Detectar el suelo con Raycast

11

Herramientas de debugging visual

12

Cambiar las animaciones según los estados

13

Reto: Terminando nuestras animaciones

14

Solución del reto

15

Hacer que el personaje camine

El manager del videojuego

16

Cómo funciona el Game Manager

17

El Singleton

18

El modo de juego

19

Input manager y juegos multiplataforma

20

Corrección del Bug del salto

21

La zona de muerte

22

Reiniciar la partida

23

Corrigiendo los bugs al reiniciar nuestro juego

Diseño procedural de niveles 2D

24

El diseño de niveles a mano

25

Configurando nuestros assets para el diseño procedural

26

Generación procedural de niveles

27

Creando la zona que eliminará bloques del nivel excedentes

28

Añadir un nuevo bloque de forma aleatoria

29

La cámara que sigue al jugador

30

Destrucción de bloques antiguos

31

Terminando de programar la destrucción de bloques antiguos

32

Solucionando el salto de la cámara al reiniciar el juego

HUD, menús y gameplay

33

El canvas en Unity

34

Uso de botones para crear un menú

35

La lógica de los menús

36

Ejercicio: Preparando el menú del juego

37

Programando el menú del juego

38

Los coleccionables del juego

39

Actualizar UI de coleccionables

40

Iniciando con pociones y maná

41

Pociones de vida y maná

42

Programando las barras de vida y maná

43

Calculando los puntajes con la distancia y el tiempo de juego

44

La lógica del maná

Enemigos y dificultad

45

Plataformas móviles

46

Iniciar movimiento de la plataforma con trigger

47

Enemigos móviles

48

Enemigos móviles: preparando nuestro enemigo para girar

49

Enemigos móviles: programando que fire al chocar

50

Arreglando el collider de nuestra roca

51

Programando la condición de muerte del personaje

52

Añadiendo música de fondo a nuestro videojuego

53

Añadiendo efectos de sonido y cierre del curso

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de C# para Videojuegos

Curso de C# para Videojuegos

Juan Gabriel Gomila

Juan Gabriel Gomila

Añadir un nuevo bloque de forma aleatoria

28/53
Recursos

Vamos a trabajar con Object Pooling, una técnica para reciclar los elementos de nuestro videojuego y evitar sobrecargar la memoria RAM a medida que añadimos estos objetos a la pantalla del videojuego.

Un muy buen ejemplo son los videojuegos de disparos (Call of Duty, por ejemplo), renderizar las balas a medida que los jugadores disparan seria muy costoso, en vez de eso, se reutiliza una cierta cantidad de balas para que después de ser disparadas, sigan su trayectoria y vuelven a la recamara para ser reutilizadas más adelante.

En esta clase, vamos a utilizar esta técnica en nuestro script LevelManager para crear, destruir y mover los objetos de nuestro videojuego sin sobrecargar la memoria.

Aportes 27

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Si saben que su código está bien, pero al generar los niveles se desfasan, no olviden que su LevelManager debe de estar en la posición 0,0,0 (x,y,z)

😪 es satisfactorio decir que he podido arreglar un error que se me presento en el proceso de la clase, fue causado por la cordenada z en los EndGame y StartGame, aunque no se utilizaba esta cordenada se alteraba haciendo cambios minimos de 0.425 o 0.28 etc, a lo que al intentar de aliniarce StartGame y EndGame no se encontraban y me daba un mundo cada vez mas alto (vertical) y no normal (horizontal). Psss no es la gran cosa el descubrimiento pero es satisfactorio encontrar el error que tantos problemas me dio 😅😁

Por si quieren hacer la tarea: Random.Range - Unity 🤓 👌 📖.

Como funciona la correccion, mientras el metodo AddLevelBlock es llamado.
.

El primer bloque de juego es instanciado de acuerdo a los valores obtenidos en la corrección.
.

El segundo bloque de juego es instanciado de acuerdo a los valores obtenidos en la corrección.

Instantiate: Optimiza creando clones de los Prefab. Mas informacion sobre su funcionamiento y reciclaje de de balas en el siguiente link :

https://unity3d.com/es/learn/tutorials/topics/scripting/instantiate

Tambien se puede dejar el código así para que quede un poco más claro

void InsertLevelBlock()
    {
        int rand_i = Random.Range(0, allTheLevelBlock.Count);
        LevelBlock newBlock;
        Vector3 currentEndPosition;

        if (currentLevelBlocks.Count == 0)
        {
            newBlock = Instantiate(allTheLevelBlock[0]);
            currentEndPosition = levelStartPoint.position;
        }
        else
        {
            newBlock = Instantiate(allTheLevelBlock[rand_i]);
            currentEndPosition = currentLevelBlocks[currentLevelBlocks.Count - 1].endPoint.position;
        }

        newBlock.transform.SetParent(this.transform, false);
        newBlock.transform.position = currentEndPosition - newBlock.startPoint.position;
        currentLevelBlocks.Add(newBlock);
    }

Se me complicó un poco el entender la linea 51. Teniendo en cuenta que en mi caso el levelStart es -10 en x y el startPoint del bloque 0 es -14 entonces tenemos en la operación de la corrección para el eje x: 10 - (-14) da un +4. Los bloques se ubican haciendo coincidir la coordenada dada con su centro. Entonces la corrección mueve 14 puntos positivos el bloque, que es la misma distancia que hay desde el centro del bloque hasta el punto inicial del bloque del nivel. Espero esto los ayude a entender mejor. Las coordenadas en el bloque son relativas a el centro del mismo.

Yo hice que el lvl0 solo aparezca solo al principio
en el random(1, allTheLevelBlocks.Count)

No me ha quedado claro algo… ¿por que al asignarle el resultado de la resta de las posiciones del punto final del bloque actual y el inicial del nuevo bloque, a la posición al nuevo bloque, da como resultado el correcto enlazamiento entre ambos bloques?
En pocas palabras, en código lo entiendo, pero en las matemáticas no me cuadra, no se si estoy pasando por alto algo en lo que refiere a las coordenadas globales y locales.

Buenas, alguien sabe como hacer que mi cámara detecte mi player??

Alguien podría explicarme por que se utiliza LevelBlock como tipo de dato para Block… y por que las LISTAS tienen como tipo de dato LevelBlocks

Un mejor metodo para que el spawn no se estropee si el Level Manager no está en el origen es este.

  1. El nuevo bloque toma la posicion del spawn point
  2. El valor de correccion ahora sera igual a la posicion actual del bloque, mas la resta de la posicion actual del bloque menos las posicion del start point del bloque.

De este modo se garantiza que la generacion de bloques emparentados al LevelManager sea correcta

Yo para poder ver lo que hay más allá he usado un paquete de Unity llamado Cinemachine, es muy útil para cámaras 2D y 3D

Wow quede asombrado con la lógica para hacer el pooling. Sugiero que aquí se puede encontrar más información sobre esta u otras técnicas https://www.youtube.com/watch?v=ZRDHEqy2uPI

Hola, cómo están!

Por favor Juan Gabriel, podrías explicar el porqué hace falta la corrección de la posición del bloque que acabamos de generar:

 Vector3 correction = new Vector3(
            spawnPosition.x - block.startPoint.position.x,
            spawnPosition.y - block.startPoint.position.y,
            0);

        block.transform.position = correction;

Entiendo que lo que se hace es calcular el vector que lleva desde la posición “spawnPosition” (la EndPosition del bloque anterior) hasta la block.startPoint.position (que es el StartPoint del bloque que acabamos de generar) ¿por qué se hace?

Al comentar el código de la corrección resulta que todos los LevelBlock se generan en el mismo sitio

https://giphy.com/gifs/RJndoUFDFGo82KGWwj/html5

Al fin pude instanciar los LevelBlocks. Lo ideal es abrir el archivo en Mozilla
https://drive.google.com/file/d/1eMB6NVvw9VLFUExFhKOH3_aVhFOjVTWH/view?usp=sharing

¡Buenísimo! 😃

Me había ocurrido un error al finalizar el script y era que no le habia puesto mi LevelStart a mi LevelManager y tambien que le hice cambios y mi LevelBlock se habia borrado de mi LevelManager y lo que hice fue agregarlo de nuevo, esten atentos y recuerden observar bien para que no les suceda estos pequeños errores

Entre a este curso para aprender C# para videojuegos, pero no estoy aprendiendo nada, sigo el curso al pie de la letra pero cada que se programa no comprendo el porque de las cosas? que me sugieren hacer?

alguien que me ayude a entender bien esta logica de la linea 51 eb el level manager???

Que solución tan pro para crear niveles y no consumir mucha memoria!

Si les da un error de null en el 'Instantiate", les recuerdo (para que no les pase como a mi) que para todos los bloques de niveles se usa el mismo script. 😛

Al darle play y ejecutarse el código los primeros 3 bloques de nivel que se generan se generan del lado izquierdo de la pantalla, es decir en el negativo de la y, los bloques del 4 en adelante se colocan correctamente, podrían ayudarme a solucionarlo, por favor.

Aquí dejo mi código.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevelManager : MonoBehaviour
{

    public static LevelManager sharedInstance;

    public List<LevelBlock> allTheLevelBlocks = new List<LevelBlock>();

    public List<LevelBlock> currentLevelBlocks = new List<LevelBlock>();

    public Transform levelStartPosition;

    private void Awake()
    {
        if(sharedInstance == null)
        {
            sharedInstance = this;
        }
    }

    void Start()
    {
        GenerateInitialBlocks();
    }

    void Update()
    {
        
    }

    public void AddLevelBlock()
    {
        int randomIdx = Random.Range(0, allTheLevelBlocks.Count);

        LevelBlock block;

        Vector3 spawnPosition = Vector3.zero;

        if(currentLevelBlocks.Count == 0)
        {
            block = Instantiate(allTheLevelBlocks[0]);
            spawnPosition = levelStartPosition.position;
        }
        else
        {
            block = Instantiate(allTheLevelBlocks[randomIdx]);
            spawnPosition = currentLevelBlocks[currentLevelBlocks.Count - 1].endPoint.position;
        }

        block.transform.SetParent(this.transform, false);

        Vector3 correction = new Vector3(spawnPosition.x - block.startPoint.position.x,
                                         spawnPosition.y - block.startPoint.position.y, 0);
        block.transform.position = correction;
        currentLevelBlocks.Add(block);
    }

    public void RemoveLevelBlock()
    {

    }

    public void RemoveAllLevelBlocks()
    {

    }

    public void GenerateInitialBlocks()
    {
        for(int i = 0; i < 2; i++)
        {
            AddLevelBlock();
        }
    }

}

En el minuto 6.59 habla de que si el primer bloque es igual a 0 pero no entiendo bien la logica de este IF

¿me ayudas?

me sale error en la linea que dice “block.transform.SetParent(this.transform, false);”

El error es este: " error CS1061: ‘LevelBlock’ does not contain a definition for ‘Transform’ and no accessible extension method ‘Transform’ accepting a first argument of type ‘LevelBlock’ could be found (are you missing a using directive or an assembly reference?)"

Creo que se refiere a que block es una clase que no hereda propiedades de unity, por lo que no lleva transform. Pero si ese es el caso como es que al profesor le funciona.

Ayudaaaa

Genial

por que el GameManager no hace el trabajo del LevelManager ?