TwinStickShooter模板應該是比較好的了解UE基本Pawn和Projectile的一個C++例子。以下是一些問題。
一、這個模板以純C++編寫,沒有藍圖,所以第一步,我想測試下如何引用藍圖,以修改子彈的外觀為例。
- 從ATwinStickShooterProjectile派生藍圖類,稱為BP_TwinStickShooterProjectile好了,然后在BP_TwinStickShooterProjectile中修改子彈的顏色(材質了),改為紅色。那么純粹的C++如何引用并產生藍圖的實例呢?
這樣實現:在pawn類中添加 TSubclassOf<ATwinStickShooterProjectile> ProjectileTemplate 成員變量,加不加UPROPERTY均可,因為我們將引用資源,資源是客觀存在的,不是我們動態產生的,不會GC。然后在對應的實現文件(.cpp)的構造函數中,添加如下代碼:
//設置子彈藍圖的引用
ConstructorHelpers::FClassFinder<ATwinStickShooterProjectile> AssetProjectile(TEXT("Blueprint'/Game/Blueprints/BP_TwinStickShooterProjectile.BP_TwinStickShooterProjectile_C'"));
if (AssetProjectile.Succeeded())
{
ProjectileTemplate = AssetProjectile.Class;
}
特別注意字符串后面添加"_C",即:Blueprint'/Game/Blueprints/BP_TwinStickShooterProjectile.BP_TwinStickShooterProjectile_C。這個字符串直接在編輯器中點選子彈對應的藍圖,然后copy reference,粘貼到對應的位置,然后添加后綴_C。因為這是藍圖類,后面都應該有后綴,話說UE版本號都15.1了,怎么還這個德性?
在FireShot函數中,如下修改:
UWorld* const World = GetWorld();
if (World != NULL)
{
// spawn the projectile
//World->SpawnActor<ATwinStickShooterProjectile>(SpawnLocation, FireRotation);
// 產生藍圖子彈
World->SpawnActor<ATwinStickShooterProjectile>(ProjectileTemplate, SpawnLocation, FireRotation);
}
桔色是原來模板的,注釋掉,然后添加紅色代碼,編譯,可以觀察到的確生成了自定義的子彈。
其中pawn類的tick函數值得研究,例如在輸入綁定時,如果BindAxis,無論是否有輸入,系統就回調自己的函數,BindAction則不存在這個問題。這個例子給出了一個較好的解決方案,只綁定名稱,不綁定回調函數,這樣我們在需要的時候,自己調用GetInputAxis,這兩種實現各有千秋,只是后一種是傳統的方式,比較熟悉。

未完待續,卡殼了……
繼續。
UProjectileMovementComponent有幾個屬性很好玩,如下:


如果設置bIsHomingProjectile = true; 生成子彈的Actor后,設置HomingTargetComponet,則子彈將以HomingTargetComponent為目標,實現跟蹤效果。。。當然,還得設置UProjectileMovementComponent的HomingAccelerationMagnitude,這個值決定加速度,,犀利!
在子彈的構造函數中如下添加代碼:
// 添加測試代碼 ProjectileMovement->bIsHomingProjectile = true; ProjectileMovement->HomingAccelerationMagnitude = 2500;
在Pawn的開火函數中如下添加代碼:
if (World != NULL)
{
// spawn the projectile
//World->SpawnActor<ATwinStickShooterProjectile>(SpawnLocation, FireRotation);
// 產生藍圖子彈
ATwinStickShooterProjectile* Projectile = World->SpawnActor<ATwinStickShooterProjectile>(ProjectileTemplate, SpawnLocation, FireRotation);
//添加HomingTargetComponent
if (TargetHome)
{
Projectile->GetProjectileMovement()->HomingTargetComponent = TargetHome->GetRootComponent();
}
}
紅色的為添加的代碼,當然在測試時,要在collision中把子彈與pawn和子彈之前的響應設置為ignore,要不然,子彈產生的太快,彼此會碰撞,并且開戶追蹤后,子彈會擊中玩家自己,效果不好,選擇ignore就ok了。效果圖:

nice! 有空再扒扒UMovementComponent中的碰撞的實現。
浙公網安備 33010602011771號