Unity 任务系统

Unity 任务系统实现

任务系统包含一个管理类和事件类,通过重写事件类中的方法来实现事件生命周期内容(直接上代码)

接口类

public interface ITaskEvent
    {
        public enum ETaskStatus
        {
            NotStart = 0,
            InProcessing,
            Completed,
            Failed
        }

        public enum ESyncType
        {
            Sync,
            Async
        }
        
        public void Update();
        public void Completed();
        public void Failed();
        public void Interrut();
        public ESyncType GetSyncType();
        public ETaskStatus GetStatus();
    }

事件类

public abstract class TaskEvent : ITaskEvent
    {
        private ITaskEvent.ESyncType SyncType { get; set; }
        private ITaskEvent.ETaskStatus Status { get; set; }
        
        public event Action<TaskEvent, ITaskEvent.ETaskStatus> TaskStatusChange;

        public virtual void Initialize(ITaskEvent.ESyncType syncType = ITaskEvent.ESyncType.Sync)
        {
            SyncType = syncType;
            Status = ITaskEvent.ETaskStatus.NotStart;
        }

        public void Start()
        {
            Status = ITaskEvent.ETaskStatus.InProcessing;
            TaskStatusChange?.Invoke(this, ITaskEvent.ETaskStatus.NotStart);
            OnStart();
        }

        public void Update()
        {
            TaskStatusChange?.Invoke(this, ITaskEvent.ETaskStatus.InProcessing);
            OnUpdate();
        }
        
        public void Completed()
        {
            if (GetStatus() == ITaskEvent.ETaskStatus.Failed) return;
            
            Status = ITaskEvent.ETaskStatus.Completed;
            TaskStatusChange?.Invoke(this, ITaskEvent.ETaskStatus.Completed);
            OnCompleted();
        }
        
        public void Failed()
        {
            if (GetStatus() == ITaskEvent.ETaskStatus.Completed) return;
            
            Status = ITaskEvent.ETaskStatus.Failed;
            TaskStatusChange?.Invoke(this, ITaskEvent.ETaskStatus.Failed);
            OnFailed();
        }

        public void Interrut()
        {
            Status = ITaskEvent.ETaskStatus.Completed;
            TaskStatusChange?.Invoke(this, ITaskEvent.ETaskStatus.Completed);
            OnInterrut();
        }
        
        protected virtual void OnUpdate() { }
        protected virtual void OnStart() { }
        protected virtual void OnCompleted() { }
        protected virtual void OnFailed() { }
        protected virtual void OnInterrut() { }

        public ITaskEvent.ESyncType GetSyncType()
        {
            return SyncType;
        }
        public ITaskEvent.ETaskStatus GetStatus()
        {
            return Status;
        }
    }

管理类

(注:单例模式实现参考之前文章)

public class TaskEventManager : MonoSingleton<TaskEventManager>
    {
        private bool IsRunning { get; set; }
        private bool Paused { get; set; }
        private List<TaskEvent> TaskEvents { get; set; } = new();

        private WaitForSeconds WaitHalfSeconds { get; set; } = new WaitForSeconds(0.5f);

        private void Start()
        {
            IsRunning = true;
            StartCoroutine(DoTask());
        }

        public TaskEvent AddTask(TaskEvent task)
        {
            task.Initialize();
            TaskEvents.Add(task);
            return task;
        }

        public void RemoveTask(TaskEvent task)
        {
            if (TaskEvents.Remove(task))
            {
                task.Interrut();
            }
        }

        public void Pause()
        {
            Paused = true;
        }

        public void Resume()
        {
            Paused = false;
        }

        private IEnumerator DoTask()
        {
            yield return WaitHalfSeconds;
            
            while (IsRunning)
            {
                if (Paused || TaskEvents.Count == 0)
                {
                    yield return WaitHalfSeconds;
                }
                
                var indexer = 0;
                while (indexer < TaskEvents.Count)
                {
                    var task = TaskEvents[indexer];
                    switch (task.GetStatus())
                    {
                        case ITaskEvent.ETaskStatus.NotStart:
                            task.Start();
                            break;
                        case ITaskEvent.ETaskStatus.InProcessing:
                            task.Update();
                            break;
                        case ITaskEvent.ETaskStatus.Completed:
                            task.Completed();
                            break;
                        case ITaskEvent.ETaskStatus.Failed:
                            task.Failed();
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                    if (task.GetSyncType() == ITaskEvent.ESyncType.Sync)
                    {
                        break;
                    }

                    indexer++;
                }
                    
                for (var i = TaskEvents.Count - 1; i >= 0; i--)
                {
                    var task = TaskEvents[i];
                    if (task.GetStatus() == ITaskEvent.ETaskStatus.Failed || 
                        task.GetStatus() == ITaskEvent.ETaskStatus.Completed)
                    {
                        RemoveTask(task);
                    }
                }
                
                yield return WaitHalfSeconds;
            }
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的Unity任务系统代码示例: ```csharp using System.Collections.Generic; using UnityEngine; public class TaskManager : MonoBehaviour { private static TaskManager instance; public static TaskManager Instance { get { return instance; } } private List<Task> tasks = new List<Task>(); private void Awake() { if (instance != null && instance != this) { Destroy(this.gameObject); return; } instance = this; } public void AddTask(Task task) { tasks.Add(task); } public void RemoveTask(Task task) { tasks.Remove(task); } private void Update() { for (int i = 0; i < tasks.Count; i++) { Task task = tasks[i]; if (!task.IsFinished) { task.UpdateTask(); } else { tasks.RemoveAt(i); i--; } } } } public abstract class Task { protected bool isFinished; public bool IsFinished { get { return isFinished; } } public abstract void UpdateTask(); } public class ExampleTask : Task { private float timer; private float duration; public ExampleTask(float duration) { this.duration = duration; } public override void UpdateTask() { timer += Time.deltaTime; if (timer >= duration) { isFinished = true; } } } ``` 在这个示例中,我们有一个`TaskManager`类,它负责管理所有任务。每个任务都是一个派生自`Task`类的具体实现。您可以根据需要创建不同的任务类型。 在`Task`类中,我们定义了一个`isFinished`字段和一个`UpdateTask()`方法。任务的实现应该重写`UpdateTask()`方法,并在完成时将`isFinished`字段设置为`true`。 在`TaskManager`类中,我们存储了所有任务,并在每个帧上循环遍历它们。如果任务未完成,则调用其`UpdateTask()`方法。如果任务已完成,则将其从`tasks`列表中删除。 您可以使用以下代码将任务添加到任务管理器: ```csharp TaskManager.Instance.AddTask(new ExampleTask(5f)); ``` 这将添加一个名为`ExampleTask`的新任务,其持续时间为5秒。在这个示例中,我们使用了一个简单的计时器来模拟任务的完成。您可以根据需要替换此行为。 希望这个示例能帮助您开始编写自己的Unity任务系统代码!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值