Gabriel Souki
Yo me tome la libertad de crear una nueva poción para el mana, que opinan?? 😀 .
Dietmar Cerpa
¡Esta genial! ¡Gracias!
José Alfredo Colmenares
Excelente diseño! Gracias.
La recolección de pociones en Unity es más clara y mantenible cuando el objeto jugador se referencia una sola vez y se notifica con métodos específicos. Aquí verás cómo vincular el PlayerController desde el script Collectable, llamar a los métodos de curación y maná, y preparar las pociones en escena con diferencias visuales claras. Todo con C# y buenas prácticas para evitar errores comunes.
¿Qué solucionamos al recoger pociones en Unity?
Al recoger una poción, ya no se notifica al game manager (como con las monedas en el switch), sino directamente al PlayerController. Como el jugador no es un singleton, se accede por nombre con GameObject.Find y luego con GetComponent para invocar los métodos correctos. Además, se evita el error de declarar la variable del jugador dentro de cada caso del switch.
¿Por qué no usar un singleton para PlayerController?
Porque el PlayerController no es un singleton. Se accede al objeto con nombre en escena usando GameObject.Find("Player") y, desde ahí, al componente del jugador. Es directo y suficiente para esta necesidad.
¿Cómo evitar el conflicto dentro del switch?
El switch no delimita ámbitos como un if/else. Declarar la misma variable en dos casos distintos puede generar conflicto. Se declara una sola referencia al jugador fuera del switch (incluso como campo privado) y se inicializa en Start. Así desaparecen los errores y el código queda más limpio.
¿Cómo notificar al jugador con GameObject.find y getcomponent?
Primero se localiza el objeto jugador por nombre y, después, se llama al componente para aplicar el efecto de la poción. Las llamadas son directas y expresivas: CollectHealth para vida y CollectMana para maná, pasando this.value como cantidad.
// Búsqueda inicial (ejemplo local): GameObject player = GameObject.Find("Player"); // Notificar recolección de poción de vida: player.GetComponent<PlayerController>() .CollectHealth(this.value); // Notificar recolección de poción de maná: player.GetComponent<PlayerController>() .CollectMana(this.value);
¿Dónde inicializar la referencia al player?
Mejor en Start, una sola vez. Así evitas repetir código en cada caso del switch y eliminas el error por duplicidad.
// En Collectable: private GameObject player; void Start() { // Ojo: GameObject con G mayúscula es la clase de Unity. // gameObject con g minúscula es la instancia asociada al script. player = GameObject.Find("Player"); } // Luego, cuando corresponda: player.GetComponent<PlayerController>().CollectHealth(this.value); player.GetComponent<PlayerController>().CollectMana(this.value);
Clave: una sola referencia compartida en la clase evita declarar variables dentro del switch y simplifica las llamadas.
¿Qué diferencia hay entre GameObject y gameObject?
¿Cómo configurar y diferenciar las pociones en escena?
Se parte de un único asset de poción en Sprites. Se arrastra a la escena, se le añade el script Collectable, y se configura su tipo y valor. Luego se duplica para la versión de maná, se tiñe el color para distinguirlas y se añade un Circle Collider a cada una para que puedan recolectarse.
¿Qué valores y tipos asignar en el inspector?
¿Cómo distinguir visualmente las pociones con el sprite renderer?
¿Qué colisionador usar para activar la recolección?
¿Quieres seguir afinando esta mecánica o te quedan dudas sobre la referencia al jugador o la configuración del sprite renderer? Comparte tus preguntas y casos en los comentarios.
Gabriel Souki
Yo me tome la libertad de crear una nueva poción para el mana, que opinan?? 😀 .
Dietmar Cerpa
¡Esta genial! ¡Gracias!
José Alfredo Colmenares
Excelente diseño! Gracias.
Raúl Alejandro Chávez Valenzuela
Santiago Sarmiento
Excelente metodo!
Andres Alba
Por qué recoge las pociones? No debería estar el circle collider como isTrigger?
Germán Arevalo Jerez
Porque el Capsule Collider del Player is Trigger.
jorge armando garcia
Correcto debe de estar seleccionado: Lo hizo con la moneda. Con las posiones no lo hizo y me parece raro que le funcionase;La logica consite en que al momento de Ontrigger detecte la biñeta del jugador, oculte el GameOdjet por medio de la desactivacion del Sprite Render y el Mismo Circle Collider 2D
Facundo Castro
No entiendo porque dice que playerController no tiene sharedInstance si le habiamos implementado singleton con el antes.
Leonel Grisaleña
Tengo 2 preguntas: 1 - En vez de acceder al PlayerController inicializando una variable usando el "GetComponent<PlayerControlller>" no es más facil ir a Player controller y establecer un SINGLETON?
PlayerController.sharedInstance.CollectHealth(this.value);
2- Por otro lado, luego de crear el objeto player. Por que lo inicializa en el start? A mi el código me funciona sin hacerlo. Cual sería el objetivo? No es redundante?
Alexis Duque
He creado una tercera poción, deadPotion, la idea es que al tomarla el personaje muere, pero no logro hacerla funcionar.
El problema es que al darle play, el personaje muere inmediatamente :c
Tal vez ven el error?
Alexis Duque
Lo he solucionado, al parecer esta línea ocasionaba el error.
Leonel Grisaleña
Cambie los colores usando photoshop. Para el que no tenga, puede usar Photopea que es online y gratuito. Dejo los sprites de las pociones por si le sirve a alguien
Wilmer David Cedeño Mendoza
Me parece extraño que se declare los puntos de vida y maná en el PlayerController y las monedas en el GameManager, ya que se declaro un método CollectObject() que recibiria distintos tipos de objetos Collectable
Usuario anónimo
Useryo lo entiendo así, la vida y el mana son atributos propios del player pero las monedas no son propios de este sino que le pertenecen a el. como contigo tu energía, (animo) conocimientos, etc. pero tu celular tus dinero esta contigo pero no son parte de ti.
Usuario anónimo
Userademas el método collectobject se ocupa de interactuar con el objeto para que el cambio se haga donde corresponda.
Tomas Leonardo Amaya Ríos
Health y Mana  { hasBeenCollected = true; switch (itemType) { case ItemType.Coin: { GameView.sharedInstance.coins += this.value; break; } case ItemType.HealthPotion: { GameObject player = GameObject.Find("Player"); player.GetComponent<PlayerController>().RecoverHp(this.value); break; } case ItemType.ManaPotion: { GameObject player = GameObject.Find("Player"); player.GetComponent<PlayerController>().RecoverMp(this.value); break; } } }
Nótese que los dos puntos ' : ' siguen ahí, y que las llaves se sitúan después de ellos.
En general, sería hacer:
switch(var){ case 1: { // Code break; } case 2: { // Code break; } }