帧同步与状态同步
ECS架构ECS架构看起来就是这样子的。先有个World,它是系统(译注,这里的系统指的是ECS中的S,不是一般意义上的系统,为了方便阅读,下文统称System)和实体(Entity)的集合。而实体就是一个ID,这个ID对应了组件(Component)的集合。组件用来存储游戏状态并且没有任何的行为(Behavior)。System有行为但是没有状态。
数据和逻辑分离, Component中只有数据, System中只有逻辑, 首先有一个World, 管理着所有的Entity是Component的容器. 还有一个EntityAdmin来管理所有的Entity
游戏中不同的角色,看待同一个Entity下同一个Component时的视角是不一样的,角色希望这个Component能做什么,那么这个Component就真的可以做什么, Component自己能做什么不是它自己决定的, 而是由其观察者决定的. 但是这些观察者应当只是从Component中读状态, 而不会修改Component中的状态, Component中的状态需要有专门对应的System进行修改. 结果看来,根据主体视角区分所有 ...
ET中的异步
本篇博客不止讨论ETTask如何实现, 更想探讨C#底层是如何支持异步实现的. 如果读者像笔者一样, 通过Unity接触到的C#语言, 可能对协程和异步概念的理解上有偏差, 因为我们在Unity中使用的协程并不是操作系统层次下讨论的与线程、进程、协程中的协程概念, Unity的协程是Unity基于IEnumerator和Unity事件更新框架实现的伪协程、伪异步, Unity的协程限制非常多, 如果读者对Unity的协程、IEnumerator和yield return语法糖有疑惑, 欢迎参考IEnumerator与IEnumerable辨析和关于协程这两篇博客, 希望能帮助你理解.
本篇博客首先会讨论C#中异步的实现思路, 然后会讨论ETTask的实现思路, UniTask和YooAsset中的异步也在本系列的讨论之中.对Task的概述
另外, 如果读者对C#中的异步不是很了解, 推荐先看一下下面五篇翻译的文章:Dissecting the async methods in C#Extending the async methods in C#The performance char ...
UniTask
(摘抄自CLR Via C#)异步函数存在以下限制:
不能将应用程序的Main方法转变成异步函数。另外构造器、属性访问器方法和事件访问器方法不能转变成异步函数
异步函数不能使用任何out或者ref参数
不能在catch,finally或unsafe块中使用await操作符(注意在try中可以使用await,笔者记得UniTask的文档中说过是可以在try catch中使用UniTask并被捕获的,是因为UniTask实现了自己的AsyncMethodBuilderAttribute吗? 记得看一下)。
不能在await操作符之前获得一个支持线程所有权或递归的锁,并在await操作符之后释放它。这是因为await之前的代码由一个线程执行,之后的代码则可能由另一个线程执行。(使用了await就一定会涉及到多线程吗?那UniTask是怎么保证它使用await的时候是在同一个线程内?)在C#的lock语句中使用await,编译器会报错。如果显式调用Monitor的Enter和Exit方法,那么代码虽然可以编译,但Monitor.Exit会在运行时抛出一个SynchronizationLock ...
ET框架Demo启动流程梳理
ET客户端启动流程梳理启动时, 客户端只有一个Fiber
我们就从Entry.cs脚本中StartAsync方法的最后一行FiberManager.Create方法开始看吧,这个方法内部有如下代码:123456789101112fiber.ThreadSynchronizationContext.Post(async () =>{ try { await EventSystem.Instance.Invoke<FiberInit, ETTask>((long)sceneType, new FiberInit() {Fiber = fiber}); tcs.SetResult(true); } catch (Exception e) { Log.Error($"init fiber fail: {sceneType} {e}"); }});这段代码会通过E ...
YooAsset
资源信息热更新流程
游戏启动
获取当前资源的Manifest信息
获取远端最新的Manifest的信息
比较当前和远端Manifest的信息,如果可以更新,则需要更新到最新的Manifest
创建ResourcePackage,根据最新的Manifest创建运行时的AssetSystem
分帧加载是什么意思?
Persistent下的BuildinRoot-> streamingAssets/YooAssetSettingsData.Setting.DefaultYooFolderNameBuildinPackageRootSandboxRoot->UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderNameSandboxPackageRoot
ManifestFileName PackageManifestDefaultYooFolderName yoo
启动流程启动游戏获得游戏的版本号初始化YooAsset有一个内置路径和一个沙盒路径内置路径是 ...
Wesnoth小地图
Wesnoth小地图的设计基于这篇博客https://www.redblobgames.com/grids/hexagons/#coordinates-cube
当我谈跑步时,我谈些什么
一个到了我这样年龄的人,还要写下这种事情,颇有些愚蠢可笑.不过为了明确事实,我得言之在线:说起来,我是那种喜爱读书的性情,表达得准确一点,是那种不太以独处为苦的性情.每天有一两个小时谁都不交谈,独自一人默默地跑步也罢,四五个小时伏案独坐,默默地写文章也罢,我都不觉得难熬,也不感到无聊.这种倾向从年轻时起便一直存在于我身上.比起同什么人一起做什么事,我更喜欢一个人默不作声地读书,或是全神贯注地听音乐.只需要一个人做的事情,我可以想出许多许多来.
虽然如此,自从年纪轻轻便结了婚(我结婚时二十二岁), 我渐渐习惯了和别人共同生活. 大学毕业后经营一家饮食店, 认识到了与他人相处的重要性. 人无法独自生存下去, 这本是理所当然, 我却是脚踏实地学到的. 尽管有点走样, 我也渐渐掌握了类似社会性的东西. 回想起来, 从二十岁到三十岁的十年当中, 我的世界观发生了不小的变化, 在做人方面也有了一些长进, 从四处碰壁之中学会了生存的诀窍. 倘若没有这算得上艰难的十年的生活体验, 恐怕我就不会写什么小说了, 即使想写也写不出来. 但话说回来, 人的本性不会极端地发生变化. 希望一人独处的念头始终不变地 ...
人生十年,不可辜负的20岁到30岁
人生十年 不可辜负的20岁到30岁身份资本身份资本是我们个人资本的积累。 他体现着我们是谁,以及我峨嵋你的人生是如何度过的。它包括我们对自己的投资,以及因我们擅长或长时间从事而逐渐演变为自己身份一部分的事情。若想真正寻得“我是谁”这个问题的答案,仅仅像海伦一样等待自己“灵光乍现”是不行的。身份资本才能让我们一点一点地,建立真实的自己。
一些身份资本,譬如学位证书、工作经历、考试成绩或社团活动,可以写在简历里;但另一些身份资本,则更加私人化,包括我们是如何向外界展现自己的,我们是如何解决问题的,我们从哪里来,以及我们的爱好或其他人生经理。这些加总在一起,才构成了我们独一无二的身份资本。它就像是成人世界里的虚拟货币。我们可以用它来购买自己想要的机会、工作和其他东西。
20多岁的年轻人,譬如海伦,或许会以为自己现在正在经理身份认同危机是理所当然的,而积累身份资本是以后的事。但事实上,经历身份认同危机和积累身份资本,可以而且应该同时进行,就像埃里克森做的那样。研究人员在研究人们如何解决身份认同危机时发现,那些只是积累身份资本,而没有经历身份认同危机的人(只工作而没有自我探索的人),他们的人生会 ...
WindowsPowerShell优化
解决运行Hexo报错hexo : 无法加载文件hexo.ps1,因为在此系统上禁止运行脚本打造好用的PowerShell媲美oh-my-zsh
Windows PowerShell中git查看文件修改状态时文件名不显示中文的问题,这篇博客中已经记录解决方案了