重写`FTickableObjectBase`的虚函数没什么好说的,主要看构造函数和析构函数以及一个静态函数 ## FTickableGameObject() ```cpp FTickableGameObject::FTickableGameObject() { FTickableStatics& Statics = FTickableStatics::Get(); //如果UObject模块已初始化,就将自身添加到Statics的待加入Tick的队列 if (UObjectInitialized()) { Statics.QueueTickableObjectForAdd(this); } //直接将自身添加到Statics的Tick对象数组 else { AddTickableObject(Statics.TickableObjects, this); } } ``` ## ~FTickableGameObject() ```cpp FTickableGameObject::~FTickableGameObject() { //从Statics删除自己 FTickableStatics& Statics = FTickableStatics::Get(); Statics.RemoveTickableObjectFromNewObjectsQueue(this); FScopeLock LockTickableObjects(&Statics.TickableObjectsCritical); RemoveTickableObject(Statics.TickableObjects, this, Statics.bIsTickingObjects); } ``` ## static TickObjects(UWorld* World, const int32 InTickType, const bool bIsPaused, const float DeltaSeconds) 代码很长就不贴了, 主要干了两件事 1. 加锁避免`GC`破坏`UObject`(这个不算) 2. 将`Statics`中`NewTickableObjects`也就是待添加的对象添加到`Tick`数组中 3. 遍历所有`TickableObject`, 根据`TickType`、`LEVELTICK`枚举和相关虚函数判断`TickableObject`是否满足以下条件,是则调用`TickableObject->Tick(DeltaSeconds) 1. `TickType`为`Always`或`TickableObject->IsTickable()`为`true`且`TickableObject`的`World`等于`TickObjects`函数的实参`World`,即该`Object`属于该`World` 2. 在编辑器内且`TickableObejct->IsTickableInEditor()`为`true`; 在游戏中未暂停且`TickType`不等于`LEVELTICK_TimeOnly`或暂停且`TickableObject->IsTickableWhenPaused()`为`true`