12.UI监听
12.1 知识点
使用 UniTask 异步监听 UI 事件
在本篇博客中,我们将介绍如何通过 UniTask 高效地处理 Unity UI 事件监听。通过对按钮点击、输入框编辑、Toggle 与 Slider 数值变化等事件的异步监听,能够使项目代码更加简洁和高效。下面将结合具体代码示例详细讲解各个场景的实现方式。
测试脚本
using System;
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks.Linq; // 引入异步 LINQ 支持
// 注释说明:若要注册事件并使用异步的 lambda,请勿使用 async void,
// 可使用 UniTask.Action 或 UniTask.UnityAction 通过 async UniTaskVoid lambda 创建委托。
// 示例:
// UniTask.Action(
// async () =>
// {
// Debug.Log("aa");
// await UniTask.Delay(1000);
// }
// );
// 注释说明:按钮点击事件可通过 OnClickAsync 转换为异步事件,其他 UI 组件类似。
// UniTask 提供了 GetCancellationTokenOnDestroy() 方法用于管理生命周期。
public class Lesson12_UI监听 : MonoBehaviour
{
public Button btn1;
public Button btn2;
public Button btn3;
public Button btn4;
public InputField inputField;
public Toggle toggle; // 新增 Toggle 组件
public Slider slider; // 新增 Slider 组件
void Start()
{
// 示例一:启动对 btn1 的不同监听方式
// 只能响应一次点击
OnClickBtn1AwaitOne().Forget();
// 持续监听点击事件
OnClickBtn1AwaitMore(this.GetCancellationTokenOnDestroy()).Forget();
// 示例二:对 btn2 采用不同的监听和处理方式监听按钮点击间隔 判断是单击还是双击
OnClickBtn2UniTask(this.GetCancellationTokenOnDestroy()).Forget();
// 示例三:使用异步 LINQ 监听 btn3 三次点击 只会监听一次三连点击
OnClickBtn3TripleClick(this.GetCancellationTokenOnDestroy()).Forget();
// 示例四:使用事件排队处理 btn4 点击事件
OnClickBtn4QueueEvents(this.GetCancellationTokenOnDestroy()).Forget();
// 示例五:监听输入框结束编辑事件
OnInputFieldEndEdit(this.GetCancellationTokenOnDestroy()).Forget();
// 示例六:监听 Toggle 值变化(异步流,实时输出变化值)
OnToggleValueChangedAsync(this.GetCancellationTokenOnDestroy()).Forget();
// 示例七:监听 Slider 值变化(异步流,每次变化输出当前值)
OnSliderValueChangedAsync(this.GetCancellationTokenOnDestroy()).Forget();
}
/// <summary>
/// 该方法监听按钮的点击事件,但只能响应一次点击。
/// 因为 await 语句只会执行一次,之后不会再监听点击事件。
/// </summary>
private async UniTaskVoid OnClickBtn1AwaitOne()
{
// 等待 btn1 被点击
await btn1.OnClickAsync();
Debug.Log("OnClickBtn1AwaitOne 再次点击无效:" + Time.time);
}
/// <summary>
/// 该方法可以持续监听按钮的点击事件。
/// 每次按钮被点击时,都会输出当前的时间。
/// </summary>
/// <param name="cancellationToken">用于取消异步操作的 CancellationToken,可通过 GetCancellationTokenOnDestroy 方法获取。</param>
private async UniTaskVoid OnClickBtn1AwaitMore(CancellationToken cancellationToken)
{
// 进入无限循环,持续监听按钮点击事件
while (true)
{
// 获取 btn1 点击事件的异步任务,传入取消令牌
var btnUniTask = btn1.OnClickAsync(cancellationToken);
// 等待 btn1 点击事件完成
await btnUniTask;
// 按钮点击后,输出日志显示点击时间
Debug.Log("OnClickBtn1AwaitMore:" + Time.time);
}
}
/// <summary>
/// 该方法使用 UniTask 处理 btn2 的点击事件,判断是单击还是双击。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn2UniTask(CancellationToken cancellationToken)
{
// 进入无限循环,持续处理 btn2 的点击事件
while (true)
{
// 获取 btn2 第一次点击事件的异步任务
var firstClickUniTask = btn2.OnClickAsync(cancellationToken);
// 等待 btn2 第一次点击事件完成
await firstClickUniTask;
// 输出第一次点击的日志信息
Debug.Log("OnClickBtn2UniTask 第1次点击");
// 获取 btn2 第二次点击事件的异步任务
var secondClickUniTask = btn2.OnClickAsync(cancellationToken);
// 判断是单击还是双击,即判断指定时间内是否又点击了,也就是判断第二次点击和等待 1 秒这两个任务发生的先后顺序
int index = await UniTask.WhenAny(secondClickUniTask,
UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cancellationToken));
// 根据 index 判断是第二次点击先发生还是等待 1 秒先完成
if (index == 0)
{
// 若 index 为 0,说明第二次点击先发生,时间间隔不超过 1 秒
Debug.Log("OnClickBtn2UniTask 时间间隔不超过1");
}
else
{
// 若 index 不为 0,说明等待 1 秒先完成,时间间隔超过 1 秒
Debug.Log("OnClickBtn2UniTask 时间间隔超过1");
}
}
}
/// <summary>
/// 该方法使用异步 LINQ 监听 btn3 三次点击。
/// 注意:该方法只会监听一次三连点击,不会持续监听。
/// 如果需要持续监听,需要自己加while
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn3TripleClick(CancellationToken cancellationToken)
{
// 使用异步 LINQ 等待 btn3 被点击三次
// await btn3.OnClickAsAsyncEnumerable().Take(3).LastAsync(cancellationToken);
await btn3.OnClickAsAsyncEnumerable().Take(3)
.ForEachAsync(_ => { Debug.Log("OnClickBtn3TripleClick: 每次点击触发"); }, cancellationToken);
// // index从0开始 第一次点击index会是0 所以取到的是0 1 2 index为2时 也就是第三次点击 所以会输出三次点击完成
// var asyncEnumerable = btn3.OnClickAsAsyncEnumerable();
// await asyncEnumerable.Take(3).ForEachAsync
// ((_, index) =>
// {
// if (cancellationToken.IsCancellationRequested) return;
//
// if (index == 0)
// {
// Debug.Log(0);
// }
// else if (index == 1)
// {
// Debug.Log(1);
// }
// else
// {
// Debug.Log(2);
// }
// }, cancellationToken);
Debug.Log("OnClickBtn3TripleClick: 三次点击完成");
}
/// <summary>
/// 该方法使用事件排队处理 btn4 点击事件。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn4QueueEvents(CancellationToken cancellationToken)
{
// 对 btn4 的点击事件进行排队处理
// 每次点击事件都会被添加到队列中,然后依次处理
// 比如如下示例中 要等三秒才能处理下一个点击事件
// 处理完成后,队列中的事件会被移除
int count = 0;
await btn4.OnClickAsAsyncEnumerable().Queue().ForEachAwaitAsync(async _ =>
{
Debug.Log($"OnClickBtn4QueueEvents: 开始处理点击事件{count}");
await UniTask.Delay(TimeSpan.FromSeconds(3), cancellationToken: cancellationToken);
Debug.Log($"OnClickBtn4QueueEvents: 点击事件{count}处理完成");
count++;
}, cancellationToken);
}
/// <summary>
/// 该方法监听输入框结束编辑事件。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnInputFieldEndEdit(CancellationToken cancellationToken)
{
// 监听输入框结束编辑事件
await foreach (var text in inputField.OnEndEditAsAsyncEnumerable().WithCancellation(cancellationToken))
{
Debug.Log($"OnInputFieldEndEdit: 输入框结束编辑,输入内容为: {text}");
}
}
/// <summary>
/// 示例六:监听 Toggle 的值变化事件,并在每次变化时输出当前值
/// </summary>
private async UniTaskVoid OnToggleValueChangedAsync(CancellationToken cancellationToken)
{
await toggle.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Toggle 值变化:" + value); });
}
/// <summary>
/// 示例七:监听 Slider 的值变化事件,并在每次变化时输出当前值
/// </summary>
private async UniTaskVoid OnSliderValueChangedAsync(CancellationToken cancellationToken)
{
await slider.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Slider 当前值:" + value); });
}
}
该脚本主要演示了以下功能:
- 按钮点击事件:分别展示了仅响应一次点击、持续监听点击、以及通过双击判断操作。
- 异步 LINQ 操作:使用异步 LINQ 实现对按钮连续点击次数的监听。
- 事件排队处理:对按钮点击事件进行排队,确保每个事件按顺序依次处理。
- UI 组件事件监听:包括输入框结束编辑、Toggle 状态变化以及 Slider 数值变化的实时监听。
代码中充分利用了 UniTask 的异步流和取消令牌,确保在 MonoBehaviour 销毁时能正确取消异步操作,避免内存泄漏或异常。
示例一:按钮不同监听方式
使用 OnClickBtn1AwaitOne
方法,仅等待按钮被点击一次,后续点击不再响应。这种方式适用于需要一次性操作的场景。
private async UniTaskVoid OnClickBtn1AwaitOne()
{
// 等待 btn1 被点击
await btn1.OnClickAsync();
Debug.Log("OnClickBtn1AwaitOne 再次点击无效:" + Time.time);
}
通过 OnClickBtn1AwaitMore
方法实现无限循环,每次点击按钮都会记录当前时间,适合需要实时响应用户点击的情况。
private async UniTaskVoid OnClickBtn1AwaitMore(CancellationToken cancellationToken)
{
// 进入无限循环,持续监听按钮点击事件
while (true)
{
// 获取 btn1 点击事件的异步任务,传入取消令牌
var btnUniTask = btn1.OnClickAsync(cancellationToken);
// 等待 btn1 点击事件完成
await btnUniTask;
// 按钮点击后输出日志显示点击时间
Debug.Log("OnClickBtn1AwaitMore:" + Time.time);
}
}
示例二:判断单击与双击
在 OnClickBtn2UniTask
方法中,首先等待第一次点击,然后在 1 秒内判断是否有第二次点击,从而区分单击和双击操作。
private async UniTaskVoid OnClickBtn2UniTask(CancellationToken cancellationToken)
{
while (true)
{
// 等待第一次点击
var firstClickUniTask = btn2.OnClickAsync(cancellationToken);
await firstClickUniTask;
Debug.Log("OnClickBtn2UniTask 第1次点击");
// 等待第二次点击或 1 秒超时
int index = await UniTask.WhenAny(
btn2.OnClickAsync(cancellationToken),
UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cancellationToken)
);
if (index == 0)
{
// 第二次点击在 1 秒内发生
Debug.Log("OnClickBtn2UniTask 时间间隔不超过1");
}
else
{
// 1 秒超时,视为单击
Debug.Log("OnClickBtn2UniTask 时间间隔超过1");
}
}
}
示例三:异步 LINQ 监听三连点击
使用异步 LINQ 操作,在 OnClickBtn3TripleClick
方法中等待按钮被点击三次后再执行后续代码,适用于需要捕捉用户快速连续操作的场景。
/// <summary>
/// 该方法使用异步 LINQ 监听 btn3 三次点击。
/// 注意:该方法只会监听一次三连点击,不会持续监听。
/// 如果需要持续监听,需要自己加while
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn3TripleClick(CancellationToken cancellationToken)
{
// 使用异步 LINQ 等待 btn3 被点击三次
// await btn3.OnClickAsAsyncEnumerable().Take(3).LastAsync(cancellationToken);
await btn3.OnClickAsAsyncEnumerable().Take(3)
.ForEachAsync(_ => { Debug.Log("OnClickBtn3TripleClick: 每次点击触发"); }, cancellationToken);
// // index从0开始 第一次点击index会是0 所以取到的是0 1 2 index为2时 也就是第三次点击 所以会输出三次点击完成
// var asyncEnumerable = btn3.OnClickAsAsyncEnumerable();
// await asyncEnumerable.Take(3).ForEachAsync
// ((_, index) =>
// {
// if (cancellationToken.IsCancellationRequested) return;
//
// if (index == 0)
// {
// Debug.Log(0);
// }
// else if (index == 1)
// {
// Debug.Log(1);
// }
// else
// {
// Debug.Log(2);
// }
// }, cancellationToken);
Debug.Log("OnClickBtn3TripleClick: 三次点击完成");
}
示例四:事件排队处理
在 OnClickBtn4QueueEvents
方法中,通过事件排队的方式处理按钮点击,每次点击事件处理之间等待固定时间,确保事件顺序执行而不会互相干扰。
private async UniTaskVoid OnClickBtn4QueueEvents(CancellationToken cancellationToken)
{
int count = 0;
await btn4.OnClickAsAsyncEnumerable().Queue().ForEachAwaitAsync(async _ =>
{
Debug.Log($"OnClickBtn4QueueEvents: 开始处理点击事件{count}");
await UniTask.Delay(TimeSpan.FromSeconds(3), cancellationToken: cancellationToken);
Debug.Log($"OnClickBtn4QueueEvents: 点击事件{count}处理完成");
count++;
}, cancellationToken);
}
示例五:监听输入框结束编辑事件
使用 OnInputFieldEndEdit
方法,通过异步流实时监听输入框结束编辑事件,并输出用户输入的内容。此方式适合需要捕捉用户输入并即时反馈的场景。
private async UniTaskVoid OnInputFieldEndEdit(CancellationToken cancellationToken)
{
// 监听输入框结束编辑事件
await foreach (var text in inputField.OnEndEditAsAsyncEnumerable().WithCancellation(cancellationToken))
{
Debug.Log($"OnInputFieldEndEdit: 输入框结束编辑,输入内容为: {text}");
}
}
示例六:监听 Toggle 值变化
在 OnToggleValueChangedAsync
方法中,通过异步流监听 Toggle 的值变化事件,每次变化时输出当前值,使状态变更能够及时反馈到日志中。
private async UniTaskVoid OnToggleValueChangedAsync(CancellationToken cancellationToken)
{
await toggle.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Toggle 值变化:" + value); });
}
示例七:监听 Slider 值变化
类似于 Toggle,OnSliderValueChangedAsync
方法通过异步流监听 Slider 数值变化,每次变化都输出当前值,方便对滑动条数值的动态监控。
private async UniTaskVoid OnSliderValueChangedAsync(CancellationToken cancellationToken)
{
await slider.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Slider 当前值:" + value); });
}
总结
UniTask 赋予了我们强大的异步处理能力,通过本文的示例,我们可以看到如何高效地监听和处理 UI 组件的各种事件。无论是针对按钮的单次点击、持续监听、双击判断,还是利用异步流实时捕获输入框、Toggle 与 Slider 的变化,都充分展现了 UniTask 在简化代码逻辑、提升运行性能方面的优势。
UniTask 在 UI 事件处理中的核心优势:
无阻塞异步操作
利用async/await
机制,确保 UI 事件处理在后台进行,不会阻塞主线程,从而保障流畅的用户体验。轻量高效的实现
采用结构体和对象池的设计,大幅降低垃圾回收压力,使得高频事件处理更加稳定。灵活的事件调度
结合CancellationToken
和异步 LINQ,不仅能够精细控制事件处理流程,还能轻松应对复杂的交互逻辑。
最佳实践提示:
- 在组件销毁时,务必使用
GetCancellationTokenOnDestroy()
来管理异步任务,防止潜在的内存泄露。 - 对于频繁变化的 UI 事件(如 Slider 滑动),优先采用异步流 (
AsAsyncEnumerable
) 方式进行监听,确保数据更新高效稳定。 - 当存在多重事件逻辑或需要顺序处理时,可通过
Queue()
方法对事件进行排队,保证每个事件都能得到妥善处理。
总之,合理运用 UniTask 的异步处理策略不仅能够显著提升代码的可读性和可维护性,更能在高交互的应用场景中带来更佳的性能表现和用户体验。通过本文提供的方案,开发者可以轻松应对复杂的 UI 事件逻辑,实现更优质的应用开发。
12.2 知识点代码
Lesson12_UI监听.cs
using System;
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks.Linq; // 引入异步 LINQ 支持
// 注释说明:若要注册事件并使用异步的 lambda,请勿使用 async void,
// 可使用 UniTask.Action 或 UniTask.UnityAction 通过 async UniTaskVoid lambda 创建委托。
// 示例:
// UniTask.Action(
// async () =>
// {
// Debug.Log("aa");
// await UniTask.Delay(1000);
// }
// );
// 注释说明:按钮点击事件可通过 OnClickAsync 转换为异步事件,其他 UI 组件类似。
// UniTask 提供了 GetCancellationTokenOnDestroy() 方法用于管理生命周期。
public class Lesson12_UI监听 : MonoBehaviour
{
public Button btn1;
public Button btn2;
public Button btn3;
public Button btn4;
public InputField inputField;
public Toggle toggle; // 新增 Toggle 组件
public Slider slider; // 新增 Slider 组件
void Start()
{
// 示例一:启动对 btn1 的不同监听方式
// 只能响应一次点击
OnClickBtn1AwaitOne().Forget();
// 持续监听点击事件
OnClickBtn1AwaitMore(this.GetCancellationTokenOnDestroy()).Forget();
// 示例二:对 btn2 采用不同的监听和处理方式监听按钮点击间隔 判断是单击还是双击
OnClickBtn2UniTask(this.GetCancellationTokenOnDestroy()).Forget();
// 示例三:使用异步 LINQ 监听 btn3 三次点击 只会监听一次三连点击
OnClickBtn3TripleClick(this.GetCancellationTokenOnDestroy()).Forget();
// 示例四:使用事件排队处理 btn4 点击事件
OnClickBtn4QueueEvents(this.GetCancellationTokenOnDestroy()).Forget();
// 示例五:监听输入框结束编辑事件
OnInputFieldEndEdit(this.GetCancellationTokenOnDestroy()).Forget();
// 示例六:监听 Toggle 值变化(异步流,实时输出变化值)
OnToggleValueChangedAsync(this.GetCancellationTokenOnDestroy()).Forget();
// 示例七:监听 Slider 值变化(异步流,每次变化输出当前值)
OnSliderValueChangedAsync(this.GetCancellationTokenOnDestroy()).Forget();
}
/// <summary>
/// 该方法监听按钮的点击事件,但只能响应一次点击。
/// 因为 await 语句只会执行一次,之后不会再监听点击事件。
/// </summary>
private async UniTaskVoid OnClickBtn1AwaitOne()
{
// 等待 btn1 被点击
await btn1.OnClickAsync();
Debug.Log("OnClickBtn1AwaitOne 再次点击无效:" + Time.time);
}
/// <summary>
/// 该方法可以持续监听按钮的点击事件。
/// 每次按钮被点击时,都会输出当前的时间。
/// </summary>
/// <param name="cancellationToken">用于取消异步操作的 CancellationToken,可通过 GetCancellationTokenOnDestroy 方法获取。</param>
private async UniTaskVoid OnClickBtn1AwaitMore(CancellationToken cancellationToken)
{
// 进入无限循环,持续监听按钮点击事件
while (true)
{
// 获取 btn1 点击事件的异步任务,传入取消令牌
var btnUniTask = btn1.OnClickAsync(cancellationToken);
// 等待 btn1 点击事件完成
await btnUniTask;
// 按钮点击后,输出日志显示点击时间
Debug.Log("OnClickBtn1AwaitMore:" + Time.time);
}
}
/// <summary>
/// 该方法使用 UniTask 处理 btn2 的点击事件,判断是单击还是双击。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn2UniTask(CancellationToken cancellationToken)
{
// 进入无限循环,持续处理 btn2 的点击事件
while (true)
{
// 获取 btn2 第一次点击事件的异步任务
var firstClickUniTask = btn2.OnClickAsync(cancellationToken);
// 等待 btn2 第一次点击事件完成
await firstClickUniTask;
// 输出第一次点击的日志信息
Debug.Log("OnClickBtn2UniTask 第1次点击");
// 获取 btn2 第二次点击事件的异步任务
var secondClickUniTask = btn2.OnClickAsync(cancellationToken);
// 判断是单击还是双击,即判断指定时间内是否又点击了,也就是判断第二次点击和等待 1 秒这两个任务发生的先后顺序
int index = await UniTask.WhenAny(secondClickUniTask,
UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cancellationToken));
// 根据 index 判断是第二次点击先发生还是等待 1 秒先完成
if (index == 0)
{
// 若 index 为 0,说明第二次点击先发生,时间间隔不超过 1 秒
Debug.Log("OnClickBtn2UniTask 时间间隔不超过1");
}
else
{
// 若 index 不为 0,说明等待 1 秒先完成,时间间隔超过 1 秒
Debug.Log("OnClickBtn2UniTask 时间间隔超过1");
}
}
}
/// <summary>
/// 该方法使用异步 LINQ 监听 btn3 三次点击。
/// 注意:该方法只会监听一次三连点击,不会持续监听。
/// 如果需要持续监听,需要自己加while
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn3TripleClick(CancellationToken cancellationToken)
{
// 使用异步 LINQ 等待 btn3 被点击三次
// await btn3.OnClickAsAsyncEnumerable().Take(3).LastAsync(cancellationToken);
await btn3.OnClickAsAsyncEnumerable().Take(3)
.ForEachAsync(_ => { Debug.Log("OnClickBtn3TripleClick: 每次点击触发"); }, cancellationToken);
// // index从0开始 第一次点击index会是0 所以取到的是0 1 2 index为2时 也就是第三次点击 所以会输出三次点击完成
// var asyncEnumerable = btn3.OnClickAsAsyncEnumerable();
// await asyncEnumerable.Take(3).ForEachAsync
// ((_, index) =>
// {
// if (cancellationToken.IsCancellationRequested) return;
//
// if (index == 0)
// {
// Debug.Log(0);
// }
// else if (index == 1)
// {
// Debug.Log(1);
// }
// else
// {
// Debug.Log(2);
// }
// }, cancellationToken);
Debug.Log("OnClickBtn3TripleClick: 三次点击完成");
}
/// <summary>
/// 该方法使用事件排队处理 btn4 点击事件。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnClickBtn4QueueEvents(CancellationToken cancellationToken)
{
// 对 btn4 的点击事件进行排队处理
// 每次点击事件都会被添加到队列中,然后依次处理
// 比如如下示例中 要等三秒才能处理下一个点击事件
// 处理完成后,队列中的事件会被移除
int count = 0;
await btn4.OnClickAsAsyncEnumerable().Queue().ForEachAwaitAsync(async _ =>
{
Debug.Log($"OnClickBtn4QueueEvents: 开始处理点击事件{count}");
await UniTask.Delay(TimeSpan.FromSeconds(3), cancellationToken: cancellationToken);
Debug.Log($"OnClickBtn4QueueEvents: 点击事件{count}处理完成");
count++;
}, cancellationToken);
}
/// <summary>
/// 该方法监听输入框结束编辑事件。
/// </summary>
/// <param name="cancellationToken"></param>
private async UniTaskVoid OnInputFieldEndEdit(CancellationToken cancellationToken)
{
// 监听输入框结束编辑事件
await foreach (var text in inputField.OnEndEditAsAsyncEnumerable().WithCancellation(cancellationToken))
{
Debug.Log($"OnInputFieldEndEdit: 输入框结束编辑,输入内容为: {text}");
}
}
/// <summary>
/// 示例六:监听 Toggle 的值变化事件,并在每次变化时输出当前值
/// </summary>
private async UniTaskVoid OnToggleValueChangedAsync(CancellationToken cancellationToken)
{
await toggle.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Toggle 值变化:" + value); });
}
/// <summary>
/// 示例七:监听 Slider 的值变化事件,并在每次变化时输出当前值
/// </summary>
private async UniTaskVoid OnSliderValueChangedAsync(CancellationToken cancellationToken)
{
await slider.OnValueChangedAsAsyncEnumerable(cancellationToken)
.ForEachAsync(value => { Debug.Log("Slider 当前值:" + value); });
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com