Skip to content

Actor 系统 ​

预警、粒子大小或首刀表现异常时,先核对挂载、资源依赖、scope 和缩放组成,见表现诊断。AutoScale 还可能使用半径和体积;不应按“大模型”统一关闭,也不应将隐藏多次预热作为所有预警的必需步骤。

Actor 系统管理游戏中所有视觉表现元素——3D 模型、粒子特效、光束、音效、材质覆盖、高光、文字等。Actor 由客户端创建和渲染,通过 ActorScope 管理生命周期和可见性同步。

需要取得具体表现的 Node、模型、动画、粒子或声音组件时,阅读GameCore 与 GameGraph 桥接。客户端表现节点与 ActorScope 的 replicated 绑定节点各有用途;Unit 与 Entity 也能通过共享接口直接访问动画能力。

核心类型 ​

类型说明
GameDataActorActor 数编基类(抽象),定义挂接、缩放、旋转等通用配置
ActorActor 运行时基类(抽象),所有视觉元素的公共基类
ActorScope管理一组 Actor 的生命周期(抽象)
ActorScopePersist持久 Scope,与实体绑定,服务端创建并同步
ActorScopeTransient瞬态 Scope,客户端播放,服务端可请求可见客户端创建一次性表现
IActorScopeContextScope 上下文接口,提供目标、位置、缩放等参数
IActorScopeOwnerScope 所有者接口,管理 Scope 的创建和子 Actor

类型继承关系 ​

GameDataActor (abstract)
 ├── GameDataActorModel        → ActorModel       3D 模型
 ├── GameDataActorAdditionModel → ActorAdditionModel 附加模型
 ├── GameDataActorParticle     → ActorParticle     粒子特效
 ├── GameDataActorBeam         → ActorBeam         光束
 ├── GameDataActorGrid         → ActorGrid         网格覆盖
 ├── GameDataActorSegmented    → ActorSegmented    分段效果(抽象)
 ├── GameDataActorSound        → ActorSound        音效
 ├── GameDataActorText         → ActorText         世界文字
 ├── GameDataActorSite         → ActorSite         位置标记(不可见)
 └── GameDataActorHostModifier                     宿主修改器基类
      ├── GameDataActorHighlight → ActorHighlight  高光/选中效果
      ├── GameDataActorMaterial  → ActorMaterial   材质覆盖
      └── GameDataActorAction   → ActorAction      动作效果

ActorScope (abstract)
 ├── ActorScopePersist    持久 Scope(双端)
 └── ActorScopeTransient  瞬态 Scope(客户端播放,服务端可请求创建)

GameDataActor 通用配置 ​

所有 Actor 数编共享的基类属性:

属性类型默认值说明
IsTransientboolfalse是否为瞬态(播放完自动销毁)
SocketUTF8String?null挂接点名称
OffsetVector3?null位置偏移
RotationVector3?null旋转偏移
InheritRotationbooltrue继承父级旋转
InheritScaleboolfalse继承父级缩放
AutoScalebooltrue从 Scope 自动缩放
Scalefloat?null均匀缩放
ScaleVectorVector3?null非均匀缩放
AttachForwardOnceboolfalse仅使用父节点和挂点初始化一次位置与旋转,随后立即解除挂接并保持世界变换
MiniMapIconMiniMapIcon?null小地图图标配置
ParentRemovalProcedureParentRemovalProcedure—父级移除时的行为

创建 Actor(客户端):

csharp
#if CLIENT
Actor? actor = myActorLink.Data?.CreateActor(scope);
#endif

Actor 类型详解 ​

ActorModel — 3D 模型 ​

渲染 3D 模型,支持动画播放、骨骼链、挂接点。

数编配置(GameDataActorModel):

属性类型说明
ModelIGameLink<GameDataModel>?模型资源

运行时实现 IActorAnimationPlayable 接口(仅客户端),提供:

方法说明
PlayAnimation(Animation, AnimationPlayParam?)播放动画
PlayAnimationSequence(IGameLink<GameDataAnimationSequence>, float)播放动画序列
PlayAnimationBracket(IGameLink<GameDataAnimationBracket>)播放括号动画
StopAnimationOfLayer(AnimationLogicLayer)停止指定层的动画
SetBirthStandDeathAnimation(UTF8String, UTF8String, UTF8String)设置生命周期动画
SetAnimationMapping(UTF8String, UTF8String)设置动画别名映射
CreateBoneChain(IEnumerable<ModelBoneWeight>)创建骨骼链(分体旋转)
SetUpperBodyRootBone(UTF8String)设置上下半身动画分割
GetSocketPosition(UTF8String)获取挂接点世界坐标

