首页 > 编程知识 正文

unity代码大全(unity官网)

时间:2023-05-06 01:34:02 阅读:80842 作者:3077

本文在《洪流学堂》wechat公众号上首次发表。 洪流,让你快几步!

正文译者: gddhxc -你的技术探访者的翻译日2018年2月1日,本文由UNIRX (3359 Github.com/Neue CC/UNIRX )插件翻译而成的自述文件是我最喜欢的插件,

UniRx - Unity响应式编程插件

插件的作者yoshifumikawai(neuecc )这篇文章的译者: gddhxc -你的技术探索者

改写了

UniRx是什么?

unirx(unity响应编程插件).Net的响应扩展程序。 Net公式的Rx很棒,但是在Unity上不能使用,与IOS的IL2CPP的兼容性有问题。 该库存在这些问题,并添加了Unity专用的工具类。 受支持的平台包括PC/MAC/Android/IOs/wp8/windows store /,并支持Unity4.6及更高版本。

UniRx在UniRx资产存储区的地址(免费) http://u3d.as/content/neue cc/uni-rx-rx-reactive-extensions-for-unity/7tt

演讲PPT-http://www.slide share.net /纽约/unirx-reactive-extensions-for-unity en

博客更新- https://媒体.com/@新抄送

在Unity论坛上提供支持- http://论坛3d.com/threads/248535-unirx-reactive-extensions-for-unity

更新unirx /发行版(https://github.com /新建抄送/unirx /发行版)

在UniRx上,有“道路(端口frx )平台适配器”“主道路调度器/从道路/网络”“框架”“可互换策略/”

为什么用Rx?

一般来说,网络操作需要WWW和Coroutine。 但是,由于以下原因,使用Coroutine对于异步操作不是很好的选择:

秃鹰不能具有返回值。 返回类型必须是IEnumerator

协和不能处理异常。 因为yield return语句不会被try-catch

引起代码大面积的强耦合。

Rx是来解决异步问题的。 Rx可以使异步操作更优雅,使用事件驱动编程,使用LINQ操作。

游戏循环(every Update,OnCollisionEnter,etc )、传感器数据) Kinect,Leap Motion,VR输入,etc.)都是一个事件。 Rx将事件转换为响应序列,可以通过LINQ操作简单组合,也支持时间操作。

Unity通常是单线程,但UniRx可以简化多线程。

UniRx简化了uGUI的编程,所有的UI事件(clicked,valuechanged,etc )都可以转换为UniRx的事件流。

介绍

简介

的非常棒的文章3360《The introduction to Reactive Programming you've been missing》 (https://Gist.github.com/sta ltz/868 E7B C2 A7B 8C1 F754 )。

下面的代码实现双击检测。

var click stream=observable.every update (.where (_=输入. getmousebuttondown ) )0); 点击流.缓冲器(点击流. throttle (来自时间跨度. 250 ).where ) xs=xs.count=2) .子系统此示例只有五行代码,显示了以下特性:

将游戏循环到“更新”中,使其成为事件流

事件流组合

合并自己的事件流

基于时间的操作非常简单

网络操作

使用ObservableWWW进行异步网络操作。 其Get/Post方法返回可订阅的IObservables:

