Jump to content
Sign in to follow this  
Andres David

instantiate random gameobject

Recommended Posts

Good afternoon.

My question is this: My character grab a box that is containing various powers, to grab it, this gives a random power. I want that power remains stored in another game object, to use it, anytime pressing a key.

My Script

public GameObject[] anim;

public GameObject objetoPadre;

void OnTriggerEnter2D(Collider2D collider)

{

Destroy(gameObject);

Generar(); 
}

void Generar()

{

GameObject objetoHijo = Instantiate(anim[Random.Range(0,anim.Length)], transform.position, Quaternion.identity) as GameObject;

objetoHijo.transform.parent = objetoPadre.transform;

objetoHijo.transform.position = objetoPadre.transform.position;

Destroy(objetoHijo, 1);

 

So, immediately, I instance the power, and I want to do it as I specified at the beginning.

Thanks for the help.

Share this post


Link to post
Share on other sites

Ya, pero no dices que falla. De todos modos ese destroy gameobject antes de la muy anglosajona palabra Generar va a producir que se autodestruya antes de completar el proceso.

Y si, esto es un foro en Spanish.

Share this post


Link to post
Share on other sites

Jajajaja, Siii esta bien, cambiare al español.

Mi código está de la siguiente manera(Ya se los mostrare) y si, el funciona, pero funciona instanciandome el power inmediatamente apenas toca la caja y lo que quiero es que me lo almacene y que en cualquier momento del juego lo pueda usar, digamos presionando una tecla. 

Y como dice iRobb tienes la razón, el destroy me destruye el ojeto, pero lo que me destruye es la caja que contiene los poderes, solo que aquí lo copie por equivocación, pido disculpas y el generar es un metodo que estoy utilizando para hacer la instancia del poder cuando yo quiera (Se supone).

Ya me almacena el poder, pero no me lo instancia, en la imagen lo explico.

Gracias por comentar

Codigo.png

Edited by Andres David

Share this post


Link to post
Share on other sites

Si esta bien que no lo instancie según tu código. 

El método Generar () es llamado un instante por el método OnTriggerEnter (),  (se supone llamado único,  no es un bucle); por esto cuando presionas el botón Poder no pasa nada, pues la ejecución del método Generar () depende del momento en el que se entra en colisión y no cuando se permanece en colisión o cuando se presiona el botón. 

Puedes poner la parte del código del botón dentro del Update pero su ejecución dependiente de tal vez un booleano que podría ser activado después de asignar el poder en el método Generar ().

Por otro lado obviamente el código va a depender de donde este puesto (que gameObject).

En mi caso para almacenar cosas como poderes almaceno un index (por ejemplo una variable tipo int) dentro de un script administrador,  luego esa variable se convierte en el número de elemento de un array que  contiene objetos los cuales deseo instanciar al presionar un botón ( objetos también almacenados en el Administrador).

Muchas veces utilizo la instrucción SendMessage () de unity para actualizar el valor del index.

 

Por cierto en tu código... que pasa si el valor devuelto por Random.Range es igual al largo del array anim... no estaría eligiendo un elemento fuera del largo del array?.

Share this post


Link to post
Share on other sites

Muchas gracias Oak Human, solo era cambiar el codigo a la parte del Update, organizar otras cositas y listo, ya me funciona, no he utilizado la instruccion SendMessage() debido a que todo me funciona bien, no se si de todas maneras mas adelante la tendré que utilizar. (Aunque bueno, solo tengo un pequeño problema), que al momento de coger dos cajas de poder (Osea cojo una y no utilizo el poder y después cojo la otra) y en ese momento utilizo dicho poder, me suelta dos poderes, y quiero que me suelte solo uno, sea el poder que coge primero o sea el que coge de último, como puedo solucionar esto. Gracias.

Y respondiendo a tu pregunta, la respuesta es no, siempre me elige uno de los elementos que están dentro de ese array; simple y sencillamente es un array con 3 poderes, osea un array de 3 posiciones, por lo cual si me devuelve 0, o 1, o 2 me da un poder diferente por cada una de esas posiciones, eso es lo que hace esta parte del codigo. Mmm espero haber aclarado esa pregunta, sino me dices y con mucho gusto busco otra manera de responderte.

Y aprovecho para preguntar otra cosa, si yo quiero que se instancie el poder por si solo, digamos que cogí la caja y me dio X poder y quiero que a los dos segundos se instancie ese poder, como puedo hacer eso.(No se si depronto dentro de la intruccion "instantiate" se pueda especificar) PD: Me voy a poner en estas, pero por si depronto no soy capaz, me adelanto a preguntar XD.

Gracias Nuevamente.

EDITO: La última parte ya lo pude solucionar. :D

Edited by Andres David

Share this post


Link to post
Share on other sites

Si usas una courutine puedes usar un yield, asi rápidamente creo:

IEnumerator Countdown(){
    
    yield return new WaitForSeconds(2.0f)
    SiguienteMetodo();
}

Para llamarlo usa StartCourutine(Countdown));

