Git Product home page Git Product logo

donnyep / cosmosframework Goto Github PK

View Code? Open in Web Editor NEW
372.0 10.0 52.0 305.19 MB

CosmosFramework is a medium-lightweight plug-in Unity development framework . Has a rich Unity method extensions and toolchain. async/await syntax support, multi-network channel support.Long term support for this project

License: MIT License

C# 100.00%
kcp puremvc assetbundle await-async unity unityframework tcp-client-server tcp quadtree astar-pathfinding

cosmosframework's Introduction

CosmosGitLogo

License: MIT Issues:Welcome

CosmosFramework

CosmosFramework是一款中轻量级的Unity开发框架。框架拥有丰富的Unity方法扩展以及工具链。async/await语法支持,多网络通道支持,完整的资源打包流水线。支持自动化部署。框架遵循unityPackage规范,建议通过UPM导入使用。

导航

环境

  • Unity版本:2018及以上,DOTNET API版本:4.x。

启动框架

CosmosConfig

  • 在游戏入口处添加CosmosConfig组件,添加后即可启动框架。

模块简介

  • Audio: 游戏音效模块。通过注册音效信息,播放时传入音效名即可自动加载音效资源播放。音效支持分组,支持同一音效多实体播放。

  • Config:游戏常用配置模块。用户可在游戏初始化时读取配置文件,并缓存于配置模块。运行时在其他所需位置读取对应配置的数据。

  • Controller:控制器模块。使用此模块进行注册后,无需生成实体对象(GameObject)也可进行轮询管理。此模块提供Update轮询。

  • DataNode:数据缓存模块。数据以树形结构存储于此模块中,可通过web地址格式或者逗号分隔符获取对应数据的对象。

  • DataTable:数据表模块。在此模块中,数据行以对象形式存储于数据表中。数据表可实时增删改查,并通过自定义的反序列化方式生成所需要的数据对象。

  • Download:下载模块。支持localhost本地文件下载与http文件下载。文件下载时以byte流异步增量写入本地。下载中支持动态添加、移除下载任务;

  • Entity:游戏实体模块。管理游戏运行时的实体对象。实体支持组分类,通过传入资源地址可以直接管理资源实体对象的生成、回收等操作,内置对象池生成。

  • Event:事件中心模块。使用标准事件模型,提供了监听、移除、派发等常用事件功能。提供事件观测方法,可实时检测事件状态。

  • FSM:有限状态机模块。完全抽象的有限状态机,可针对不同类型的拥有者做状态机实现。

  • Input:输入适配模块。通过虚拟按键模拟各个平台的输入,传入不同的输入适配器可适配不同平台的输入方式。

  • Main:模块中心。自定义模块与扩展模块都存于此。自定义模块按照内置模块相同格式写入后,可享有完全同等与内置模块的生命周期与权限。几乎与内置模块无异。此主模块的内置轮询池:FixedRefreshHandler、LateRefreshHandler、RefreshHandler、ElapseRefreshHandler可对需要统一进行轮询管理的对象进行统一轮询,减少由于过多的Update等mono回调导致的性能损耗。

  • Network:网络模块。提供了多种高速可靠的UDP协议,如RUDP、SUDP、KCP、TCP等,默认使用KCP协议。网络以通道(Channel)形式区分各个连接,支持多种网络类型同时连接。可实现(Client-Server)模式。支持async/await语法。

  • ObjectsPool:对象池模块。提供常用的实体对象生成回收等功能。底层使用数据结构Pool进行实现。

  • Procedure:流程节点模块。方便管理运行时执行的逻辑节点,如热游戏启动节点,资源校验节点,下载资源节点,进入游戏节点等。将每个操作封装为节点,则大大有利于项目维护。

  • Resource:资源加载模块。内置提供AssetDatabase、AssetBundle以及Resource三种加载模式。AssetDatabase与AssetBundle模式支持引用计数,资源包会根据引用计数自动管理包体的加载或卸载。Runtime加载器可自定义加载方案。支持自动化流水线,如Jenkins构建部署等。资源模块对应的编辑器位于Window>Cosmos>Module>Resource。开发阶段阶段使用AssetDatabase模式,构建app时使用AssetBundle模式。若需要使用Unity Resource作为加载方案,则切换为Resource模式。

  • Scene:场景加载模块。提供常用的异步、同步加载嵌入的场景功能。支持自定义实现加载方式。

  • UI:UI模块。抽象实现UI面板以及UI的加载方式。支持激活,失活,面板优先级,组别设置等功能,使用更轻便。框架提供了基于UGUI实现的面板类与资源加载帮助体。其他UI方案可自行扩展,目前稳定兼容FGUI。

  • WebRequest:UnityWebRequest模块,可用于加载持久化资源、网络资源下载等需求。支持获取AssetBundle、AudioClip、Texture2D、string。当资源获取到后,用户可通过WebRequestCallback对资源进行操作。

