我们都知道同步方法是一步一步执行,但是不总能够一条道走到黑,特别是在资源加载的时候
一、协程加载(假异步)
代码如下,比较简单
using System.Collections;
using UnityEngine;
public class CoroutineExample : MonoBehaviour
{
private void Start()
{
StartCoroutine(MyCoroutine());
}
private IEnumerator MyCoroutine()
{
Debug.Log("Coroutine Started");
// 等待2秒
yield return new WaitForSeconds(2f);
Debug.Log("Coroutine Resumed after 2 seconds");
// 每隔1秒打印一次信息,重复5次
for (int i = 0; i < 5; i++)
{
Debug.Log("Coroutine Running: " + i);
yield return new WaitForSeconds(1f);
}
Debug.Log("Coroutine Finished");
}
}
协程后台实际上是使用状态机进行的
Additional:状态机
状态机(State Machine)是一种用于描述对象在不同状态下的行为和状态转换的数学模型。它通常用于建模实体(Entity)的状态和行为
比如:
using System;
using UnityEngine;
public enum CharacterState
{
Idle,
Walk,
Jump
}
public class CharacterStateMachine
{
private CharacterState currentState;
public CharacterStateMachine()
{
// 初始状态为站立
currentState = CharacterState.Idle;
}
public void TransitionToState(CharacterState newState)
{
if (currentState != newState)
{
switch (newState)
{
case CharacterState.Idle:
// 执行从其他状态到站立状态的转换逻辑
Debug.Log("Transitioning to Idle state");
break;
case CharacterState.Walk:
// 执行从站立到行走状态的转换逻辑
Debug.Log("Transitioning to Walk state");
break;
case CharacterState.Jump:
// 执行从站立或行走到跳跃状态的转换逻辑
Debug.Log("Transitioning to Jump state");
break;
default:
break;
}
currentState = newState;
}
}
public CharacterState GetCurrentState()
{
return currentState;
}
}
public class CharacterController : MonoBehaviour
{
private CharacterStateMachine stateMachine;
void Start()
{
stateMachine = new CharacterStateMachine();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
// 当按下W键时,切换到行走状态
stateMachine.TransitionToState(CharacterState.Walk);
}
else if (Input.GetKeyDown(KeyCode.Space))
{
// 当按下空格键时,切换到跳跃状态
stateMachine.TransitionToState(CharacterState.Jump);
}
Debug.Log("Current state: " + stateMachine.GetCurrentState());
}
}
这就是一种简单的状态机,简单说就是几种状态,对应几种枚举,在每一种状态下执行一种命令
二、Async/Await异步加载
拿这个登录的方法举例
public async UniTask<bool> Login(string username, string password)
{
var url = $"{root}?username={username}&password={password}";
HTTPRequest request = new HTTPRequest(new Uri(url), HTTPMethods.Post);
await request.Send();
if (request.Exception != null)
{
Debug.Log("请求异常" + request.Exception.Message);
return false;
}
else if (request.Response.IsSuccess)
{
Debug.Log("response success!");
string stringResponse = request.Response.DataAsText;
response = JsonMapper.ToObject<ResponseResult>(stringResponse);
bool isSuccess = response.success;
Debug.Log(isSuccess);
Debug.Log(response.result);
return isSuccess;
}
return false;
}
把链接的请求丢给服务器,然后让服务器返回相应的内容,我们做出下一步的判断,这个方法就使用了async/await方法进行,避免放到主线程会堵塞线程
三、Thread线程
还是拿代码进行举例
using System;
using System.Threading;
class Program
{
static void Main()
{
// 创建一个新线程并指定执行的方法
Thread thread = new Thread(new ThreadStart(WorkerMethod));
// 启动线程
thread.Start();
// 主线程继续执行其他工作
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Main Thread: " + i);
Thread.Sleep(1000); // 主线程休眠1秒
}
// 等待新线程执行完成
thread.Join();
Console.WriteLine("Main Thread Done");
}
static void WorkerMethod()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Worker Thread: " + i);
Thread.Sleep(1000); // 新线程休眠1秒
}
}
}
我们可以看出,协程是类似于线程的,不过它不是真正的线程,事实上它是一种轻量级的协作多任务系统,它使用状态机和主线程来实现异步操作,而不是创建新的操作系统线程。这使得编写异步代码变得更加容易,而无需担心多线程的复杂性。