Share this post


Link to post
Share on other sites

Cambios cambios :rolleyes:

GetButton() por GetButtonDown ().

GetButton es usado para detectar cuando el botón es mantenido presionado,  luego como esta dentro del Update lo lee una vez por frame resultando en una creación de un GameObject por frame.

GetButtonDown es un evento llamado por una vez cuando se presiona el Botón... según el código creará un GameObject cuando el botón sea presionado pero no cuando se mantenga presionado.

Por cierto sigo pensando que anim.Lenght devuelve el largo correspondiente del array anim, entonces si el Random.Range llegara a devolver el valor de largo del array (anim.Lenght), este estara fuera del rango de elementos del array debido a que la cuenta de los elementos de un array empieza en 0.

Entonces por ejemplo si anim.Lenght es 3 y escribo:

int element = anim.Lenght;

y selecciono de esta forma

GameObject obj = anim[element];

Y los elementos del array  son 0, 1, 2,

Entonces estará seleccionando un elemento fuera del largo de el array.

Edited by Oak Human Flesh
Teléfono disléxico @)

Share this post


Link to post
Share on other sites

Holaa 

Oak Human, referente al GetButton, ya lo habia cambiado, me pude dar cuenta del error, cuando lo estaba probando, aunque gracias.

Y sobre lo del anim.Length lo que dices tiene sentido, y según tu ejemplo, claro es un array que me devuelve 3 y el GameObject obj por ende me devuelve 3 porque en element va a ver un 3; pero haber, el Random.Range me devuelve un numero aleatorio entre 0 y el tamaño del array que es 3, entonces uno diría (entre: 0,1,2,3) y habiendo solamente 3 elementos, uno diria se desborda, o como dices tu selecciona un elemento fuera del array, pero como tengo entendido yo, es que no es asi (osea 0,1,2,3, sino que es 0[1], 1[2] y 2[3]) por ende no selecciona un elemento fuera del array, Espero hacerme entender. Y ademas así es como entiendo yo el funcionamiento de los arrays desde que empece a ver primeramente Vectores y Matrices, y si estoy equivocado, entonces he estado equivocado el tiempo que llevo en esto del desarrollo/programación; pero hasta el momento siempre lo he funcionado así, y hasta el son de hoy me a dado. Jajajaja.  Asi a simple vista uno diria que son 4, pero para el sistema por decirlo así, en realidad siguen siendo 3. Bueno, así lo entiendo yo XD :D

Quedo atento a ver que me dices referente a esto.

Y si me puedes colaborar con lo que pregunte antes te lo agradecería mucho, referente a esto: al momento de coger dos cajas de poder (Osea cojo una y no utilizo el poder y después cojo la otra) y en ese momento utilizo dicho poder, me suelta los dos poderes  que cogí, y quiero que me suelte solo uno, sea el poder que coge primero o sea el que coge de último.

 