ActorAdditionModel — 附加模型 ​

在已有宿主上自动显示额外模型,例如手持物、背饰、披风、盾牌、头饰或整套外观覆盖。它使用 GameDataActorAdditionModel 配置,并可放入单位、物品、Buff、技能或效果的 ActorArray。

数编配置:

属性类型默认值说明
ModelIGameLink<GameDataModel>?null要附加显示的模型资源
CullHostMeshboolfalse附加模型覆盖宿主主体时,可开启以减少宿主与附加模型重叠造成的穿插或重叠渲染

ActorAdditionModel 的对齐方式与普通 Actor 不同:它不通过 Socket、Offset、Rotation、Scale 等字段定位,资源应按宿主骨架制作。详细配方见 自动挂载模型表现。

ActorParticle — 粒子特效 ​

播放粒子特效,实现 IActorPlayable。

数编配置(GameDataActorParticle):

属性类型默认值说明
ParticleIGameLink<GameDataParticle>?null粒子资源
AutoPlaybooltrue自动播放
Fadeboolfalse结束时淡出
PlaySpeedfloat?null播放速率
CreationFilterLevelint1最低画质等级

运行时方法:

方法说明
Play()开始播放
Stop(bool fade)停止,可选淡出
SetPlaySpeed(float)设置播放速率

Fade=true 时,停止会先停止发射并让已经发射的粒子按自身寿命完成;需要立即清理时使用 Stop(false) 或 Destroy(forceNoFade: true)。表现节点默认值由项目模板决定。

ActorSound — 音效 ​

GameDataActorSound 没有 Actor 级 Fade 布尔字段。音效资源 GameDataSound.FadeTime 控制淡入淡出时长,普通音效模板通常使用 0.5 秒,音乐模板通常使用 2 秒。

ActorBeam — 光束 ​

从一点延伸到另一点的效果(激光、闪电等)。运行时 ActorBeam 实现 IActorPlayable 和 IActorDualEndPoints,数编配置 GameDataActorBeam 实现 IGameDataActorDualEndPoints。

ActorBeam 与 GameGraph ParticleSystem 中的 Beam 发射器共享底层光束粒子能力。它通过 Beam 引用 GameDataParticle 资源,并由框架管理两端单位/挂点跟随、播放和生命周期。绑定后,框架每帧读取挂点位置并更新粒子端点;任一绑定端点失效时隐藏光束,端点重新有效时恢复播放。

如果需要纯代码构造光束,可使用 ParticleSystem.CreateRuntime()、AddBeamEmitter(...) 和 ParticleEmitterBeamBuilder。Builder 负责资源配置,Points(...) 只保存坐标,不绑定 Node;挂载到节点后,应通过运行时 ParticleEmitter.SetSourcePoint/SetEndPoint 更新端点,由项目代码管理跟随与清理。ActorBeam 本身不通过 C# Builder 实现。选型和跟随示例见 GameGraph 粒子与音频系统。

数编配置(GameDataActorBeam):

属性类型默认值说明
BeamIGameLink<GameDataParticle>?null光束粒子资源
LaunchSocketUTF8String?null发射端挂接点
ImpactSocketUTF8String?null命中端挂接点
AutoPlaybooltrue自动播放
Fadeboolfalse结束时淡出
DurationTimeSpan1 秒持续时间

ActorGrid — 网格覆盖 ​

在地面显示网格状效果,每个格子可独立设置状态。

数编配置(GameDataActorGrid):

属性类型默认值说明
GridSizefloat128格子大小(世界单位)
StateModelsList<IGameLink<GameDataModel>?>[]各状态对应的模型(索引=状态值)

运行时属性(仅客户端):

属性类型说明
AxisGridAxisX/Y 轴向量,定义方向和格子大小
BoundsGridBounds覆盖范围,设置正值维度使网格可见
GridStatesGridState格子状态管理器,支持 [x, y] 索引器
StickToGroundbool是否贴合地形(默认 true)

> 服务端的 ActorGrid 是轻量壳——仅用于消息传输,不含实际渲染逻辑。

ActorSegmented — 分段效果 ​

从起点到终点的分段效果(闪电链、弹道轨迹、范围指示器),抽象基类。

运行时属性(仅客户端):

属性类型说明
Lengthfloat?覆盖长度,null 表示自动计算
ActualLengthfloat计算后的实际长度
LaunchActorActor?起点效果
ImpactActorActor?终点效果
CenterActorsIReadOnlyList<Actor>中间段的 Actor 列表

调用 UpdateForward() 计算朝向和长度。

