Quantum
- 广泛使用于RTS,MOBA,格斗动作,体育运动类游戏。
- 价格:
Public Cloud(公共云) a. 免费20个ccu。
b. $95 提供12个月100个ccu预估支持40,000个用户。
c. $1,250 提供12个月100个ccu预估支持40,000个用户。
d. $ 2,500 提供12个月1000个ccu预估支持400,000个用户。
f. $ 5,000 提供12个月2000个ccu预估支持800,000个用户。- Premium Cloud(高性能云)
$1,000 提供1个月2000个ccu。 - Self-host(本地服务器) 需要是Gaming Circle,获取Free Development License
ECS
Quantum是采用ECS框架,ECS独立于UnityEngine被放在quantum_code项目中,通过dsl生成component,这些组件通过unity中EntityPrototype挂在在角色身上,系统(继承SystemMainThread)通过SystemSetup注册到Core.cs, Quantum引擎回回调这些System函数。
通过DSL生成数据类代码
«««< HEAD
- 注册账号 生成appid
- 下载测试案例 (https://dashboard.photonengine.com/zh-cn/download/quantum/quantum-100-2.1.4.zip)
- 解压文件quantum-100-2.1.4.zip,将quantum-100-2.1.4\tools\codeintegration_unity内容全部复制到quantum-100-2.1.4\quantum_code\quantum.code
- 在quantum_unity/Packages/manifest.json中添加本地配置包配置 “com.exitgames.photonquantumcode”: “file:../../quantum_code/quantum.code”
- 删除 quantum_unity/Assets/Photon/Quantum/Assemblies/quantum.code.dll
- quantum-100-2.1.4\quantum_code\quantum.code\quantum.code.csproj 添加下面代码
创建qtn文件
- 注册账号 生成appid
- 下载测试案例 (https://dashboard.photonengine.com/zh-cn/download/quantum/quantum-100-2.1.4.zip)
- 解压文件quantum-100-2.1.4.zip,将quantum-100-2.1.4\tools\codeintegration_unity内容全部复制到quantum-100-2.1.4\quantum_code\quantum.code
- 在quantum_unity/Packages/manifest.json中添加本地配置包配置 “com.exitgames.photonquantumcode”: “file:../../quantum_code/quantum.code”
- 删除 quantum_unity/Assets/Photon/Quantum/Assemblies/quantum.code.dll
- quantum-100-2.1.4\quantum_code\quantum.code\quantum.code.csproj 添加下面代码
- 创建qtn文件
32ab6d7121c9d6a9cc2a7cfa68f2dfe67d3b198d
1 2 3 4 5 component Action { FP Cooldown; FP Power; }«««< HEAD
- cmd运行 D:\quantum-100-2.1.4/tools/codegen/quantum.codegen.host.exe D:\quantum-100-2.1.4\quantum_code\quantum.code
打开quantum_code.sln 生成dll文件,开发阶段可以不用生成
组件 (Components)
- 自定义组件 通过dsl生成
1 2 3 4 5
component Action { FP Cooldown; FP Power; }
生成组件名:EntityComponentAction
- 系统组件 无状态物理引擎 PhysicsCollider、PhysicsBody、PhysicsCallbacks、PhysicsJoints (2D/3D)
- 系统组件 基于导航网格的路径查找和移动 PathFinderAgent、SteeringAgent、AvoidanceAgent、AvoidanceObstacle:。
游戏逻辑 Systems
- 继承SystemMainThread
- 继承SystemMainThreadFilter
,可以关注需要的内容 - System需要通过SystemSetup:CreateSystems需要将数据放入Core.cs
- Systems通过Update从Frame中获得需要的数据:f.Unsafe.TryGetPointer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public unsafe class MySystem : SystemMainThread
{
public override void Update(Frame f)
{
}
}
public unsafe class MovementSystem : SystemMainThreadFilter<MovementSystem.Filter>
{
public struct Filter
{
public EntityRef Entity;
public Transform2D* Transform;
public PlayerCharacter* PlayerCharacter;
public KCC* Kcc;
}
public override void Update(Frame frame, ref Filter filter)
{
//frame.Unsafe.GetPointer<PlayerCharacter>(entity);
}
}
Frame
1
2
3
4
frame是系统(继承SystemMainThread)通过Quantum内部回调Update得到。
继承关系:Frame:FrameBase:DeterministicFrame
使用Frame.User 扩展Frame数据
System从Frame中获得需要的数据:f.Unsafe.TryGetPointer
事件和回调 (Events & Callbacks)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//dsl生成myevnt类
event MyEvent {
int Foo;
}
//事件触发 必须是系统(MySystem)
public override void Update(Frame f) {
f.Events.MyEvent(2022);
}
//事件注册
QuantumEvent.Subscribe<EventMyEvent>(listener: this, handler: OnEventPlayerHit);
private void OnEventPlayerHit(EventMyEvent e){
Debug.Log($"MyEvent {e.Foo}");
}
定点数 Events & Callbacks
- 采用的是Q48.16(48位整数,16位小数)
- 使用FPAnimationCurve 创建动画曲线,或者AnimationCurve 烘培到FPAnimationCurve
QuantumLoadBalancingClient 使用(点击开始按钮创建QuantumLoadBalancingClient)
- var Client = new QuantumLoadBalancingClient(PhotonServerSettings.Instance.AppSettings.Protocol);
- Client.ConnectUsingSettings(appSettings, Username)
- Client.OpJoinRandomOrCreateRoom(joinRandomParams, _enterRoomParams)
- QuantumRunner.StartGame(clientId, param);
EntityViewUpdater (渲染部分)
- 注册消息 QuantumCallback.Subscribe
- 同步数据 SyncViews (是否创建player BindMapEntityIfNeeded->CreateView->CreateEntityViewInstance->GameObject.Instantiate)
EntityPrototype
这是一个实体原型,虽然继承了MonoBehaviour,但是没有使用任何API,直接用于挂在组件而用的,实际数据序列化到EntityPrototypeAsset。 需要加载EntityPrototypeAsset数据,实例化组件
- IResourceLoader.LoadResource(AssetResource resource)
- FinishLoading
- EntityPrototypeAsset:PrepareAsset()->behaviourBuffer
EntityView 渲染部分
1
2
Non Verified:可在预测帧中创建视图游戏对象,如子弹
Verified :只能在已验证帧中创建,如玩家角色
QuantumCallbacks 相当于MonoBehaviour,回调数据来说photon网络调用
- Quantum.Core Quantum 内部调用的一些接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public enum CallbackId { PollInput, GameStarted,//游戏开始时调用 GameResynced,//游戏快照重新同步时调用的回调 GameDestroyed,//游戏销毁时调用 UpdateView,//回调保证在每个渲染帧被调用。 SimulateFinished,//逻辑帧完成回调 EventCanceled, //当由于回滚,错过预测而在已验证帧中取消预测帧中引发的事件时调用的回调 EventConfirmed,//当经过验证的帧确认事件时调用回调 ChecksumError,//校验预测错误时调用回调 ChecksumErrorFrameDump,//由于校验预测错误而转储帧时调用的回调 InputConfirmed,//本地输入确认后回调 ChecksumComputed, PluginDisconnect, UserCallbackIdStart, }
QuantumCallbacks 函数
OnGameStart:
OnGameResync: OnGameDestroyed: OnUpdateView:
OnSimulateFinished:
OnUnitySceneLoadBegin:
OnUnitySceneLoadDone:
OnUnitySceneUnloadBegin:
OnUnitySceneUnloadDone:
OnChecksumError:注册数据Frame (quantum_code里面)
_ISignalOnPlayerDataSet = BuildSignalsArray(); _ISignalOnCollision2DSystems = BuildSignalsArray (); _ISignalOnCollisionExit2DSystems = BuildSignalsArray (); 发送数据
发生数据:game.SendPlayerData(lp, new Quantum.RuntimePlayer { PlayerName = PlayerName, SelectedCharacter = CharacterPrototype});接受数据
Core:OnSimulate() Core:UpdatePlayerData()-> ISignalOnPlayerDataSet:OnPlayerDataSet() (quantum_code里面) 派发到 PlayerConnectedSystem 里面- QuantumCallbackHandler_LegacyQuantumCallback
QuantumCallback:QuantumCallback:() //内部调用 IsDefaultHandlerEnabled() QuantumCallbackHandler_LegacyQuantumCallback.Initialize() QuantumCallback.SubscribeManual //手动订阅消息(CallbackChecksumError,CallbackGameDestroyed,CallbackGameStarted,CallbackGameResynced …)