mrpacogp gracias por ese comentario, no sabia de ese courutine, pero eso que me dijiste es referente a la pregunta que hice acerca de los dos poderes o a a la pregunta de instanciar un poder al pasar determinado tiempo? Por lo que creo y veo es para la instancia del poder al pasar un tiempo, si es así, te digo que lo solucione de otra manera, pero gracias, me puede llegar a ser útil mas adelante, lo estudiaré a ver que tal.

Muchas gracias. Y nuevamente quedo atento.

Edited by Andres David

Share this post


Link to post
Share on other sites

No te preocupe mucho lo del largo del array, debido a que tenia una duda por el Random.Range al usar parámetros Enteros, luego salí de mi duda al leer la doc. de Unity, esta es la respuesta, de el por que no se pasa del largo de la matriz:

Random.Range

Returns a random integer number between min [inclusive] and max [exclusive] (Read Only).

Unity manual.

http://docs.unity3d.com/ScriptReference/Random.Range.html

 

Y si me puedes colaborar con lo que pregunte antes te lo agradecería mucho, referente a esto: al momento de coger dos cajas de poder (Osea cojo una y no utilizo el poder y después cojo la otra) y en ese momento utilizo dicho poder, me suelta los dos poderes  que cogí, y quiero que me suelte solo uno, sea el poder que coge primero o sea el que coge de último.

Muchas gracias. Y nuevamente quedo atento.

tal vez podrías usar una variable entera como contador de poderes instanciados, y usarlo para evaluar si se crea un poder... si es mayor o igual a 1 no permitir instanciar, y cuando el objetoHijo no exista restar la cantidad del contador. (es una idea). :D 

 

 

 

Edited by Oak Human Flesh

Share this post


Link to post
Share on other sites

Jajajaja, bueno, ahí tenemos la documentación...

Pero sabes que, referente a lo de los poderes, no puede ser con los contadores porque estoy utilizando varios GameObjects para lo mismo, pero en diferentes puntos; me explico, al pasar por la primera caja de poder, digamos que el contador de ese que está en 0, pasa a 1, pero al llegar a la otra caja de poder el contador de ese está en 0, y también pasaría a 1 (Son varios game objects debido a los colliders) entonces no veo como podría funcionar así.

Porque digamos, cojo la primera caja, contador igual a 1, y no utilizo el poder, llego a la segunda caja el contador de ese game object que esta en 0 al pasar el trigger sube a 1, entonces ambos quedan con el contador en 1 y no veo que condición podría utilizar yo ahí, porque por ejemplo si digo que: if (contador >= 1) { no instancie }... No podría ser, porque ya no me instanciaria ninguno de los dos.

O si se puede, no veo la lógica, no se me ocurre como podría preguntar jajaja.

 

Share this post


Link to post
Share on other sites

Jajajaja, bueno, ahí tenemos la documentación...

Pero sabes que, referente a lo de los poderes, no puede ser con los contadores porque estoy utilizando varios GameObjects para lo mismo, pero en diferentes puntos; me explico, al pasar por la primera caja de poder, digamos que el contador de ese que está en 0, pasa a 1, pero al llegar a la otra caja de poder el contador de ese está en 0, y también pasaría a 1 (Son varios game objects debido a los colliders) entonces no veo como podría funcionar así.

Porque digamos, cojo la primera caja, contador igual a 1, y no utilizo el poder, llego a la segunda caja el contador de ese game object que esta en 0 al pasar el trigger sube a 1, entonces ambos quedan con el contador en 1 y no veo que condición podría utilizar yo ahí, porque por ejemplo si digo que: if (contador >= 1) { no instancie }... No podría ser, porque ya no me instanciaria ninguno de los dos.

O si se puede, no veo la lógica, no se me ocurre como podría preguntar jajaja.

 

Creo que volver al script administrador y  el SendMessage() serian la solución, este debe ser quien decida cuando se deben instanciar los poderes y cuantos.