observable www.get (http://谷歌.日本杂志/' ) .订阅;x=调试日志;x .订阅(0,100 ) )、//统一资源

可以组合和取消。你也可以通过LINQ表达式进行查询:

// composing asynchronous sequence with LINQ query expressionsvar query = from google in ObservableWWW.Get("http://google.com/") from bing in ObservableWWW.Get("http://bing.com/") from unknown in ObservableWWW.Get(google + bing) select new { google, bing, unknown };var cancel = query.Subscribe(x => Debug.Log(x));// Call Dispose is cancel.cancel.Dispose();

并行请求使用 Observable.WhenAll :

// Observable.WhenAll is for parallel asynchronous operation// (It's like Observable.Zip but specialized for single async operations like Task.WhenAll)var parallel = Observable.WhenAll( ObservableWWW.Get("http://google.com/"), ObservableWWW.Get("http://bing.com/"), ObservableWWW.Get("http://unity3d.com/"));parallel.Subscribe(xs =>{ Debug.Log(xs[0].Substring(0, 100)); // google Debug.Log(xs[1].Substring(0, 100)); // bing Debug.Log(xs[2].Substring(0, 100)); // unity});

也可以获取进度信息:

// notifier for progress use ScheudledNotifier or new Progress<float>(/* action */)var progressNotifier = new ScheduledNotifier<float>();progressNotifier.Subscribe(x => Debug.Log(x)); // write www.progress// pass notifier to WWW.Get/PostObservableWWW.Get("http://google.com/", progress: progressNotifier).Subscribe();

错误处理:

// If WWW has .error, ObservableWWW throws WWWErrorException to onError pipeline.// WWWErrorException has RawErrorMessage, HasResponse, StatusCode, ResponseHeadersObservableWWW.Get("http://www.google.com/404") .CatchIgnore((WWWErrorException ex) => { Debug.Log(ex.RawErrorMessage); if (ex.HasResponse) { Debug.Log(ex.StatusCode); } foreach (var item in ex.ResponseHeaders) { Debug.Log(item.Key + ":" + item.Value); } }) .Subscribe();

和 IEnumerators 一起使用(协程)

IEnumerator (协程) 是Unity主要的异步工具。UniRx 集成了协程和 IObservables。 你可以用协程写异步代码,然后用 UniRx 来组织他们。这是控制异步流的最好的方法。

// two coroutinesIEnumerator AsyncA(){ Debug.Log("a start"); yield return new WaitForSeconds(1); Debug.Log("a end");}IEnumerator AsyncB(){ Debug.Log("b start"); yield return new WaitForEndOfFrame(); Debug.Log("b end");}// main code// Observable.FromCoroutine converts IEnumerator to Observable<Unit>.// You can also use the shorthand, AsyncA().ToObservable()// after AsyncA completes, run AsyncB as a continuous routine.// UniRx expands SelectMany(IEnumerator) as SelectMany(IEnumerator.ToObservable())var cancel = Observable.FromCoroutine(AsyncA) .SelectMany(AsyncB) .Subscribe();// you can stop a coroutine by calling your subscription's Dispose.cancel.Dispose();

在 Unity 5.3 或更新版本里, 可以使用 ToYieldInstruction 将 Observable 转为 Coroutine。

IEnumerator TestNewCustomYieldInstruction(){ // wait Rx Observable. yield return Observable.Timer(TimeSpan.FromSeconds(1)).ToYieldInstruction(); // you can change the scheduler(this is ignore Time.scale) yield return Observable.Timer(TimeSpan.FromSeconds(1), Scheduler.MainThreadIgnoreTimeScale).ToYieldInstruction(); // get return value from ObservableYieldInstruction var o = ObservableWWW.Get("http://unity3d.com/").ToYieldInstruction(throwOnError: false); yield return o; if (o.HasError) { Debug.Log(o.Error.ToString()); } if (o.HasResult) { Debug.Log(o.Result); } // other sample(wait until transform.position.y >= 100) yield return this.transform.ObserveEveryValueChanged(x => x.position).FirstOrDefault(p => p.y >= 100).ToYieldInstruction();}

通常,协程想要返回一个值需要使用回调callback。Observable.FromCoroutine 可以将协程转为可以取消的 IObservable[T]。

// public methodpublic static IObservable<string> GetWWW(string url){ // convert coroutine to IObservable return Observable.FromCoroutine<string>((observer, cancellationToken) => GetWWWCore(url, observer, cancellationToken));}// IObserver is a callback publisher// Note: IObserver's basic scheme is "OnNext* (OnError | Oncompleted)?" static IEnumerator GetWWWCore(string url, IObserver<string> observer, CancellationToken cancellationToken){ var www = new UnityEngine.WWW(url); while (!www.isDone && !cancellationToken.IsCancellationRequested) { yield return null; } if (cancellationToken.IsCancellationRequested) yield break; if (www.error != null) { observer.OnError(new Exception(www.error)); } else { observer.OnNext(www.text); observer.OnCompleted(); // IObserver needs OnCompleted after OnNext! }}

这有一些例子。接下来是一个多OnNext模式。

public static IObservable<float> ToObservable(this UnityEngine.AsyncOperation asyncOperation){ if (asyncOperation == null) throw new ArgumentNullException("asyncOperation"); return Observable.FromCoroutine<float>((observer, cancellationToken) => RunAsyncOperation(asyncOperation, observer, cancellationToken));}static IEnumerator RunAsyncOperation(UnityEngine.AsyncOperation asyncOperation, IObserver<float> observer, CancellationToken cancellationToken){ while (!asyncOperation.isDone && !cancellationToken.IsCancellationRequested) { observer.OnNext(asyncOperation.progress); yield return null; } if (!cancellationToken.IsCancellationRequested) { observer.OnNext(asyncOperation.progress); // push 100% observer.OnCompleted(); }}// usecaseApplication.LoadLevelAsync("testscene") .ToObservable() .Do(x => Debug.Log(x)) // output progress .Last() // last sequence is load completed .Subscribe();

未完结,敬请期待后续连载



交流群:492325637 关注“洪流学堂”微信公众号,让你快人几步

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。