“SingleCoroutine”。用GameObject.Active来管理协程Coroutine的方案

time:20210909
更新一下这篇文章,现有版本StartCoroutine已经有返回值了,可以自己保存返回值,用于Stop。但是这篇SingleCoroutine还是有意义的。
取决于设计上采用什么样的设计模式。

因为Coroutine有各种开启方法
StartCoroutine(字符串);
StartCoroutine(函数);
StopCoroutine(字符串);
StopCoroutine(函数);
StopAllCoroutines();
用过就会知道 开启和停止的调用比较混乱。
用字符串启动,可以用字符串停止。
用函数启动,无法用函数停止。

1.为了解决这个对应关系,所以可以考虑到Coroutine和MonoBehaviour的特性:
Coroutine是依赖于MonoBehaviour运行的。
GameObject.Active设置为false,可以停止这个GameObject上MonoBehaviour的所有行为。
MonoBehaviour.Enable设置为false,可以停止这个脚本的所有行为。

2.经过测试,发现启动Coroutine可以用MonoBehaviour的子类启动,并不关注IEnumerator函数所在的脚本。
函数所在的脚本被Enable(false)或者Active(false),并不影响启动Coroutine的MonoBehaviour脚本继续跑Coroutine。
所以可以得出结论: Coroutine会跑在启动它的MonoBehaviour脚本上。

所以就有了SingleCoroutine的方案:
其实逻辑很简单,用一个空脚本Attach到GameObject上,用这个GameObject上的MonoBehaviour脚本去启动Coroutine。
那么我们要停止Coroutine,只需要操作这个GameObject或者MonoBehaviour脚本的 enable或者active 就可以了。

在这样的情况下,我们就无所谓启动Coroutine用哪种方法,因为停止Coroutine并不需要找对应的函数,
而是无脑简单的去关脚本就好了。

这个方案有个缺点就是 为了针对一个Coroutine做开关,
所以使用的时候,一个MonoBehaviour只允许启动一个Coroutine。启动多个。。那么停止的时候,就会把起在同一个MonoBehaviour的Coroutine全部停止。

代码如下:

SingleCoroutine类:

public class SingleCoroutine : MonoBehaviour
{
}

SingleCoroutine对象池;

	private Queue<SingleCoroutine> m_queueSingleCoroutine = new Queue<SingleCoroutine>();

	public SingleCoroutine AcquireSingleCoroutine()
	{
		SingleCoroutine result = null;
		if (m_queueSingleCoroutine.Count > 0)
		{
			result = m_queueSingleCoroutine.Dequeue();
		}
		else
		{
			GameObject newObj = new GameObject();
			result = newObj.AddComponent<SingleCoroutine>();
		}
		result.gameObject.SetActive(true);
		return result;
	}

	public void FreeSingleCoroutine(SingleCoroutine sc)
	{
		sc.StopAllCoroutines();
		sc.gameObject.SetActive(true);
		m_queueSingleCoroutine.Enqueue(sc);
	}

这边我使用了 sc.gameObject.SetActive(),实际上用MonoBehaviour.Enable也是可以的。用GameObject的原因是因为在面板上比较容易看到 灰色和白色的 Active状态,便于调试。而且对比之下性能差异,基本可以忽略。

测试代码:


	private SingleCoroutine m_scUsing = null;
	public void BeginCoroutineTest()
	{
		m_scUsing = AcquireSingleCoroutine();
		m_scUsing.StartCoroutine(test());
	}

	public void EndCoroutineTest()
	{
		FreeSingleCoroutine(m_scUsing);
	}

	private IEnumerator test()
	{
		Debug.Log("1");
		yield return new WaitForSeconds(1);
		Debug.Log("2");
		yield return new WaitForSeconds(1);
		Debug.Log("3");
		yield return new WaitForSeconds(1);
		Debug.Log("4");
		yield return new WaitForSeconds(1);
		Debug.Log("5");
		yield return new WaitForSeconds(1);
		Debug.Log("6");
		yield return new WaitForSeconds(1);
	}

	void Update ()
	{
		if (Input.GetKeyDown(KeyCode.A))
		{
			BeginCoroutineTest();
		}
		if (Input.GetKeyDown(KeyCode.S))
		{
			EndCoroutineTest();
		}
	}

这里的Demo是一个概念,具体编码和设计方法,可以随意调整。

程序学无止尽。
欢迎大家沟通,有啥不明确的,或者不对的,也可以和我私聊
我的QQ 334524067 神一般的狄狄

### ShowGS 和 HideGS 方法的功能 `ShowGS` 和 `HideGS` 是自定义的方法名称,在 Unity 中通常用于控制游戏对象 (`GameObject`) 的显示和隐藏状态。具体来说: - **`SetActive(true)`**: 将指定的游戏对象设置为活动状态,使其在游戏中可见并参与更新循环[^1]。 - **`SetActive(false)`**: 将指定的游戏对象设置为非活动状态,使其不可见且不参与任何更新操作。 以下是这两个方法可能的实现方式: ```csharp public void ShowGS(GameObject go) { go.SetActive(true); } public void HideGS(GameObject go) { go.SetActive(false); } ``` 当调用 `ShowGS` 或 `HideGS` 时,会分别激活或禁用传入的游戏对象。 --- ### 调试日志的作用 Unity 提供了 `Debug.Log()` 函数来记录调试信息到控制台 (Console),这对于开发过程中的错误排查非常重要[^2]。其主要功能如下: - 输出消息至 Console 面板,便于开发者实时查看程序运行的状态。 - 帮助定位代码执行路径,验证变量值是否符合预期。 - 支持多参数输入,可以打印复杂数据结构的信息。 例如: ```csharp void Example() { GameObject go = new GameObject("TestObject"); Debug.Log($"Game Object is active: {go.activeInHierarchy}"); // 打印当前状态 go.SetActive(false); Debug.Log($"After SetActive(false), Game Object is active: {go.activeInHierarchy}"); } ``` 上述代码展示了如何利用 `Debug.Log` 来跟踪游戏对象的活动状态变化。 --- ### 组件与游戏对象的关系 在 Unity 中,所有的组件都挂载在一个游戏对象上[^3]。这意味着如果要管理某个组件的行为,则需要先找到它所属的游戏对象。例如,可以通过以下方式获取组件实例: ```csharp Rigidbody rb = GetComponent<Rigidbody>(); if (rb != null) { Debug.Log("Rigidbody component found."); } else { Debug.Log("No Rigidbody attached to this object."); } ``` 此代码片段尝试检索当前游戏对象上的刚体组件,并通过调试日志确认是否存在该组件。 --- ### 总结 - `ShowGS` 和 `HideGS` 方法的核心在于调整游戏对象的活动状态,从而影响它们在场景中的表现。 - `Debug.Log` 是一种简单而有效的工具,能够辅助开发者监控应用程序内部的工作流程。 - 游戏对象及其关联的组件构成了 Unity 场景的基础单元;合理运用这些机制有助于构建复杂的交互逻辑。 --- ####
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值