ActorSound — 音效 ​

播放 3D/2D 音效,实现 IActorPlayable。

数编配置(GameDataActorSound):

属性类型默认值说明
SoundList<WeightedLink<IGameLink<GameDataSound>?>>—带权重的音效列表
AutoPlaybooltrue自动播放
LoopCountuint?null循环次数,null 为无限
Is2Dboolfalse2D 音频(无空间衰减)
RolloffFactorfloat43D 距离衰减系数
CutoffDistancefloat500完全静音的距离

运行时方法:Play(), Stop(bool), SetPlaySpeed(float), SetSoundVolume(float), IsMuted

ActorText — 世界文字 ​

在 3D 空间渲染文字。

数编配置(GameDataActorText):

属性类型默认值说明
FontFontfiramono.ttf字体
FontSizefloat50字号
Textstring"你好,星火"默认文字
ColorColorBlack颜色
WrapWidthfloat?null自动换行宽度
HorizontalAlignmentTextHorizontalAlignmentCenter水平对齐
VerticalAlignmentTextVerticalAlignmentCenter垂直对齐

运行时方法:SetText(string) / SetText(UTF8String)

ActorSite — 位置标记 ​

不可见的位置标记,用作其他 Actor 的挂接/锚定点。

ActorHighlight — 高光效果 ​

附加到宿主 Actor 上的颜色动画效果(选中、高亮),继承自 ActorHostModifier。

数编配置(GameDataActorHighlight):

属性类型说明
FromArithmeticMixer<HdrColor>?起始颜色(null 使用宿主当前色)
ToArithmeticMixer<HdrColor>目标颜色
DurationTimeSpan动画时长
AutoReversebool到达目标后反向
RepeatBehaviorRepeatBehavior重复次数
Weightdouble与宿主颜色的混合权重

ActorMaterial — 材质覆盖 ​

覆盖宿主 Actor 的材质,支持属性动画。继承自 ActorHostModifier,实现 IActorPlayable。

数编配置(GameDataActorMaterial):

属性类型说明
MaterialMaterial材质资源
PriorityMaterialPriority覆盖优先级
AutoPlaybool自动播放属性动画
PropertyAnimationsList<MaterialPropertyAnimation>?材质属性动画列表
IntroDuration / OutroDurationTimeSpan入场/退场动画时长

ActorAction — 动作效果 ​

附加到宿主 Actor 的动作效果,支持发射端和命中端挂接点。继承自 ActorHostModifier。

数编配置(GameDataActorAction):

属性类型说明
LaunchSocketUTF8String?宿主上的发射挂接点
ImpactSocketUTF8String?宿主上的命中挂接点

ActorScope 生命周期 ​

ActorScope 管理一组 Actor 的创建、销毁和可见性。服务端现在可以基于 ActorScope 发起客户端表现创建,但表现仍由客户端实际渲染;同步边界始终是“表现从属于某个作用域”,而不是全局广播一段任意表现操作。

能力总览 ​

能力服务端入口客户端行为生命周期典型用途
一次性表现IActorScope.PlayTransient(...)当前可见客户端创建一个 transient actor 并播放actor 自身 transient 配置,或调用时指定 Duration命中火花、爆炸、提示圈、短音效
持久作用域ActorScopePersist客户端创建一个可长期存在的 scope,并按作用域可见性创建/移除表现scope Kill() / Destroy() 或宿主生命周期单位模型、持续光环、任务标记
持久子表现 slotActorScopePersist.SetActorSlot(...)客户端收到 slot 声明后本地创建 actor,并附着到 scope 自身的 AttachSiteslot 被清除或 scope 销毁持续粒子、光环、可见性受控的服务端声明表现
高级 replicated Node 表现ActorScopePersist.EnsureNodeBinding(...) + binding.SetActorSlot(...)客户端收到绑定 node 和 slot 声明后本地创建 actor,并附着到指定 replicated nodeslot 被清除、binding 被解绑或 scope 销毁hitbox、raycast target、GameGraph 组件、Node SyncVar 元数据

ActorScopePersist(持久 Scope) ​

  • 与实体(Entity/Unit)或显式作用域上下文绑定,服务端创建并同步到客户端。
  • 通过作用域上下文和底层可见性机制控制哪些客户端能看到该 scope。
  • 拥有 Position(ScenePoint)和 Scene,可作为服务端可同步表现的归属边界。
  • 调用 Kill() / Destroy() 会销毁该作用域及关联表现。
  • 适合“服务端声明、客户端持续保持”的表现,例如单位模型、持续光环、可交互物标记、服务端创建的独立持久表现点。

