2014-11-20 1 views
2

Моя цель: заставить мою улитку казаться, что она движется сама по себе. Пример: Идите вправо на несколько секунд, идите на несколько секунд, оставаясь в одном месте на несколько секунд.Единство, C# | Как у меня есть время ожидания между методами?

Текущий статус: улитка сидит на одном месте, когда я пытаюсь использовать WaitForSeconds

Без WaitForSeconds, моя улитка меняет направления вперед и назад, успешно (за исключением делать это очень быстро)

Я только начал изучая Unity и C# вчера. Любые советы/предложения будут иметь большую помощь, даже если это не по моему первоначальному вопросу. Если есть что-то еще, что я могу сделать, чтобы помочь вам помочь, дайте мне знать! :)

using UnityEngine; 
using System.Collections; 

public class SnailMove : MonoBehaviour { 
void Start() 
{ 

} 
// Use this for initialization 
void Update() 
{ 
    Waiting(); 
} 

// Update is called once per frame 
void Movement() 
{ 

    int direct = Random.Range(-1, 2); 
    if (direct == 1) 
    { 
     transform.Translate(Vector3.left * 1f * Time.deltaTime); 
     transform.eulerAngles = new Vector2(0,180); 
    } 
    if (direct == -1) 
    { 
     transform.Translate(Vector3.left * 1f * Time.deltaTime); 
     transform.eulerAngles = new Vector2(0,0); 
    } 
} 
    IEnumerator Waiting() 
    { 
    Movement(); 
    yield return new WaitForSeconds (5); 
    } 
} 

ответ

2

Corouts необходимо начинать с StartCoroutine. Из вашего описания это похоже на то, что вы хотите что-то вроде этого:

using UnityEngine; 
using System.Collections; 

public class SnailMove : MonoBehaviour 
{ 
    public float speed = 1f; 
    int direction = 0; 
    void Start() 
    { 
     StartCoroutine(ChangeDirection()); 
    } 

    void Update() 
    { 
     if (direction == 1) 
     { 
      transform.Translate(Vector3.left * speed * Time.deltaTime); 
      transform.eulerAngles = new Vector2(0,180); 
     } 
     else if (direction == -1) 
     { 
      transform.Translate(Vector3.left * speed * Time.deltaTime); 
      transform.eulerAngles = new Vector2(0,0); 
     } 
    } 

    IEnumerator ChangeDirection() 
    { 
     while(true) 
     { 
      yield return new WaitForSeconds (5); 
      direction = Random.Range(-1, 2); // returns "-1", "0" or "1" 
     } 
    } 
} 
+0

Omg. Я так люблю тебя сейчас! Это потрясающе!! <3 – FireFoxxie

1

Ваш логический поток немного смущен. Вы запускаете coroutine каждый кадр, когда вы, вероятно, захотите позвонить его один раз (например, в Start()) и зацикливать свою сопрограмму. В результате у вас есть целая куча Waiting() сопрограммы и все конкурируют друг с другом.

У вас есть два варианта здесь:

void Start() { 
    StartCoroutine(Waiting()); 
} 

IEnumrator Waiting() { 
    while(true) { 
     Movement(); 
     yield return new WaitForSeconds(5f); 
    } 
} 

я получил тошнит типирование, что, хотя, потому что while(true) это ужасная идея. Лучше бы отслеживать время в Update() и вызвать Movement() каждые 5 секунд, например, так:

private float timer = 0f; 

void Update() { 
    timer += Time.deltaTime; 
    if (timer > 5f) { 
     Movement(); 
     timer -= 5f; 
    } 
} 
+0

Ваш ответ - самое ближайшее решение, которое мне нужно. Это действительно работало, моя улитка медленно двигалась в случайных направлениях. Я предполагаю, что я должен был сказать, я хочу подражать кому-то нажав клавиши со стрелками влево и вправо, но для моей улитки. В настоящее время я пытаюсь манипулировать вашим кодом (2-й), чтобы получить то, что я хочу, чтобы он делал. Если у вас есть другие идеи, я буду рад их услышать. Если нет, большое вам спасибо за то, что вы приблизились к решению! Это очень помогло! :) – FireFoxxie

+0

Вам нужно будет проверить вход для вашего метода обновления, чтобы определить, есть ли у пользователя ключ, например: if (Input.GetKey (KeyCode.RightArrow)) MoveRight(); else if (Input.GetKey (KeyCode.LeftArrow)) MoveLeft(); Это зависит от вас, чтобы выяснить, что должны делать MoveRight и MoveLeft (в основном, просто обновлять вектор transform.line улитки). – stromdotcom

+0

while (true) не является ужасной идеей в сопрограмме. Тем не менее, вы не начали сопрограмму вообще. Вы должны использовать StartCoroutine для запуска сопрограммы. Просто вызов метода IEnumerator ничего не сделает. – Bunny83

1

Добрый день, я считаю, что ваша проблема в том, что вы вызываете ожидания в вашем методе обновления, который будет вызываться на каждом кадре, независимо от предыдущие исполнения, это означает, что только поток, который вызвал ожидание перед ожиданием, и как таковой, метод может быть вызван еще раз, когда ожидает только другой поток.

попробовать это:

using UnityEngine; 
using System.Collections; 

private bool waiting = false; 

public class SnailMove : MonoBehaviour { 
void Start() 
{ 

} 
// Use this for initialization 
void Update() 
{ 
    if(waiting == false) 
    { 
     Waiting(); 
    } 
} 

// Update is called once per frame 
void Movement() 
{ 

    int direct = Random.Range(-1, 2); 
    if (direct == 1) 
    { 
     transform.Translate(Vector3.left * 1f * Time.deltaTime); 
     transform.eulerAngles = new Vector2(0,180); 
    } 
    if (direct == -1) 
    { 
     transform.Translate(Vector3.left * 1f * Time.deltaTime); 
     transform.eulerAngles = new Vector2(0,0); 
    } 
} 
    IEnumerator Waiting() 
    { 
    Movement(); 
    waiting = true; 
    yield return new WaitForSeconds (5); 
    waiting = false; 
    } 
} 

Это заставит функцию обновления ждать булево ожидания должен быть установлен в ложь, прежде чем она будет вызывать функцию снова.

+0

К сожалению, я не работал. Это дало мне такое же влияние, как и на мой оригинальный код. Хотя, спасибо за указание на факт о методе обновления :) – FireFoxxie