内置数据结构、工具

  • Utility:提供了反射、算法、断言、转换、Debug富文本、IO、加密、Json、MessagePack、Time、Text、Unity协程、Unity组件等常用工具函数。

  • Singleton:单例基类。提供了线程安全、非线程安全、MONO单例基类。

  • DataStructure:常用数据结构。链表、双向链表、双向字典、二叉树、四叉树、AStar、LRU、线程锁等数据结构。

  • Extensions:静态扩展库。提供Unity以及C#原生的相关扩展方法。

  • Awaitable :此工具提供了async/await语法在unity环境中的支持。可以像写c#原生异步一样,在Unity中写异步。支持Task异步,Task执行完成后会回到主线程,使用时按照正常格式写即可。

  • EventCore 完全抽象的事件数据结构。内含普通、标准与线程安全类型。

    //声明一个类,使其派生自EventCore,并做类型约束。
    public class MyEventCore :EventCore<string,string, MyEventCore>{}
    //实现后即可使用自定义的事件监听。
  • ReferencePool :全局引用池模块。

  • Editor :Editor中提供了在Hierarchy常用检索对象、组件的方法,EditorConfig提供了代码生成是自动创建代码标头的功能;

  • FutureTask:异步任务检测,支持多线程与协程异步进度检测。检测函数需要传入Func格式的函数,当条件返回值为true时,异步检测结束。支持async/await语法,可使用await语句等待任务完成。

  • Pool:池数据结构。包含线程安全与非线程安全类型。框架中的对象池、引用池以及其他模块的缓存池都使用了“Pool”进行实现。

内置架构 PureMVC

  • 基于原始PureMVC改进的更适于理解的架构。 框架提供了基于特性更加简洁的注册方式:

    • 1.MVCCommandAttribute,对应Command,即C层;
    • 2.MVCMediatorAttribute,对应Mediator,即V层;
    • 3.MVCProxyAttribute,对应Proxy,即M层;
  • MVC自动注册只需在入口调用MVC.RegisterAttributedMVC()方法即可。

  • 派生的代理类需要覆写构造函数,并传入NAME参数。

  • 需要注意,MVC.RegisterAttributedMVC()方法需要传入对应的程序集。支持多程序集反射。

注意事项

  • 内置案例地址:Assets\Examples\ 。

UPM

  • CosmosFramework遵循unityPackage规范,可以完全将整个库放置于Packages目录下。

  • 从本地导入:选择Assets/CosmosFramework文件夹,拷贝到工程的Packages目录下。

  • 从git导入:填入url: https://github.com/DonnYep/CosmosFramework.git#v1.3_upm

其他

Library link

回到最上层

cosmosframework's People

Contributors

codingwatching avatar donnyep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cosmosframework's Issues

Example

Hi @DonnYep
Thank you so much for awesome Framework, The examples list are very easy to run
When I try to run 08_ObjectPool, I see the null error here, Please check

image

NullReferenceException: Object reference not set to an instance of an object
Cosmos.Test.MyObjectSpawner+<Start>d__13.MoveNext () (at Assets/Examples/ExampleScripts/08_ObjectPool/MyObjectSpawner.cs:36)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <eae584ce26bc40229c1b1aa476bfa589>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:153)
UnityEngine.UnitySynchronizationContext:ExecuteTasks() (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:107)

Thank you so much!

network help

能弄个有tcp和kcp同时存在的例子吗?

[Question] - Should we add PauseAllTask and UnPauseAll Task into TickTimer

