朱峰社區(qū)首頁 朱峰社區(qū)

搜索資源 注冊|登陸

等待

返回 展開菜單
按功能 按軟件

伊芙利特

伊芙利特

包含6節(jié)視頻教程

完全的掌握貼圖繪制和類人型怪物的制作技巧。相信到現(xiàn)在你的模型功力已經(jīng)很了不得了。未來等待你的將是一個輝煌的未來。你已經(jīng)可以盡快去游戲公司工作了!

關(guān)閉

Unity3D教程-自定義YieldInstruction

關(guān)注:1114 留言:0 樓主:路絲絲 發(fā)帖時間:15年12月4日

路絲絲

普通會員

路絲絲

社區(qū)兄弟:4級

關(guān)注4364人

  • 積分

    97

  • 登陸

    11

  • 發(fā)帖

    39

  • 留言

    5

  • 作品

    1

間隔線


  本篇文章我們來看下擴(kuò)展Coroutine:自定義YieldInstruction,Unity 的Coroutine機(jī)制無疑是這個引擎的一個亮點,可以把很多異步的邏輯用一種順序的書寫方式去實現(xiàn),這個還是很重要的。

  關(guān)于Coroutine的原理,說實話,這個沒有源代碼,不好說具體是怎么實現(xiàn)的?此玫搅薎Enumerator,想象是使用了.Net的枚舉機(jī)制。網(wǎng)上有不是探討Coroutine實現(xiàn)原理的帖子,有興趣的同學(xué)可以翻開看看。

  Coroutine之所以強(qiáng)大,缺不了一系列YieldInstruction的派生類,包括:WaitForSeconds , WaitForFixedUpdate,AsyncOperation等等,我一直在琢磨能不能實現(xiàn)自己的YieldInstruction派生類呢?今天花時間嘗試了一些,答案是“不能,也能”,哈哈。為什么說“不能”呢,是因為YieldInstruction這個類可沒什么虛函數(shù)可以去override的,為什么說“能”呢!我們可以借用一個特殊的YieldInstruction派生類,來實現(xiàn)等同的功能,這個類就是Coroutine。

  假設(shè)我們想實現(xiàn)這樣一個YieldInstruction:當(dāng)一個動畫播放完事兒之后,程序再繼續(xù)。

  具體的實現(xiàn)也很簡單,首先我們需要一個IEnumerator的派生類,并實現(xiàn)其3個接口,具體代碼如下:

  using UnityEngine;

  using System.Collections;

  public class WaitForEndOfAnim : IEnumerator

  {

  AnimationState m_animState;

  public WaitForEndOfAnim(AnimationState animState)

  {

  m_animState = animState;

  }

  //-- IEnumerator Interface

  public object Current

  {

  get

  {

  return null;

  }

  }

  //-- IEnumerator Interface

  public bool MoveNext()

  {

  return m_animState.enabled;

  }

  //-- IEnumerator Interface

  public void Reset()

  {

  }

  }

  這里面核心的邏輯就在“MoveNext”函數(shù)中,我通過m_animState.enabled來判斷動畫是否播放完了。

  有了這個類時候,如果我們在協(xié)程函數(shù)體中寫:yield return new WaitForEndOfAnim(animState),發(fā)現(xiàn)并沒有其作用。后來改為:yield return StartCoroutine(new WaitForEndOfAnim(animAttack));就OK了。完整的測試代碼如下:

  using UnityEngine;

  using System.Collections;

  public class UnitTest : MonoBehaviour

  {

  // Use this for initialization

  void Start()

  {

  }

  void OnGUI()

  {

  GUILayout.BeginArea(new Rect(6, 6, 200, 300));

  GUILayout.BeginVertical();

  GUILayout.Box("Conrountinue測試");

  if (GUILayout.Button("啟動"))

  {

  StartCoroutine(DoTest());

  }

  GUILayout.EndVertical();

  GUILayout.EndArea();

  }

  IEnumerator DoTest()

  {

  Animation anim = GetComponentInChildren();

  AnimationState animAttack = anim["attack"];

  animAttack.speed = 0.1f;

  AnimationState animHit = anim["hit"];

  animHit.speed = 0.1f;

  AnimationState animDie = anim["die"];

  animDie.speed = 0.1f;

  Debug.Log("1.開始播放攻擊動畫。" + Time.time * 1000);

  anim.Play(animAttack.name);

  yield return StartCoroutine(new WaitForEndOfAnim(animAttack));

  Debug.Log("2.開始播放受擊動畫。" + Time.time * 1000);

  anim.Play(animHit.name);

  yield return StartCoroutine(new WaitForEndOfAnim(animHit));

  Debug.Log("3.開始播放死亡動畫。" + Time.time * 1000);

  anim.Play(animDie.name);

  yield return StartCoroutine(new WaitForEndOfAnim(animDie));

  }

  }

  最后,運(yùn)行結(jié)果看下圖,注意時間戳:

  好了,本篇unity3d教程關(guān)于自定義擴(kuò)展Coroutine的講解到此結(jié)束,下篇我們再會。

 


贊0 踩0

未知用戶

2005-2024 朱峰社區(qū) 版權(quán)所有 遼ICP備2021001865號-1
2005-2024 ZhuFeng Community All Rights Reserved

VIP

朱峰社區(qū)微信公眾號

回頂部

1.復(fù)制文本發(fā)給您的QQ好友或群、微信等;好友點擊鏈接以后,轉(zhuǎn)發(fā)就成功了。 2.如朋友點擊您的鏈接,您需要需刷新一下才行;同一個好友僅能點擊一次。
購買VIP,觀看所有收費教程。