Unity中常用方法
使用观察者模式对Unity UI组件进行扩展
位于UniRx public static class UnityUIComponentExtensions类中
- 观察Button点击事件
//Observe onClick event 观察点击事件
public static IObservable OnClickAsObservable(this Button button)
{
return button.onClick.AsObservable();
}
- 观察Toggol值变化
//Observe onValueChanged with current `isOn` value on subscribe 观察isOn值并传递
public static IObservable OnValueChangedAsObservable(this Toggle toggle)
{
return Observable.CreateWithState(toggle, (t, observer) =>
{
observer.OnNext(t.isOn);
return t.onValueChanged.AsObservable().Subscribe(observer);
});
}
- 观察Scrollbar值变化
//Observe onValueChanged with current `value` on subscribe 观察value值并传递给下一个函数
public static IObservable OnValueChangedAsObservable(this Scrollbar scrollbar)
{
return Observable.CreateWithState(scrollbar, (s, observer) =>
{
observer.OnNext(s.value);
return s.onValueChanged.AsObservable().Subscribe(observer);
});
}
- 观察Slider值变化
//Observe onValueChanged with current `value` on subscribe 观察Value值并传递
public static IObservable OnValueChangedAsObservable(this Slider slider)
{
return Observable.CreateWithState(slider, (s, observer) =>
{
observer.OnNext(s.value);
return s.onValueChanged.AsObservable().Subscribe(observer);
});
}
- 观察InputField输入
//Observe onValueChanged with current `text` value on subscribe 观察当前输入text并传递
public static IObservable OnValueChangedAsObservable(this InputField inputField)
{
return Observable.CreateWithState(inputField, (i, observer) =>
{
observer.OnNext(i.text);
return i.onValueChanged.AsObservable().Subscribe(observer);
});
}
//Observe onEndEdit(Submit) event 观察输入结束事件
public static IObservable OnEndEditAsObservable(this InputField inputField)
{
return inputField.onEndEdit.AsObservable();
}
UniRx处理协程
public static IObservable FromCoroutine(Func coroutine, bool publishEveryYield = false)
{
return FromCoroutine((observer, cancellationToken) => WrapEnumerator(coroutine(), observer, cancellationToken, publishEveryYield));
}
public static IObservable FromCoroutineValue(Func coroutine, bool nullAsNextUpdate = true)
{
return FromCoroutine((observer, cancellationToken) => WrapEnumeratorYieldValue(coroutine(), observer, cancellationToken, nullAsNextUpdate));
}
public static IObservable ToObservable(this IEnumerator coroutine, bool publishEveryYield = false)
{
return FromCoroutine((observer, cancellationToken) => WrapEnumerator(coroutine, observer, cancellationToken, publishEveryYield));
}
Mono生命周期
- 每一帧执行
public static IObservable EveryUpdate(){};
public static IObservable EveryFixedUpdate(){};
public static IObservable EveryEndOfFrame(){};
public static IObservable EveryLateUpdate(){};
public static IObservable EveryAfterUpdate(){};
- 观察目标状态
public static IObservable TakeUntilDestroy(this IObservable source, Component target)
{
return source.TakeUntil(target.OnDestroyAsObservable());
}
public static IObservable RepeatUntilDestroy(this IObservable source, GameObject target)
{
return RepeatUntilCore(RepeatInfinite(source), target.OnDestroyAsObservable(), target);
}
处理WWW请求
public static IObservable GetWWW(string url, Hash headers = null, IProgress progress = null)
{
return ObservableUnity.FromCoroutine((observer, cancellation) => Fetch(new WWW(url, null, (headers ?? new Hash())), observer, progress, cancellation));
}
常用操作符
- Observable.map:将一个序列中每次对外发射的信息做转换(例:map(x=>x*10))
- Observable.range:发射一定数量值得序列。
- Observable.toArray: 在序列完成时将所有发射值转换为一个数组。
- Observable.flatMap: 将原始序列流中的元素转化为一个新的序列流,并将这个新的序列流merge到原来的序列中元素的位置。
- Observable.startWith: 它会设置Observable序列的第一个值
- Observable.combineLatest: 类似于promiseAll,在所有序列有结果后才会执行
- Observable.scan: 将序列中每次发射的值可以做聚合,与reduce类似,reduce会将整个序列的值聚合起来,在序列完成时发送一个最终值
- Observable.sample: 从持续的序列中取得一定的样品
- Observable.merge:将多个序列合并成一个,可以做OR来使用
- Observable.timestamp: 能够得到每个发射值的发射时的时间
- Observable.distinctUntilChanged(compare, selector): selector取出用来比较的key,compare用来比较两个key
- Observable.takeWhile() 当参数为false时停止发射数据
创建操作符
- create:最基本的创建Observable的操作符
- Start:创建发射一个函数的返回值的Observable
- range:根据输入的初始值n和数目m发射一系列大于等于n的m个值(每次+1)
- just:将某个对象转化为Observable对象,并且将其发射出去,可以是一个数字、一个字符串、数组、list对象等
- defer:只有当有Subscriber来订阅的时候才会创建一个新的Observable对象,也就是说每次订阅都会得到一个刚创建的最新的Observable对象,这可以确保Observable对象里的数据是最新的
- from:用来将某个对象转化为Observable对象,并且依次将其内容发射出去。这个类似于just,但是just会将这个对象整个发射出去。比如说一个含有10个数字的数组,使用from就会发射10次,每次发射一个数字,而使用just会发射一次来将整个的数组发射出去
- interval:创建的Observable对象会从0开始,每隔固定的时间发射一个数字
- Repeat:将一个Observable对象重复发射,我们可以指定其发射的次数
- Timer:创建在一个指定的延迟之后发射单个数据的Observable
过滤操作符
- Distinct:删除序列中重复的元素,只允许还没有发射过的数据项通过
- distinctUntilChanged:和Distinct函数功能类似,是去掉连续重复的数据
- Debounce:与throttleWithTimeOut相同,如果在设定好的时间结束前源Observable有新的数据发射出来,这个数据就会被丢弃,同时重新开始计时,在一个指定的时间间隔过去了仍旧没有发射一个,那么它将发射最后的那个
- ElementAt: ElementAt只会返回指定位置的数据。其相关方法有elementAtOrDefault(int,T),可以允许默认值
- Filter: 允许传入一个Func,通过的数据才会被发射,特殊形式ofType(Class):Observable只返回指定类型的数据
- First和Last:First返回满足条件的第一条数据,被实现为first,firstOrDefault和takeFirst;Last操作符只返回最后一条满足条件的数据,被实现为last和lastOrDefault
- Skip和Take:Skip操作符将源Observable发射的数据过滤掉前n项,而Take操作符则只取前n项
- ThrottleFirst:定期发射这个时间段里源Observable发射的第一个数据
- Sample:定时地发射源Observable最近发射的数据,其他的都会被过滤掉,等效于ThrottleLast操作符
- ignoreElements:忽略所有源Observable产生的结果,只把Observable的onCompleted和onError事件通知给订阅者
参考链接
合并操作符
- combinelatest:将2~9个Observable发射的数据组装起来然后再发射出来,不过还有两个条件:
- 所有的Observable都发射过数据
- 任何一个Observable发射一个数据,就将所有Observable最新发射的数据按照提供的函数组装起来发射出去
- Merge:将多个Observable发射的数据整合起来发射,就如同是一个Observable发射的数据一样
- StartWith:会在源Observable发射的数据前面插上一些数据
- switch:将一个发射多个小Observable的源Observable转化为一个Observable,然后发射这多个小Observable所发射的数据
- Zip:将多个Observable发射的数据按顺序组合起来,每个数据只能组合一次,而且都是有序的。最终组合的数据的数量由发射数据最少的Observable来决定。
转换操作符
- Buffer — 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个
- FlatMap — 扁平映射,将Observable发射的数据变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,可以认为是一个将嵌套的数据结构展开的过程。
- GroupBy — 分组,将原来的Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据
- Map — 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项
- Scan — 扫描,对Observable发射的每一项数据应用一个函数,然后按顺序依次发射这些值
- Window — 窗口,定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。类似于Buffer,但Buffer发射的是数据,Window发射的是Observable,每一个Observable发射原始Observable的数据的一个子集