【Unity】UniRx.Async에서 await 연골소 시 주의사항
2019/06/24 추기
라이브러리가 UniTask
로 분리되면 다음 동작이 수정됩니다.
연골소 await를 정확하게 연골소로 처리하는 쪽으로 통일한다.
다음은 과거의 일지로 남겨 둡니다.
입문
Unity 2018.3 이후와 Unity 2018.2, UniRx에서 코르크를 만들 때의 행동은 다르다.
Unity 2018.3 이후와 Unity 2018.2, UniRx에서 코르크를 만들 때의 행동은 다르다.
무슨 현상이 일어났는가
UniRx는 await 연골소의 기능을 가지고 있습니다.
하지만 유니티 2018.2와 2018.3과는 다르다.
정확히 말하면 UniRx.비헤이비어는 Async 활성화 여부에 따라 다릅니다.using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
await Coroutine();
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
yield return new WaitForSeconds(1.0f);
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
2018.2 결과
WaitForSeconds
정상적으로 운행하고 예상대로 플로피소를 운행한다.
2018.3 결과
WaitForSeconds
무시되어 코르크 단백질이 정상적으로 작동하지 않는다.
왜?
각 버전에서 호출Awaiter
이 다르기 때문이다.
대IEnumerator
를 await할 때
using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
await Coroutine();
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
yield return new WaitForSeconds(1.0f);
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
각 버전에서 호출
Awaiter
이 다르기 때문이다.대
IEnumerator
를 await할 때GetAwaiter
를 호출하여 IEnumerator
를 연골소로 간주하여 awaitIEnumerator
을 하나의 작은 데이터로 간주하여 await이 호출
Awaiter
이 다르기 때문에 이런 행위 차이가 나타난다.대책
2018.3 이후 코르크단백질 await를 하려면 다음과 같은 방법으로 대책을 세울 수 있다.
방법IENumerator를 코르크로 시작한 후 await
StartCoroutine
에서 코르크 단백질을 명확하게 가동한 후 await를 진행하는데 동작이 정확하다using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
// StartCoroutineでコルーチンを起動して、それをawaitする
await StartCoroutine(Coroutine());
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
yield return new WaitForSeconds(1.0f);
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
Observable.FromCoroutine
등도 문제없다.// コルーチンをObservableに変換してしまう
await Observable.FromCoroutine(Coroutine);
// Observable.FromCoroutineの省略記法
await Coroutine().ToObservable();
방법마이크로소프트 골소와 같은 방법을 사용하다
UniRx는 MicroCoroutine
yield return null
만 허용하는 경량 코르크 기구를 설치했다.
그것에 따라 yield return null
의 코르크만 다시 쓰고 await는 그것의 방법을 사용했다.using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
await Coroutine();
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
var startTime = Time.time;
while (Time.time - startTime < 1.0f)
{
yield return null; // WaitForSecondsを使わない
}
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
총결산
2018.2에서 UniRx를 사용하는 경우 2018.3으로 업데이트하면 여기에 빠질 수 있습니다.
코르크 단백질을 만드는await의 경우 특히 주의해야 한다.
Reference
이 문제에 관하여(【Unity】UniRx.Async에서 await 연골소 시 주의사항), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toRisouP/items/5dd497723ac7c2ffb822
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
// StartCoroutineでコルーチンを起動して、それをawaitする
await StartCoroutine(Coroutine());
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
yield return new WaitForSeconds(1.0f);
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
// コルーチンをObservableに変換してしまう
await Observable.FromCoroutine(Coroutine);
// Observable.FromCoroutineの省略記法
await Coroutine().ToObservable();
using System.Collections;
using System.Threading.Tasks;
using UniRx;
using UnityEngine;
using UniRx.Async; // 2018.3のときのみ有効化される
public class CoroutineAwaitSample : MonoBehaviour
{
void Start()
{
Debug.Log(Application.unityVersion);
AwaitCoroutineAsync();
}
private async Task AwaitCoroutineAsync()
{
Debug.Log($"Await前:{Time.frameCount}");
await Coroutine();
Debug.Log($"Await後:{Time.frameCount}");
}
private IEnumerator Coroutine()
{
Debug.Log($"====コルーチン開始:{Time.frameCount}");
var startTime = Time.time;
while (Time.time - startTime < 1.0f)
{
yield return null; // WaitForSecondsを使わない
}
Debug.Log($"====コルーチン終了:{Time.frameCount}");
}
}
2018.2에서 UniRx를 사용하는 경우 2018.3으로 업데이트하면 여기에 빠질 수 있습니다.
코르크 단백질을 만드는await의 경우 특히 주의해야 한다.
Reference
이 문제에 관하여(【Unity】UniRx.Async에서 await 연골소 시 주의사항), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/toRisouP/items/5dd497723ac7c2ffb822텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)