前面的都是在節省頻寬上面下功夫,而最後一個能夠改善網路品質的方法就是調整Priority-優先度,最主要的概念是在有限的頻寬裡面去決定要同步的資訊優先度高低進行同步,假設現在有五個物件需要同步但是頻寬不夠讓五個物件都同步,這時候就要去思考什麼物件比較重要,他必須要時時保持更新,因此要為他設定較高的優先度來確保他會優先執行同步。
// In Actor.h
virtual float GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, class AActor* Viewer, AActor* ViewTarget, UActorChannel* InChannel, float Time, bool bLowBandwidth);
// In ActorReplication.cpp
float AActor::GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, AActor* Viewer, AActor* ViewTarget, UActorChannel* InChannel, float Time, bool bLowBandwidth)
{
if (bNetUseOwnerRelevancy && Owner)
{
// If we should use our owner's priority, pass it through
return Owner->GetNetPriority(ViewPos, ViewDir, Viewer, ViewTarget, InChannel, Time, bLowBandwidth);
}
if (ViewTarget && (this == ViewTarget || GetInstigator() == ViewTarget))
{
// If we're the view target or owned by the view target, use a high priority
Time *= 4.f;
}
else if (!IsHidden() && GetRootComponent() != NULL)
{
// If this actor has a location, adjust priority based on location
FVector Dir = GetActorLocation() - ViewPos;
float DistSq = Dir.SizeSquared();
// Adjust priority based on distance and whether actor is in front of viewer
if ((ViewDir | Dir) < 0.f)
{
if (DistSq > NEARSIGHTTHRESHOLDSQUARED)
{
Time *= 0.2f;
}
else if (DistSq > CLOSEPROXIMITYSQUARED)
{
Time *= 0.4f;
}
}
else if ((DistSq < FARSIGHTTHRESHOLDSQUARED) && (FMath::Square(ViewDir | Dir) > 0.5f * DistSq))
{
// Compute the amount of distance along the ViewDir vector. Dir is not normalized
// Increase priority if we're being looked directly at
Time *= 2.f;
}
else if (DistSq > MEDSIGHTTHRESHOLDSQUARED)
{
Time *= 0.4f;
}
}
return NetPriority * Time;
}
上面的程式碼是在Actor.h中的虛擬函式以及在ActorReplication.cpp裡面實現的基本內容,從這裡可以發現其實優先度會不斷地做動態調整,最主要會根據不同的條件去決定最終的優先度,原本的條件會根據關聯性與距離來做優先度的調整,我們的視角所看到的東西,有關連性或是距離越近的優先度就越高。
筆者在理解內容的時候最困難的莫過於Time這個參數所代表的意義,讀者可以看到他對於最終優先度所擁有的絕對影響力,事實上它所代表的是從複製開始之後所經過的時間,讀者想想時間過得越久數字也會越大,在最後得到的優先度也會越大,只是在過程中會利用不同條件去改變時間的比例讓最終結果改變。