9.8 KiB
9.8 KiB
Model Loading Flow: C++ to C# Conversion
This document maps the C++ model loading sequence to the C# Addressables-based implementation.
C++ Version Flow
1. INITIALIZATION
┌─────────────────────────┐
│ CECPlayer Constructor │
│ memset(m_pModels, 0) │
└───────────┬───────────────┘
│
▼
2. LOAD REQUEST
┌─────────────────────────┐
│ LoadPlayerSkeleton() │
└───────────┬───────────────┘
│
┌───────┴───────┐
│ │
▼ ▼
Synchronous Asynchronous
│ │
│ ▼
│ ┌────────────────────┐
│ │ QueueECModelForLoad │
│ │ (Background Thread)│
│ └───────────┬────────┘
│ │
│ ▼
│ ┌────────────────────┐
│ │ ThreadLoadPlayerModel│
│ └───────────┬────────┘
│ │
│ ▼
│ ┌────────────────────┐
│ │ m_aLoadedModels.Add │
│ └───────────┬────────┘
│ │
│ ▼
│ ┌────────────────────┐
│ │ DeliverLoadedModels │
│ │ (Every Frame Tick) │
│ └───────────┬────────┘
│ │
└──────────────────┘
│
▼
3. MODEL CREATION
┌─────────────────────────┐
│ LoadPlayerModel() │
│ - new CECModel │
│ - Load model file │
│ - Load skins/equips │
└───────────┬───────────────┘
│
▼
4. MODEL ASSIGNMENT
┌─────────────────────────┐
│ SetPlayerLoadedResult() │
│ - m_pPlayerModel = ... │
│ - m_pModels[MAJOR] = ...│
└─────────────────────────┘
C# Version Flow (Using Addressables)
1. INITIALIZATION
┌─────────────────────────┐
│ CECPlayer.Awake() │
│ - m_aEquips = new int[] │
│ - m_iShape = 0 │
│ (No memset needed) │
└───────────┬───────────────┘
│
▼
2. LOAD REQUEST
┌─────────────────────────┐
│ CECHostPlayer.InitCharacter() │
│ - LoadResources() │
│ - SetPlayerModel() │
└───────────┬───────────────┘
│
┌───────┴───────┐
│ │
▼ ▼
LoadResources() SetPlayerModel()
│ │
▼ ▼
┌──────────────┐ ┌──────────────────────┐
│LoadPlayerSkeleton│ │NPCManager.GetModelPlayer│
└───────┬──────┘ └──────────┬───────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────────────────┐
│SetPlayerLoadedResult│ │AddressableManager.LoadPrefabAsync│
└───────┬──────┘ └──────────┬───────────────┘
│ │
▼ │
┌──────────────┐ │
│OnAllResourceReady│ │
└──────────────┘ │
│
▼
┌──────────────────────┐
│ Unity Addressables │
│ LoadAssetAsync() │
│ (Async/Await) │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Instantiate(prefab) │
│ SetParent() │
│ SetActive(true) │
└──────────────────────┘
Key Differences
1. Initialization
C++:
memset(m_pModels, 0)- Zero-initializes model array
C#:
Awake()method initializes arrays:m_aEquips = new int[(int)IndexOfIteminEquipmentInventory.SIZE_ALL_EQUIPIVTR]; m_iShape = 0;- Location:
Assets/PerfectWorld/Scripts/Move/CECPlayer.cs:186-192
2. Load Request Entry Point
C++:
LoadPlayerSkeleton()directly callsLoadPlayerModel()orQueueECModelForLoad()
C#:
LoadPlayerSkeleton()is simplified and mostly commented out- Actual loading happens in
InitCharacter()→SetPlayerModel() - Location:
Assets/Scripts/CECHostPlayer.cs:1173-1175
3. Asynchronous Loading Mechanism
C++:
- Background thread:
QueueECModelForLoad()→ThreadLoadPlayerModel() - Queue system:
m_aLoadedModels.Add() - Frame-based delivery:
DeliverLoadedModels()called every frame tick
C#:
- No background thread - Uses Unity's async/await pattern
- No queue system - Direct async/await handling
- No frame-based delivery - Completion handled by async/await
- Flow:
SetPlayerModel()→NPCManager.GetModelPlayer()→AddressableManager.LoadPrefabAsync() - Location:
Assets/PerfectWorld/Scripts/Move/CECPlayer.cs:195-209
4. Model Loading Implementation
C++:
LoadPlayerModel()createsCECModel, loads model file, loads skins/equips
C#:
NPCManager.GetModelPlayer()loads model via Addressables:var prefab = await AddressableManager.Instance.LoadPrefabAsync(_playerModelPaths[profession * GENDER.NUM_GENDER + gender]); var player = Instantiate(prefab);- Location:
Assets/PerfectWorld/Scripts/Managers/NPCManager.cs:101-113
5. Addressables System
C# Implementation:
AddressableManagerwraps Unity Addressables API- Uses
Addressables.LoadAssetAsync<GameObject>()internally - Caches loaded assets in
_loadedPrefabAssetsdictionary - Location:
Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs:135-170
6. Model Assignment
C++:
SetPlayerLoadedResult()assigns:m_pPlayerModel = ...m_pModels[MAJOR] = ...
C#:
- Model assignment happens directly in
SetPlayerModel():_pPlayerModel = await NPCManager.Instance.GetModelPlayer(profession, gender); _pPlayerModel.transform.SetParent(parentModel); _pPlayerModel.transform.localPosition = Vector3.zero; _pPlayerModel.SetActive(true); - Location:
Assets/PerfectWorld/Scripts/Move/CECPlayer.cs:203-208 SetPlayerLoadedResult()only callsOnAllResourceReady()(simplified)- Location:
Assets/Scripts/CECHostPlayer.cs:375-378
Code Locations Summary
C# Files:
-
CECPlayer.cs (Base class)
Awake(): InitializationSetPlayerModel(): Main model loading entry point- Location:
Assets/PerfectWorld/Scripts/Move/CECPlayer.cs
-
CECHostPlayer.cs (Host player implementation)
LoadResources(): Entry point for resource loadingLoadPlayerSkeleton(): Simplified skeleton loading (mostly commented)SetPlayerLoadedResult(): Simplified result handlerInitCharacter(): Calls LoadResources() and SetPlayerModel()- Location:
Assets/Scripts/CECHostPlayer.cs
-
NPCManager.cs (Model provider)
GetModelPlayer(): Loads model via Addressables- Location:
Assets/PerfectWorld/Scripts/Managers/NPCManager.cs
-
AddressableManager.cs (Addressables wrapper)
LoadPrefabAsync(): Core Addressables loading method- Location:
Assets/PerfectWorld/Scripts/Addressable/AddressableManager.cs
-
CECHostPlayer.Model.cs (Shape transformation)
TransformShape(): Handles shape changesQueueLoadDummyModel(): Referenced but implementation may be elsewhere- Location:
Assets/Scripts/CECHostPlayer.Model.cs
Notes
- The C# version removed the background thread loading system in favor of Unity's async/await pattern
- The queue-based delivery system (
DeliverLoadedModels) is replaced by async/await completion handlers - Addressables provide built-in caching and memory management, eliminating the need for manual queue management
- Some C++ methods like
LoadPlayerModel()andQueueLoadDummyModel()are commented out in the C# version, suggesting they may be refactored or replaced - The model loading is now more streamlined with direct async calls rather than a multi-step queue system