重写`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`