2.定时功能实现
在 Unity 开发中,延时是我们经常要实现的功能,这个功能对于有点经验的开发者来说不难。
最常见的实现方式如下:
using
UnityEngine
;
public
class
CommonDelayExample
:
MonoBehaviour
{
private
float
mStartTime
;
void
Start
(
)
{
mStartTime
=
Time
.
time
;
}
void
Update
(
)
{
if
(
Time
.
time
-
mStartTime
>
5
)
{
DoSomething
(
)
;
// 避免再次执行
mStartTime
=
float
.
MaxValue
;
}
}
void
DoSomething
(
)
{
Debug
.
Log
(
"DoSomething"
)
;
}
}
这是很多初学者刚入门时候的实现方式,而初学者们随着深入学习后来接触到了 Coroutine(协程),使用 Coroutine 实现定时功能会更容易,而且也是更好的选择,实现如下:
using
System
;
using
System
.
Collections
;
using
UnityEngine
;
public
class
CoroutineDelayExample
:
MonoBehaviour
{
void
Start
(
)
{
StartCoroutine
(
Timer
(
5
,
DoSomething
)
)
;
}
IEnumerator
Timer
(
float
seconds
,
Action
callback
)
{
yield
return
new
WaitForSeconds
(
seconds
)
;
callback
(
)
;
}
void
DoSomething
(
)
{
Debug
.
Log
(
"DoSomething"
)
;
}
}
协程已经把代码精简了很多,不过接下来有更厉害的,使用 UniRx。
代码如下:
Observable
.
Timer
(
TimeSpan
.
FromSeconds
(
5
)
)
.
Subscribe
(
_
=>
{
/* do something */
}
)
;
当然以上代码是没有和 MonoBehaviour 进行生命周期绑定的,也就是说当 MonoBehaviour 销毁了之后,这个定时逻辑可能还在执行,这样就会有造成空指针异常的风险。
要解决也很简单,代码如下:
Observable
.
Timer
(
TimeSpan
.
FromSeconds
(
5
)
)
.
Subscribe
(
_
=>
{
/* do something */
}
)
.
AddTo
(
this
)
;
只要加上一个 AddTo(this) 就可以了。 这样,当 this(MonoBehaviour) Destroy 的时候,这个延时逻辑也会销毁掉,从而避免造成空指针异常。
三行代码,写下来大约 20 秒的时间,就搞定了一个实现起来比较麻烦的逻辑。
今天的内容就这些。
知识地图
3.独立的 Update
在 UniRx 简介的时候,笔者讲了一种比较麻烦的情况:就是在 MonoBehaviour 的 Update 中掺杂了大量互相无关的逻辑,导致代码非常不容易阅读。
这种情况我们平时在项目开发中非常常见,代码如下:
private
void
Update
(
)
{
if
(
A
)
{
..
.
}
if
(
B
)
{
..
.
if
(
D
)
{
..
.
}
else
{
}
}
switch
(
C
)
{
..
.
}
if
(
Input
.
GetMouseButtonUp
(
0
)
)
{
..
.
}
}
Update 方法中代码冗长,而且干扰视线,非常影响阅读。
而使用 UniRx 则可以改善这个问题。
void
Start
(
)
{
// A 逻辑,实现了 xx
Observable
.
EveryUpdate
(
)
.
Subscribe
(
_
=>
{
if
(
A
)
{
..
.
}
}
)
.
AddTo
(
this
)
;
// B 逻辑,实现了 xx
Observable
.
EveryUpdate
(
)
.
Subscribe
(
_
=>
{
if
(
B
)
{
..
.
if
(
D
)
{
..
.
}
else
{
}
}
}
)
.
AddTo
(
this
)
;
// C 逻辑,实现了 xx
Observable
.
EveryUpdate
(
)
.
Subscribe
(
_
=>
{
switch
(
C
)
{
..
.
}
}
)
.
AddTo
(
this
)
;
// 鼠标点击检测逻辑
Observable
.
EveryUpdate
(
)
.
Subscribe
(
_
=>
{
{
if
(
Input
.
GetMouseButtonUp
(
0
)
)
{
..
.
}
}
)
.
AddTo
(
this
)
;
}
虽然在代码长度上没有任何改善,但是最起码,这些 Update 逻辑互相之间独立了。 状态跳转、延时等等这些经常在 Update 里实现的逻辑,都可以使用以上这种方式独立。
使用 UniRx 可以对我们工程中的代码进行了改善,而笔者接触 UniRx 之后,就再也没有使用过 Update 方法了。
不过以上的这种 UniRx 使用方式,是比较初级的,而这种使用方式,随着对 UniRx 的深入学习,也会渐渐淘汰,因为等我们入门之后,会学习更好的实现方式。
今天的内容就这些。
知识地图
转载请注明地址:凉鞋的笔记:
liangxiegame.com
更多内容
-
QFramework 地址: https://github.com/liangxiegame/QFramework
-
QQ 交流群: 623597263
-
2020届Unity 凉鞋小班招生 :
-
关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。
721

被折叠的 条评论
为什么被折叠?



