Problemas con waitForSecond en un script

Peinacabras

Buenas, a ver, necesito que una pequeña IA tarde un tiempo entre accion y accion y he pensado en hacerlo con WaitForSeconds

El problema es que me tira un NullReferenceException, y el codigo que he cogido es de la documentacion oficial de unity, no entiendo porque falla, alguien me puede echar un cable?

Gracias

public void TakeControl(){

            ButtonsController button = GameObject.Find ("NetworkManager").GetComponent<ButtonsController> ();
            checkCards ();
            button.PushReady ();
            sendToAttack ();
            Debug.Log ("Starting " + Time.time);
            StartCoroutine (WaitAndPrint(2.0F));
            Debug.Log("Before WaitAndPrint Finishes " + Time.time);
            //button.EndTurn ();
    }

IEnumerator WaitAndPrint(float waitTime){
                yield return new WaitForSeconds(waitTime);
        }
YaW

El error lo tendrás en otra parte del código, no en la corutina. ¿Esto te funciona?

public void TakeControl(){
                StartCoroutine (WaitAndPrint(2.0F));
        }

IEnumerator WaitAndPrint(float waitTime){
                yield return new WaitForSeconds(waitTime);
        }

Si no te funciona, pon la traza completa del error.

1 1 respuesta
Czhincksx

¿Tienes creado el objeto "NetworkManager"? Y si es así, ¿tiene el componente ButtonsController?

1 1 respuesta
Peinacabras

#2 No, me tira el mismo error

#3 No es cosa de ese objeto, puesto que sin el startcorutine funciona perfectamente.

Gracias por contestar a ambos.

1 respuesta
YaW

#4 Pon la traza completa del error como te he dicho y podremos ayudarte algo más, ese código por si solo no falla, tendrás algo mal en el resto de la clase que no estés viendo o algo así.

1 respuesta
Peinacabras

#5

NullReferenceException
UnityEngine.MonoBehaviour.StartCoroutine (IEnumerator routine)
Enemie.TakeControl () (at Assets/Scripts/Enemie.cs:20)
GameController.pushNext () (at Assets/Scripts/GameController.cs:173)
ButtonsController.EndTurn () (at Assets/Scripts/ButtonsController.cs:41)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters)
UnityEngine.Events.UnityEvent.Invoke ()
UnityEngine.UI.Button.Press () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()

Yo también estuve mirando la traza y no encontré nada, la verdad.

Gracias por contestar tío.

2 respuestas
YaW

#6

You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all

El monobehaviour que estás usando lo has creado con new supongo. Eso no está permitido en Unity.

2 respuestas
Peinacabras

#7 En la parte de MonoBehaviour no la entiendo realmente, se que se utiliza para tratar con GameObjects en la clase, realmente.

La instancia de la clase Enemie() la creo en el controlador del juego

private Enemie enemie = new Enemie(); si es a lo que te refieres , sino ya pregunto en el foro de Unity.

Gracias por tu tiempo y por las molestias.

2 respuestas
Czhincksx

MonoBehaviour es una clase de la que querrás heredar cuando necesites ejecutar código cada frame, inicializarlo al activar un GameObject, etc.

Tiene funciones útiles y necesarias (pero que ya que controlar para que no te armen la de San Quintín) como Awake, Start, Update, OnEnable, etc. Otras para controlar colisiones y cosas así.

Los GameObjects son los objetos "físicos" que tienes en la escena, y cada uno puede tener componentes de todo tipo. Eso incluye scripts, sprites, mallas, colliders, partículas, audio, etc.

Efectivamente, para tener acceso a esos componentes desde un script, el script debe heredar de la clase MonoBehaviour para leer el componente con el método GetComponent.

También para lanzar una corrutina tu script tiene que heredar de MonoBehaviour.

Esto no te resuelve el problema extraño que tienes pero al menos espero haberte aclarado un poco cómo va.

#7 ¿De dónde sacas ese texto? Si está en el post #6 me sale cortado :/

1
B

#8 La clase Enemie() extiende MonoBehaviour o es una clase sin más?

1 respuesta
YaW

#8 el problema es muy simple. Un MonoBehaviour nunca se debe instanciar haciendo un new. Los MonoBehaviour están diseñados para que los adjuntes a un GameObject y entonces se ejecuten automáticamente.

Si lo que quieres es tener una clase que no sea un MonoBehaviour y poder instanciarla tú a antojo, no la extiendas de MonoBehaviour. La Corutina la tendrás que ejecutar en otro MonoBehaviour que tengas en la escena asociado a algún script.

Resumen, nunca hagas new a un MonoBehaviour.

1 1 respuesta
Peinacabras

#10 Extiende de MonoBehaviour

#11 Okok, modificare el código entonces , cuando lo haga muestro resultados, un saludo y gracias

Usuarios habituales