2016年11月20日 星期日

Unreal: Actor Spawning and GetDefaultObject in C++

since: 2016/11/20
update: 2016/11/20

reference:
1. Actor Spawning and GetDefaultObject | Orfeas Eleftheriou
2. I touchs: Unreal: Adding a C++ Class
3. I touchs: Unreal: Exposing C++ variables to Blueprints
4. I touchs: Unreal: Exposing C++ functions to Blueprints
5. I touchs: Unreal: Add Override C++ Event Functions in Blueprints
6. I touchs: Unreal: Create C++ Blueprint Function Library
7. I touchs: Unreal: Casting types in C++


A. 新增 "要被生成的角色" 之 C++ 類別
     1. 可以接續 I touchs: Unreal: Casting types in C++ 的專案

     2. Add New > New C++ Class...


     3. 選擇 "Actor" 作為 Parent Class > Next

     4. 幫新增的 Class 命名: UsefulActor > Create Class

-----------------------------------------------------------------------------------------------

B.  UsefulActor 新增  DoSomething() 函式宣告與內容
     1. 修改: UsefulActor.h
....
    //@add ######

    UFUNCTION(BlueprintCallable, Category = "MyUsefulFunction")
    void DoSomething();
....


     2. 修改: UsefulActor.cpp
....
//@add ######

void AUsefulActor::DoSomething()
{
    GLog->Log("UsefulActor does something...");
}
....

     3. 存檔編譯

-----------------------------------------------------------------------------------------------

C. 新增繼承自 UsefulActor 的 Blueprint 類別:
1. Add New > Blueprint Class


     2. 搜尋選擇 "UsefulActor" 作為 Parent Class > Next

     3. 命名為: BP_UsefulActor

     4. 點二下滑鼠, 進入 BP_UsefulActor 的 Blueprint,
         > 新增一個 static mesh (在此為 Sphere),
         > 主要用來被告知角色何時生成了, 並調整其大小.


-----------------------------------------------------------------------------------------------

D. 新增 "用來生成角色" 的 C++ 類別
    1. Add New > New C++ Class...


    2. 選擇 "Actor" 作為 Parent Class > Next


    3. 幫新增的 Class 命名: ActorSpawner > Create Class

-----------------------------------------------------------------------------------------------

E.  ActorSpawner 新增宣告與內容
     1. 修改: ActorSpawner.h

          a. 加入
UsefulActor.h 標頭檔 (必須要在 ActorSpawner.generated.h 之前)
....
#include "GameFramework/Actor.h"
//@add ######

#include "UsefulActor.h"

#include "ActorSpawner.generated.h"
....


          b. 加入巨集定義
....
/*Blueprint Reference of UsefulActor class*/
UPROPERTY(EditDefaultsOnly,Category="ActorSpawning")
TSubclassOf<AUsefulActor> UsefulActorBP;
 
/*Delay after the Blueprint of the UsefulActor will get spawned*/
UPROPERTY(EditDefaultsOnly, Category = "ActorSpawning")
float TimeToSpawn = 2.f;
 
/*Spawns the UsefulActor Blueprint*/
UFUNCTION()
void SpawnUsefulActor();
....

 
     2. 修改: ActorSpawner.cpp
          a. 修改: AActorSpawner::BeginPlay() 函式
....
void AActorSpawner::BeginPlay()
{
    Super::BeginPlay();

    //@add ######
    FTimerHandle OutHandle;
 
    //Will call SpawnUsefulActor after the specified time
    GetWorld()->GetTimerManager().SetTimer(OutHandle, this, &AActorSpawner::SpawnUsefulActor, TimeToSpawn);
   
}
....


          a. 新增: AActorSpawner::SpawnUsefulActor() 函式
....
void AActorSpawner::SpawnUsefulActor()
{
    //If the usefulactorbp is valid
    if(UsefulActorBP)
    {
        //Spawn parameters for the current spawn.
        //We can use this for a number of options like disable collision or adjust the spawn position
        //if a collision is happening in the spawn point etc..
        FActorSpawnParameters SpawnParams;
 
        //Actual Spawn. The following function returns a reference to the spawned actor
        AUsefulActor* ActorRef = GetWorld()->SpawnActor<AUsefulActor>(UsefulActorBP, GetTransform(), SpawnParams);
 
        GLog->Log("Spawned the UsefulActor.");
    }
}

....

     3. 存檔編譯

-----------------------------------------------------------------------------------------------

F. 新增繼承自 ActorSpawner
的 Blueprint 類別:
     1. Add New > Blueprint Class


     2. 搜尋選擇 "ActorSpawner" 作為 Parent Class > Next

     3. 命名為: BP_ActorSpawner

     4. 點二下滑鼠, 進入 BP_ActorSpawner 的 Blueprint,
          > 在 Details 裡, 將 UsefulActorBP 屬性設為: BP_UsefulActor
          (備註: 因為我們將 static mesh(Sphere) 存放在
BP_UsefulActor 裡)

-----------------------------------------------------------------------------------------------

G. 測試
    1. 將 BP_ActorSpawner 拖拉到場景.

    2. 編譯執行:
        > 在經過 Time To Spawn 秒數後,(在此為 2 秒) 就會生成 Sphere Actor

    Output log:

-----------------------------------------------------------------------------------------------

H. 呼叫 UsefulActor 的 DoSomething 方法
    1. 修改 AActorSpawner::SpawnUsefulActor() 函式
....
//@add ######

//UsefulActorBP->DoSomething(); // ----> error
UsefulActorBP->GetDefaultObject<AUsefulActor>()->DoSomething();
....

備註: GetDefaultObject<T> comes in handy. This function, allows us to
          get the parent class of the subclass we’ve used above
          (which is where the c++ functions “reside”).

    2. 編譯執行:
        Output log
:

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。