Skip to content
jiepengtan edited this page Nov 20, 2019 · 7 revisions
  • 需要在文件 __DllSourceFiles/Tools.UnsafeECS.ECDefine/Src/Unsafe/System.cs 中进行定义,
  • 同时需要继承自 ISystem 相应的接口的说明可以在 __DllSourceFiles/Tools.UnsafeECS.ECDefine/Src/BuildIn/BuildIn_Interfaces.cs 中找到
  • 生成的代码的主体可以在 __DllSourceFiles/Game.Model/Src/__UnsafeECS/Generated/CodeGen_System.cs 看到
  • 抱歉,为了可以在 游戏逻辑代码 有编译错误的情况下依旧能够生成代码,需要将相应的system 在 ECDefine.dll 中进行声明
  • 比如声明了相应的System
  1. Overview
  • System Define

    • IJobSystem
    • IPureSystem
  • System Implement

    • GameJobSystem
    • GameExecuteSystem
  • 其中以Job开头的定义,在UNING_UNITY_BURST_JOB 定义了的情况下,会使用Unity 的Burst 进行编译,且会交由Unity 的JobSystem 进行调度,否则会在主线程中调度,所以这类System,不能修改全局的状态,只能访问相关的属性

  • 而 IPureSystem 一定会被主线程调用,适合处理涉及全局状态的改变的任务

 public abstract unsafe class BaseExecuteSystem : BaseSystem, IExecuteSystem {
        public void Execute(IContext context){
            if (BeforeSchedule()) {  DoSchedule(context);  }
            AfterSchedule(isSucc);
        }
        protected virtual bool BeforeSchedule(){ return true;}
        protected virtual void DoSchedule(IContext context){  context.Schedule(this);  }
        protected virtual void AfterSchedule(bool isSucc){ }
    }
 public partial class GameExecuteSystem :BaseExecuteSystem{   }
  • 你可以Override BeforeSchedule 在正式调度前去设置一下状态,方便在Execute 中访问
  • 你可以Override AfterSchedule 在调度完成后去清理一下状态
  1. 更多的描述
    //Input
    public class InputSystem : IPureSystem {
        public PlayerData PlayerData;
        public MoveData MoveData;
    }
  • 相应的在Game.Model.dll 中你需要定义相应的System
    public unsafe partial class InputSystem : GameExecuteSystem {
        public void Execute(
            ref PlayerData playerData,
            ref MoveData moveData
            ){
            //... other codes
        }
        //... other codes
    }
  • 1.如果该System 继承自 ISystemWithIdx,则相应的System 的定义需要添加 int Index 参数,该参数意思是在本次调度中第多少次调用该函数
  • eg:
    //Input
    public class InputSystem : IPureSystem, ISystemWithIdx {
        public PlayerData PlayerData;
        public MoveData MoveData;
    }
    public unsafe partial class InputSystem : GameExecuteSystem {
        public void Execute(
            int index,//代码在这里
            ref PlayerData playerData,
            ref MoveData moveData
            ){
            //... other codes
        }
        //... other codes
    }
  • 2.如果该System 继承自 ISystemWithEntity 的定义需要添加 Entity ptr*参数,该参数代表这次调用的 Entity 对象的指针
    //Input
    public class InputSystem : IPureSystem, ISystemWithEntity {
        public PlayerData PlayerData;
        public MoveData MoveData;
    }
    public unsafe partial class InputSystem : GameExecuteSystem {
        public void Execute(
            Entity* ptr,//代码在这里
            ref PlayerData playerData,
            ref MoveData moveData
            ){
            //... other codes
        }
        //... other codes
    }
  • 3.如果该System 继承自 IJobSystem

    • 如果定义了宏 UNING_UNITY_BURST_JOB 该系统将会使用 Unity's Burst compiler 进行编辑并被 Unity's JobSystem 调度(多线程)
    • 如果没有定义 UNING_UNITY_BURST_JOB ,则会在主线程中调度,
    • 所以为了可以使用Unity Burst,请保证在 该System中是线程安全的,比如不能修改全局变量,或着调用会修改全局变量的函数eg:_DestroyEntity
    • 如果不能保证线程安全,请使用 IPureSystem
  • eg: 在ECDefine.dll 中进行声明

    public class SinkSystem : IJobSystem {
        public Transform3D Transform;
        public BoidState BoidState;
    }
  • 需要以内部Struct的形式定义相应的JobDefine
  • 注意 不要添加 [Unity.Burst.BurstCompile] ,也不要 继承自 Unity.Jobs.IJob,方便后续框架使用条件宏开关相应的调度,以及运行在服务器中
  • 相应的JobDefine 中的成员的初始化,可以在 BeforeSchedule 进行赋值(在主线程中调用)
    public unsafe partial class SinkSystem : GameJobSystem {
        public unsafe partial struct JobDefine {
            [ReadOnly] public LVector3 SinkOffset;
            [ReadOnly] public LFloat DeltaTime;

            public void Execute(ref Transform3D transform3D, ref BoidState boidState){
                if (!boidState.IsDied) return;
                boidState.SinkTimer -= DeltaTime;
                transform3D.Position += SinkOffset;
            }
        }
        // 相应的需要在BeforeSchedule 中给相应的 JobDefine
        protected override bool BeforeSchedule(){
            //assign jobData info
            JobData.DeltaTime = _globalStateService.DeltaTime;
            JobData.SinkOffset = new LVector3(0,_gameConfigService.BoidSettting.SinkSpd * JobData.DeltaTime,0) ;
            return true;
        }
    }
  • 下面是相应的System Interface的定义
    /// should declare a Method like:
    /// public void Execute(.....)
    public interface ISystem { }
    /// should declare a Method like:
    /// public void Execute(int index, .....)
    public interface ISystemWithIdx { }
    /// should declare a Method like:
    /// public void Execute(Entity* ptr, .....)
    public interface ISystemWithEntity { }

    /// this system would always be scheduled in main thread 
    /// should declare a Method like:
    /// public void Execute(.....)
    public interface IPureSystem : ISystem { }

    /// this system would always be scheduled in main thread 
    /// should declare a Method like:
    /// public void Execute(Entity* ptr, .....)
    public interface IPureSystemWithEntity : IPureSystem, ISystemWithEntity { }
    
    /// If macro UNING_UNITY_BURST_JOB was defined
    /// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
    /// should declare a Method like:
    ///  public void Execute(.....)
    public interface IJobSystem : ISystem { }

    /// If macro UNING_UNITY_BURST_JOB was defined
    /// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
    /// should declare a Method like:
    /// public void Execute(Entity* ptr, .....)
    public interface IJobSystemWithEntity : IJobSystem, ISystemWithEntity { }

    /// If macro UNING_UNITY_BURST_JOB was defined
    /// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
    /// should declare a Method like:
    /// public void Execute(int index, .....)
    public interface IJobForEachSystem : IJobSystem { }
    /// If macro UNING_UNITY_BURST_JOB was defined
    /// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
    /// should declare a Method like:
    /// public void Execute(Entity* ptr,int index, .....)
    public interface IJobForEachSystemWithEntity : IJobForEachSystem, ISystemWithEntity { }

    /// If macro UNING_UNITY_BURST_JOB was defined
    /// this system will be complied by Unity's Burst compiler and scheduled by Unity's JobSystem,Otherwise it will be scheduled call in MainThread
    /// should declare as if it was inherited from : Unity.Collections.IJobNativeMultiHashMapMergedSharedKeyIndices
    public interface IJobHashMapSystem : ISystem { }
Clone this wiki locally