Hi @DonnYep
I am using TickTimer to spawn tasks and when the game pause, I need to pause all task too
Should we add 2 functions for that purpose into TickTimer?

        public void PauseAllTask()
        {
            foreach (var taskId in taskDict.Keys)
            {
                PauseTask(taskId);
            }
        }

        public void UnPauseAllTask()
        {
            foreach (var taskId in taskDict.Keys)
            {
                UnPauseTask(taskId);
            }
        }

Thank you!

框架不错,希望能持续更新

感谢 开源这个框架。

最担心开发者因为其他事情导致这种框架类项目中途停滞,半途而废,希望这个项目不要出现这种情况。

[Bug] - TickTimer PauseTask and UnPauseTask

Hi @DonnYep
I am trying using TickTimer feature. When testing Pause and Resume (UnPause), I see the problem that PauseTask removes the task from taskDict but in UnPauseTask, the taskDict is not adding the task again, so the task can not be resumed.
Please check

  public bool PauseTask(int taskId)
        {
            if (!taskDict.TryRemove(taskId, out TickTask task))
                return false;
            task.IsPause = true;
                var remainTime= task.DestTime - GetUTCMilliseconds();
            task.PauseRemainTime = remainTime > 0 ? remainTime : 0;
            return true;
        }
        public bool UnPauseTask(int taskId)
        {
            if (!taskDict.TryRemove(taskId, out TickTask task))
                return false;
            task.IsPause = false;
            task.DestTime = task.PauseRemainTime + GetUTCMilliseconds();
            return true;
        }

Client.cs中ReceiveThreadFunction函数中少了Finally

!!!下面语句应该放finally中

        // add 'Disconnected' event to receive pipe so that the caller
        // knows that the Connect failed. otherwise they will never know
        state.receivePipe.Enqueue(0, EventType.Disconnected, default);
        
        // sendthread might be waiting on ManualResetEvent,
        // so let's make sure to end it if the connection
        // closed.
        // otherwise the send thread would only end if it's
        // actually sending data while the connection is
        // closed.
        sendThread?.Interrupt();

        // Connect might have failed. thread might have been closed.
        // let's reset connecting state no matter what.
        state.Connecting = false;

        // if we got here then we are done. ReceiveLoop cleans up already,
        // but we may never get there if connect fails. so let's clean up
        // here too.
        state.client?.Close();
    }

请教一下WaitForMainThread的用法

我写了如下的测试代码,发现"Down"的Log顺序在"AwaitableTest >>> After IEnumerator EnumWait"之后,
image

 IEnumerator EnumWait()
    {
        yield return new WaitForSeconds(3);
        Task task = new Task((() =>
        {
            Thread.Sleep(2000);
            Debug.Log("Down");
        }));
        task.Start();
        yield return task;
        Debug.Log("AwaitableTest >>> After IEnumerator EnumWait");
    }

但是当我将yield return task修改成yield return task.AsCoroutine();结果会变成
image

所以想请教一下WaitForMainThread的用法

How to handle Entity Life Cycle

Hi @DonnYep
I am reading the Entity Example and applying it to my game.
I want to reset some logic data (from table config) each time Entity is shown again, so I need some exclusive Functions like this:

  • OnInit (Can replace by Awake)
  • OnShow
  • OnHide

After reading the code, I think we can implement that functions in EntiyHelper and EntityGroupHelper classes but should we provide it in Entity Class?
Thank you so much!

[UI Manager] - Should we add some default Layers and some Tweening function

Hi @DonnYep
It is only my suggestion, currently, the UI in our Framework is simple and easy to use enough.

  • Add some layer node likes: Top Layer, Middle Layer, Bottom Layer, or some parent as a placeholder for the panel group
  • Add basic Tweenning function for UI components before and after Panel Open and Close (Need some async function to await the tweens to completed)
    Thank you so much! Have a nice day!

TickTimer Error in some case?

@DonnYep
I am trying the ObjectPool example and when I change the timer config to:

            //注意,这里是毫秒单位;
            tickTimer.AddTask(100, OnSpawnTime, null, int.MaxValue);
            //此写法的实际意义为,生成的单位存活时间为15秒;
            //await new WaitForSeconds(15f);
            tickTimer.AddTask(10, 1500, OnDespawnTime, null, int.MaxValue);