ActorScopeTransient(瞬态 Scope) ​

  • 客户端负责实际创建和播放,火并忘(fire-and-forget)。
  • 服务端可通过已有 IActorScope.PlayTransient(...) 请求可见客户端播放一次性表现。
  • 构造时仍支持从 IActorScopeContext.Cache.ActorArray 创建 Actor;PlayTransient 额外允许服务端指定一个本次播放的 actor。
  • 自动创建位置锚点(StaticSite)和源锚点(SourceSite)。
  • 播放完毕后自动销毁。
  • 不做 late join replay。瞬时表现只面向当前可见客户端发送,后加入或当时不可见的客户端不会补播。

瞬态 vs 持久 ​

特性瞬态(Transient)持久(Persist / Slot)
创建语义服务端发起一次播放请求,客户端本地创建服务端声明一个长期存在的作用域或 slot,客户端按声明保持
生命周期自动销毁,不 replay持续存在,客户端 late join 或重新可见时可按当前状态创建
可见性只发给当时能看到作用域的客户端跟随 scope / node 当前可见性,重新可见会重建当前状态
典型用途一次性特效、短音效、打击反馈单位模型、持续光环、服务端创建的持久场景表现

服务端创建表现 ​

从服务端创建一次性或持久客户端表现的完整说明见 服务端创建表现。该文档是这项能力的主入口,包含:

  • PlayTransient(...) 一次性表现,明确不做 late join replay。
  • ActorScopePersist + scope.SetActorSlot(...) 普通持久表现,重新可见后按当前声明恢复。
  • ActorScopeNodeBinding 高级用法:需要真实 replicated Node 时再使用。
  • 固定场景点、已有单位、双端 GameData / ScopeData、slot version 和常见错误。

本页只保留 Actor 与 ActorScope 的基础概念。生成或评审“服务端创建表现”代码时,不要只看本页,应先看上面的专题文档。

IActorScopeOwner ​

实现此接口的对象(如 Unit、Ability)可以拥有和管理 ActorScope:

csharp
// 服务端:初始化 ActorScope
#if SERVER
var scope = (unit as IActorScopeOwner).InitializeActorScope();
#endif

// 客户端:创建默认子 Actor
#if CLIENT
(unit as IActorScopeOwner).CreateDefaultChildren();
#endif

使用示例 ​

在效果树中创建 Actor ​

Actor 通常通过数编配置在效果树中创建,绑定到实体的 Scope:

csharp
// 在 GameDataActorScope 中配置 ActorArray
// 当效果执行时,自动创建配置的 Actor

手动创建 Actor ​

csharp
#if CLIENT
// 从数编创建
var model = myActorModelLink.Data?.CreateActor(scope);

// 操作粒子
if (actor is ActorParticle particle)
{
    particle.Play();
    particle.SetPlaySpeed(2.0f);
    particle.Stop(fade: true);
}

// 设置网格状态
if (actor is ActorGrid grid)
{
    grid.Bounds = new GridBounds(0, 0, 10, 10);
    grid.GridStates[3, 5] = new GridState(1);
}

// 设置文字
if (actor is ActorText text)
{
    text.SetText("Hello World");
}

// 播放音效
if (actor is ActorSound sound)
{
    sound.Play();
    sound.SetSoundVolume(0.5f);
}
#endif

无 Model 仅 ActorArray 的单位 ​

GameDataUnit 不设 Model 属性、仅配置 ActorArray 的单位同样有效。 框架会为单位创建隐含的场景 Node,ActorArray 中的 Actor(如粒子特效)会自动附着在该 Node 上。 适用于经验宝石、掉落物、纯视觉标记等不需要 3D 模型的场景实体。

csharp
// 定义粒子特效
var gemParticle = new GameLink<GameDataParticle, GameDataParticle>("ExpGem"u8);
_ = new GameDataParticle(gemParticle) { Asset = "effect/eff_arpg/arpg_tongyong/diaoluo_1/particle.effect"u8 };

// 定义粒子 Actor
var gemActor = new GameLink<GameDataActor, GameDataActorParticle>("ExpGemActor"u8);
_ = new GameDataActorParticle(gemActor) { AutoPlay = true, Particle = gemParticle };

// 定义单位:无 Model,仅 ActorArray
_ = new GameDataUnit(gemUnit)
{
    Name = "经验宝石",
    Filter = [UnitFilter.Item],
    ActorArray = [gemActor],  // 粒子特效附着在单位隐含 Node 上
};

销毁 Actor ​

csharp
#if CLIENT
actor.Destroy();
#endif

相关文档 ​