6.7 KiB
6.7 KiB
Architecture Understanding
System Overview
The Skill GFX system manages visual effects when skills are cast in Perfect World. It handles projectile flight, hit effects, and various movement patterns.
High-Level Flow
Player Casts Skill
↓
CECAttacksMan.AddSkillAttack()
↓
CECAttackEvent.Tick() - Timing system
↓
CECAttackEvent.DoFire() - Triggers when skill fires
↓
A3DSkillGfxComposerMan.Play() - Finds composer by skill ID
↓
A3DSkillGfxComposer.Play() - Iterates targets, calls AddOneTarget
↓
A3DSkillGfxMan.AddSkillGfxEvent() - Creates GFX event
↓
A3DSkillGfxEvent.Tick() - State machine (Wait → Flying → Hit → Finished)
↓
CGfxMoveBase.TickMove() - Updates projectile position
↓
Unity VFX System - Renders effects
Core Components
1. Attack Event System
- CECAttacksMan: Manages all attack events
- CECAttackEvent: Individual attack event, handles timing
- Purpose: Determines WHEN to trigger GFX (based on skill timing)
2. GFX Composer System
- A3DSkillGfxComposerMan: Manages composers, loads from SkillStub
- A3DSkillGfxComposer: Contains GFX paths and parameters for a skill
- Purpose: Maps skill ID → GFX configuration
3. GFX Event System
- A3DSkillGfxMan: Base manager (abstract)
- A3DSkillGfxEvent: Base event class (abstract)
- CECSkillGfxMan: Unity-specific manager (inherits A3DSkillGfxMan)
- CECSkillGfxEvent: Unity-specific event (inherits A3DSkillGfxEvent)
- Purpose: Manages active GFX instances and state machine
4. Movement System
- CGfxMoveBase: Abstract base class for movement patterns
- CGfxLinearMove: Straight-line projectile
- CGfxOnTargetMove: Instant hit (no flight)
- CGfxParabolicMove: Arc trajectory
- CGfxMissileMove: Homing missile
- Purpose: Calculates projectile position over time
Class Hierarchy
Movement Classes
CGfxMoveBase (abstract)
├── CGfxLinearMove
├── CGfxOnTargetMove
├── CGfxParabolicMove
├── CGfxMissileMove
├── CGfxMeteoricMove
├── CGfxHelixMove
├── CGfxCurvedMove
├── CGfxAccMove
├── CGfxLinkMove
└── CGfxRandMove
Event Classes
A3DSkillGfxMan (abstract)
└── CECSkillGfxMan (Unity implementation)
A3DSkillGfxEvent (abstract)
└── CECSkillGfxEvent (Unity implementation)
Composer Classes
A3DSkillGfxComposerMan
└── A3DSkillGfxComposer
State Machine
A3DSkillGfxEvent States
-
enumWait: Waiting for delay time
- Increments
m_dwCurSpan - Transitions to
enumFlyingwhen delay expires
- Increments
-
enumFlying: Projectile in flight
- Calls
m_pMoveMethod.TickMove()each frame - Updates GFX position
- Transitions to
enumHitwhenTickMove()returnstrueOR timeout
- Calls
-
enumHit: Hit effect playing
- Plays hit GFX at target position
- Transitions to
enumFinishedwhen hit GFX completes
-
enumFinished: Event complete
- Event can be recycled/pooled
Data Flow
Skill Configuration
SkillStub (C# data structure)
↓
A3DSkillGfxComposer.Load(SkillStub)
↓
Populates:
- Fly GFX path
- Hit GFX path
- Movement mode
- Fly time
- Scales
- Parameters
Event Creation
A3DSkillGfxComposer.Play()
↓
For each target:
A3DSkillGfxMan.AddSkillGfxEvent(
composer,
hostID,
targetID,
flyGfxPath,
hitGfxPath,
flyTimeSpan,
moveMode,
...
)
↓
Creates A3DSkillGfxEvent:
- Sets composer
- Creates movement method (CGfxMoveBase.CreateMoveMethod)
- Sets parameters
- Initializes state to enumWait
Runtime Update
A3DSkillGfxMan.Tick() (called each frame)
↓
For each active event:
A3DSkillGfxEvent.Tick(deltaTime)
↓
State machine:
- enumWait: Check delay
- enumFlying:
- m_pMoveMethod.TickMove()
- Update GFX position
- Check timeout
- enumHit: Check hit GFX completion
- enumFinished: Mark for cleanup
Key Relationships
A3DSkillGfxEvent → CGfxMoveBase
- Relationship: Composition
- Field:
m_pMoveMethod : CGfxMoveBase - Usage: Delegates movement calculation to movement method
- Creation:
CGfxMoveBase.CreateMoveMethod(mode)
A3DSkillGfxEvent → A3DSkillGfxComposer
- Relationship: Reference
- Field:
m_pComposer : A3DSkillGfxComposer - Usage: Accesses GFX paths and parameters
- Set:
SetComposer(composer)
A3DSkillGfxMan → A3DSkillGfxEvent
- Relationship: Container/Manager
- Storage: List/array of active events
- Management: Creates, updates, destroys events
- Pooling: Reuses finished events
CECSkillGfxEvent → Unity VFX
- Relationship: Unity integration
- Fields:
m_flyGfxInstance : GameObject,m_hitGfxInstance : GameObject - Usage: Instantiates Unity particle systems/prefabs
- Loading: Uses Addressables for async loading
Memory Management
C++ Pattern
- Manual
new/delete - Object pooling for events
- GFX caching system
C# Pattern
- Automatic garbage collection
- Object pooling still recommended for performance
- Unity Addressables for asset loading
Threading Model
- C++: Single-threaded game loop
- C#: Unity main thread (MonoBehaviour.Update)
- Async: Addressables loading can be async, but GFX updates on main thread
Performance Considerations
- Object Pooling: Reuse
A3DSkillGfxEventinstances - GFX Caching: Cache loaded GFX prefabs
- Batch Updates: Update all events in single loop
- Early Exit: Skip finished events quickly
- LOD System: Use
m_bGfxUseLodfor distance-based quality
Integration Points
With Attack System
- Trigger:
CECAttackEvent.DoFire()callsA3DSkillGfxComposerMan.Play() - Timing: GFX starts when skill "fires" (not when cast begins)
With Character System
- Position:
GetTargetCenter()gets character position - Tracking:
m_bTraceTargetenables position updates during flight - Hooks: Future feature for bone attachment
With Unity VFX
- Loading: Addressables async loading
- Instantiation: Unity GameObject/Prefab system
- Rendering: Unity Particle System or custom VFX
Extension Points
New Movement Modes
- Create new class inheriting
CGfxMoveBase - Implement
StartMove()andTickMove() - Add case to
CreateMoveMethod()
New Event Types
- Create new class inheriting
A3DSkillGfxEventorCECSkillGfxEvent - Override
GetTargetCenter()and other virtual methods - Implement Unity-specific rendering
Custom GFX Systems
- Override
LoadFlyGfx()/LoadHitGfx() - Implement custom VFX loading/instantiation
- Use Unity Addressables or custom asset system