Then it errors :

NullReferenceException: Object reference not set to an instance of an object
Cosmos.TickTimer.TickRefresh () (at Assets/CosmosFramework/Runtime/Base/Timer/TickTimer.cs:192)
Cosmos.Test.MyObjectSpawner.Update () (at Assets/Examples/ExampleScripts/08_ObjectPool/MyObjectSpawner.cs:52)

Maybe we need to check some conditions to avoid this situation .. ?

Thank you so much!

20_AOI SquareGrid.cs数组越界

    public Square[] GetNearbySquares(float posX, float posY, int level = 0)
    {
        if (!IsOverlapping(posX, posY))
            return new Square[0];

!!!重复 if (!IsOverlapping(posX, posY))
!!!重复 return new Square[0];

!!! var row = (int)((posX - OffsetX) / CellSideLength);
!!! var col = (int)((posY - OffsetY) / CellSideLength);

        level = level >= 0 ? level : 0;
        if (level == 0)
            return new Square[] { square2d[col, row] };
        if (level == CellSection)
            return square1d;
        int sideCellCount = level * 2 + 1;
        int squareCount = sideCellCount * sideCellCount;
        Square[] neabySquares = new Square[squareCount + 1];
        int idx = 0;
        for (int x = -level; x <= level; x++)
        {
            for (int y = -level; y <= level; y++)
            {
                int idxX = col + x;
                int idxY = row + y;
                if (idxX < CellSection && idxX >= 0 && idxY < CellSection && idxY >= 0)
                {
                    neabySquares[idx] = square2d[idxX, idxY];
                    idx++;
                }
            }
        }
        var dstSquares = new Square[idx];

!!!越界 dstSquares[0] = square2d[col , row];

        Array.Copy(neabySquares, 0, dstSquares, 0, idx);
        return dstSquares;
    }

框架Resource模块是否能够同步加载资源?

目前看来所有加载资源的方法都是异步的,不知道有没同步的方式
由于本人不熟习异步思路开发,感觉困难重重
主要在与异步的污染性,一条代码是异步导致所有上层都要改为异步.
这样来,代码凡是和加载资源有关的(创建预制体这种很频繁的操作),都需要改为异步
在资源加载逻辑上下游也要变为异步

建议:资源加载失败的时候打印一个警告

想起之前容易出错的一点就是场景管理器切换场景的时候,调用了方法但是没任何反应,场景也没切换成功
后来才发现是SCENE的资源路径错误了,但是系统没提示,排查起来费劲

感谢作者分享

代码过了一遍 ,学到了很多知识,感谢作者DonnYep大大

DefaultDownloadRequester.cs EnumGetFileSize函数if逻辑写反了

    IEnumerator EnumGetFileSize(string uri, Action<long> callback)
    {
        using (UnityWebRequest request = UnityWebRequest.Head(uri))
        {
            yield return request.SendWebRequest();
            string size = request.GetResponseHeader("Content-Length");

            if (request.result != UnityWebRequest.Result.ConnectionError && request.result != UnityWebRequest.Result.ProtocolError)
                callback?.Invoke(-1);
            else
                callback?.Invoke(Convert.ToInt64(size));
        }
    }

[Question] - Can we receive more information from TickTimer Task

Hi @DonnYep
I am using CosmosFramework to implement this game requirement:

  • The enemy will spawn in some future time
    So I use addTask and set the delayTime to handle this
    But in the future, I need to know what enemy name (or enemy id) to spawn, for now, only task id is return.
    I am thinking about adding userData to Task construction, so when we call TaskCallback, we pass it like this
task.TaskCallback.Invoke(task.TaskId,task.UserData);

Is there another way to do it? Thank you so much, I am learning CosmosFramework every day

We are hiring

hi DonnYep,

I've read ur resume from BOSS (直聘), wondering if u still interested to have a new job in Ningbo Zhoushan Port (base Ningbo). I would be delighted if u would like to add my wx: MTM3MzIxNzU3MDA=, which I encoded with base64.

Sry to leave irrelevant issue as a message here since BOSS stop us from contact u, feel free to delete this message.

Best regards,
Li

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.