Unity(C#) — Почему не работают корутины?

217
27 февраля 2018, 02:38

Недавно начал изучать корутины. Не совсем понимаю, как они работают. Я писал скрипт босса для игры, и использовал корутины(впервые). Мне нужно было, чтобы, при переходе на вторую стадию, босс двигался по схемы с корутинов, но при переходе на вторую стадию, он продолжает движение так же, как на первой. Вот код:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Boss2 : Monster
{
  [SerializeField]
  private float speed = 2.0F;
  [SerializeField]
  public float PosMax1;
  [SerializeField]
  public float PosMin1;
  [SerializeField]
  public float PosMax2;
  [SerializeField]
  public float PosMin2;
  [SerializeField]
  int HitPoints = 7;
  [SerializeField]
  int Stadium = 1;
  Vector3 direction;
  private SpriteRenderer sprite;
  private Bullet bullet;
  IEnumerator Waiting()
  {
    yield return new WaitForSeconds(5);
  }
  IEnumerator Start1()
  {
    yield return StartCoroutine(Waiting());
    transform.position+=Vector3.left*10*Mathf.Sin(Time.deltaTime);
    Debug.Log ("Complite");
  }
  IEnumerator Start2()
  {
    yield return StartCoroutine(Waiting());
    if (transform.position.x >= PosMax2) 
    {
      direction *= -1.0F;
    } 
    else if (transform.position.x <= PosMin2) 
    {
      direction = transform.right;
    }
    Debug.Log ("Complite");
  }
  IEnumerator Start3()
  {
    yield return StartCoroutine(Waiting());
    transform.position+=Vector3.left*-10*Mathf.Sin(Time.deltaTime);
    Debug.Log ("Complite");
  }
  IEnumerator Start4()
  {
    yield return StartCoroutine(Waiting());
    if (transform.position.x >= PosMax1) 
    {
      direction *= -1.0F;
    } 
    else if (transform.position.x <= PosMin1) 
    {
      direction = transform.right;
    }
    Debug.Log ("Complite");
  }
  void Start5()
  {
    if (transform.position.x >= PosMax1) 
    {
      direction *= -1.0F;
    } 
    else if (transform.position.x <= PosMin1) 
    {
      direction = transform.right;
    }
    Debug.Log ("Complite");
  }
  protected override void Awake()
  {
    sprite = GetComponentInChildren<SpriteRenderer> ();
    bullet = Resources.Load<Bullet>("Bullet");
  }
  protected override void Start()
  {
    direction = transform.right;
    Stadium = 1;
  }
  void Update ()
  {
    Move ();
  }
  public void Damaged()
  {
    HitPoints--;
    if (Stadium == 1 && HitPoints == 0) 
    {
      Stadium = 2;
      HitPoints = 10;
    } 
    else if (Stadium == 2 && HitPoints == 0) 
    {
      Destroy (gameObject);
    }
  }
  protected virtual void OnTriggerEnter2D(Collider2D collider)
  {
    Bullet bullet = collider.GetComponent<Bullet> ();
    if (bullet) 
    {
      Damaged ();
    }
    Character character = collider.GetComponent<Character> ();
    if (character) 
    {
      character.ReceiveDamage ();
    }
  }

  private void Move()
  {
    if (Stadium == 1) 
    {
      if (transform.position.x >= PosMax1) 
      {
        direction *= -1.0F;
      } 
      else if (transform.position.x <= PosMin1) 
      {
        //transform.position+=Vector3.up*10*Time.deltaTime;
        direction = transform.right;
      }
    } 
    else if (Stadium == 2) 
    {
      for (; ;) 
      {
        Start5 ();
        Start1 ();
        Start2 ();
        Start3 ();
        Start4 ();
      }
    }
    transform.position = Vector3.MoveTowards (transform.position, transform.position + direction, speed * Time.deltaTime);
    sprite.flipX = direction.x > 0.0F;
  }
}

Буду рад вашей помощи. P.S. Я новичок, и это мой первый проект

Answer 1

Вы же заметили, что Start5 у вас обычный метод, а не корутина, верно?

Трудно, конечно, понять магию, которая у вас там происходит, поэтому код не трогаю, а помогу по сути синтаксиса: все корутины должны запускаться через StartCoroutine(), а у вас простой вызов метода - поэтому и не работает.

А движение, как в первой стадии у вас потому, что первая стадия и метод Start5 содержат один и тот же код. Т.к. метод Start5 не является корутиной, то он единственный из ваших вызовов во второй стадии срабатывает и, как следствие, разницы в движении вы не замечаете.

Вот вам статья на хабре, где более менее подробно про корутины расписано. Возможно, немного поможет в осознании :)

READ ALSO
Верстка DataGrid В XAML

Верстка DataGrid В XAML

Как реализовать таблицу такого вида на XAML? Туплю конкретноЕсли не сложно, можно готовый код или ссылку на статью, где подобное подробно описывается

214
Сокеты, выход за границы массива?

Сокеты, выход за границы массива?

Люди добрые, осваиваю сокеты на c#, и увидел товарища на ютюбе, который объясняет как это делатьВообщем, когда он принимает сообщение от клиента(простая...

146
LINQ to XML: парсинг xml с отсутствующими тегами

LINQ to XML: парсинг xml с отсутствующими тегами

Есть некий xmlВ целом его структура "постоянна", но есть узлы, в которых нет части тегов, которые необходимо считать

168
C# double. Округление

C# double. Округление

если число меньше какого то значения "00000002", то C# превращает его в 2e-07

222