Share this post


Link to post
Share on other sites

un ejemplo simple podría ser algo asi:

using UnityEngine;
using System.Collections;
// Script para el objeto Administrador...
// este gameObject debe estar instanciado en escena.
public class GameManager : MonoBehaviour {
    public int myIndex, powerCount;
    public GameObject[] powers;
    GameObject clon;
    public Transform player;
    // Use this for initialization
    void Start () {
        player = GameObject.FindWithTag("Player").transform;
        powerCount = 0;
    }
	
	// Update is called once per frame
	void Update () {
        if (!clon && powerCount > 0)
        {
            if (Input.GetButtonDown("Fire1"))
            {
                clon = Instantiate(powers[myIndex], player.position, player.rotation) as GameObject;
                Destroy(clon, 1f);
                powerCount--;
            }
        }
	}
    void UpdateIndex(int rxIndex)
    {
        myIndex = rxIndex;
        powerCount++;
    }
}

y para el objeto con el isTrigger

using UnityEngine;
using System.Collections;
// este script envia un mensaje al componente administrador del objeto
// que posee el tag GameController
public class ColMessager : MonoBehaviour {
    GameObject theManager;
	// Use this for initialization
	void Start () {
        theManager = GameObject.FindWithTag("GameController");
	}
   // OnTriggerEnter para proyectos en 3d
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            // envia un mensaje al metodo UpdateIndex y le pasa como parametro un
            // integer aleatorio cuyo valor es entre 0 y el largo del array powers de
            // el componente GameManager.
            theManager.SendMessage("UpdateIndex", Random.Range(0, theManager.GetComponent<GameManager>().powers.Length));
        }
    }
}

con estos script se consigue que se instancie un objeto a la vez (de los almacenados en el array powers del script GameManager), y además se aumente la cantidad de powers disponibles (variable powerCount).

El power instanciado dependerá de el ultimo valor del myIndex actualizado por el método UpdateIndex del script GameManager.

El segundo script (la clase ColMessager ) lo puedes poner en cuantos objetos desees, pero el script administrador solo es uno.

;) espero solucione tu problema...

Edited by Oak Human Flesh

Share this post


Link to post
Share on other sites

Hola nuevamente y gracias por el script, lo provaré a ver que tal, estos días estuve sin acceso a internet y me puse a hacerlo de otra manera y te cuento que otra solución que hallé al problema fue destruir el poder si no lo utilizaba en determinada cantidad de tiempo, osea que cogió el poder y si no lo utiliza a los X segundos, lo pierde y le toca esperar hasta que coja el siguiente. Asi lo hice, pero analizaré este que me enviaste... Gracias

Aunque en lo que estoy ya, es en la afectación de los poderes, te explico, el juego que estoy haciendo es un juego de... "yo", por así decirlo, contra la máquina, y uno de los poderes es el aumento de velocidad, entonces estoy mirando como hacer para aumentar la velocidad, ya que este (el personaje), se mueve con motores debido a que es un man sobre una bicicleta.

Gracias por tu ayuda.

Share this post


Link to post
Share on other sites

Buenas Oak Human, te hago una pregunta por si de pronto sabes que estaré haciendo mal, en mi código tengo lo siguiente, y lo que pasa es que no cumple con lo que tiene que hacer al  momento de presionar la tecla. Mira a ver si sabes de pronto que estoy haciendo mal. 

La idea es que al presionar la tecla y si el poder es flama, que esto es igual a un aumento de velocidad, por ende aumente la velocidad del personaje, he hice la prueba utilizándolo en el FixedUpdate y funciona, pero aumenta la velocidad apenas detecta que el poder es flama, osea por si solo, y lo que quiero es que sea cuando yo haga uso del poder, osea cuando presione la tecla "Poder". Gracias...

Codigo.png

EDITO: Ya lo pude solucionar...

Edited by Andres David

Share this post


Link to post
Share on other sites
Sign in to follow this  

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...