UE4網課學習筆記

學習資源:https://www.bilibili.com/video/av52017180?p=22


  • BSP:二進制空間劃分
  • 讓門可旋轉,需要將屬性改爲“Movable”
  • 選中一個物體後,在Level BluePrint中右鍵會自動出現對應物體的函數
  • TimeLine: 其中:Play是正向播放,Play From Start是每次從第0幀開始(這樣對於開門不好,如果開到一半又出來,再進去,門會瞬間回到z=0°開始)
  • 實現門開門關,藍圖監控鍵盤輸入/鼠標點擊,要Enable Input後。Gate節點,兩種輸入A,B只有一種輸出C,FlioFlop接受C,有兩條路線交替走
  • 點擊Eject能切換到自由模式
  • 觸發其他藍圖類的自定義事件(跨藍圖使用腳本的變量/函數)
  • 圖表:在一個藍圖中,進行平面分割一樣,各個功能模塊可以分開寫,有點類似unity中一個Gameobject掛着多個腳本
  • 變量:選中一個變量→提升爲變量,在一個藍圖的不同圖表中可以被反覆利用(跨圖表使用)
  • Tick事件:每一幀都執行一次,實現物體不停地自轉
  • Branch:代表分支,切換(代替FlipFlop)
  • Ctrl + 變量拉到藍圖窗口 = 獲得Get ;Alt + 變量拉到藍圖窗口 = 設置Set ; Ctrl + W 快速複製
  • 監聽按鍵輸入,TODO:對於ThirdPersonCharacter爲什麼可以不用Enable Input也可以監聽,表示很奇怪
  • 射線檢測可以自定義通道,Actor開啓對應通道纔可以被檢測到

PacMan Project總結

  • 創建材質:
  • 編碼規範問題:虛幻引擎生成的類,會自帶首字母,比如Actor類classname會自動添上Aclassname
  • 假如GENERATED_BODY()爆紅:切換debug editor和develop。debug模式便於程序員調試,但是優化不足
  • PlayerStart:確認主角的位置,如果不存在默認(0,0,0)
  • GameMode:創建基於它的BP_GameMode,在Project Settings→Maps&Modes設置BP_GameMode。TODO:爲什麼要創建對應的藍圖類?????藍圖和C++一起協同,GameMode有什麼作用(遊戲規則??)?目前有了理解,以後再來寫
  • C++類拖拽到空間中,再調用加載Mesh的方法,就可以顯性。已解決:爲什麼要設置這些屬性,每個屬性有什麼不同?有點像unity中的可序列化,可見等等
  • 如何取消某個類的Tick調用 
  • 代碼實現按鍵監聽
  • 創建基於C++類的藍圖,TODO:有何作用?比較像u3d的Ins面板
  • 關卡重新開始函數定義 以及 函數綁定
  • 碰撞檢測
    • 必須要先有碰撞體,主角的碰撞體是在藍圖類內實現的,因此要先進行綁定
    • UFUNCTION()  TODO:反射機制?爲什麼得到的是AActor而不是類似Unity中的GameObject呢?
          void OnCollision(class UPrimitiveComponent* HitComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
  • 獲取World()中的某個類
    •     CollectablesCntToEat = 0;
          for (TActorIterator<ACollectables> AcollectableIterator(GetWorld()); AcollectableIterator; ++AcollectableIterator) {
              ++CollectablesCntToEat;
          }
  • Log:UE_LOG(LogTemp, Warning, TEXT("InitCollectablesCount = %d"), CollectablesCntToEat);

總結:監聽輸入調用函數,碰撞檢測


Unreal Engine 4 For unity

Category Unity UE4
Gameplay Types Component Component
  GameObject ActorPawn
  Prefab Blueprint Class
Editor UI Hierarchy Panel World Outliner
  Inspector Details Panel
  Project Browser Content Browser
  Scene View Viewport
Meshes Mesh Static Mesh
  Skinned Mesh Skeletal Mesh
Materials Shader MaterialMaterial Editor
  Material Material Instance
Effects Particle Effect Effect, Particle, Cascade
  Shuriken Cascade
Game UI UI UMG (Unreal Motion Graphics)
Animation Animation Skeletal Animation System
  Mecanim Persona , Animation Blueprint
2D Sprite Editor Paper2D
Programming C# C++
  Script Blueprint
Physics Raycast Line Trace, Shape Trace
  Rigid Body Collision, Physics
Runtime Platforms iOS Player, Web Player Platforms
  • Actor,Pawn,Character可以拖進場景中,UE4用Gameplay Framework與這些特定的Actor相關聯
  • UE4_Actor和Unity_GameObject的區別在於:Unity中的GameObject是不可擴展的C#類,而UE4_Actor是可通過繼承的方式擴展並自定義的C++類
  • Unity直接添加組件,組件沒有層級關係;而UE4是在將放置到世界的Actor的detail面板中,並且存在層級關係
  • Unity:GameObject→Prefabs   ;  UE4:Actor(帶有組件)→“Blueprint/Add Script”(變成預製體)
  • UE4也可以添加組件(藍圖/C++腳本 有start和update)
  • Unity的GameObject都有一個Transform組件來提供位置,旋轉,比例,而UE4是使用Root Component
  • 能放進關卡中的都是Actor類,Object類是所有Unreal類的基類
  • Gameplay Framework是某種遊戲框架,需要了解內置類的源碼實現,待理解學習
  • 打開VS有兩種方法:①菜單Open Visual Studio ②雙擊C++類
  • 當手動修改文件源文件 or 下載新版本的UE4,可能需要點擊菜單欄中的Refresh VS Project;或者虛uproject文件選擇"Generate Visual Studio project files"。
  • UE4區別於U3D的是:UE4的Actor(GameObject)可以寫代碼,這是最不適應的地方。理解:相當於unity多了個組件,只不過ue4給繼承在了GameObject上。
  • 在UE4種調用基類的方法,在Unity中的C#會調用 base.Update() ,但是UE4種的C++會使用 Super::TickComponent();
  • Instantiating GameObject / Spawning Actor
    • unity:GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
    • ue4:
      AMyActor* CreateCloneOfMyActor(AMyActor* ExistingActor, FVector SpawnLocation, FRotator SpawnRotation)
      {
          UWorld* World = ExistingActor->GetWorld();
          FActorSpawnParameters SpawnParams;
          SpawnParams.Template = ExistingActor;
          World->SpawnActor<AMyActor>(ExistingActor->GetClass(), SpawnLocation, SpawnRotation, SpawnParams);
      }
  • Unreal 子類化 UObject 類似於 Unity 子類化 ScriptableObject,即.asset資源文件,不依賴於任何Actor或者需要生成到世界的物體,其實就是static數據
    • unity:MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();
    • ue4:UMyObject* NewObj = NewObject<UMyObject>();
  • 類型轉換
    • unity:C#無指針
      Collider collider = gameObject.GetComponent<Collider>;
      SphereCollider sphereCollider = collider as SphereCollider;
      if (sphereCollider != null)
      {
              // ...
      }
    • UE4:使用Cast進行指針轉換
      UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
      USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
      if (SphereCollider != nullptr)
      {
              // ...
      }
  • Destroying GameObject / Actor
    • unity:Destroy(MyGameObject);
    • UE4:MyActor->Destroy();
  • Destroying GameObject / Actor(With 1 Second Delay)
    • unity:Destroy(MyGameObject, 1);
    • UE4:MyActor->SetLifeSpan(1);
  • Disabling GameObjects / Actors
    • unity:MyGameObject.SetActive(false);
    • UE4:
          // Hides visible components
          MyActor->SetActorHiddenInGame(true);
      
          // Disables collision components
          MyActor->SetActorEnableCollision(false);
      
          // Stops the Actor from ticking
          MyActor->SetActorTickEnabled(false);
  • 通過組件獲得父親
    • unity:GameObject ParentGO = MyComponent.gameObject; 
    • UE4:AActor* ParentActor = MyComponent->GetOwner();
  • Accessing a Component from the GameObject / Actor 
    • unity:MyComponent MyComp = gameObject.GetComponent<MyComponent>();
    • UE4:UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();
  • Finding GameObjects / Actors
    • unity:
      //C# 
      // Find GameObject by name 通過名字
      GameObject MyGO = GameObject.Find("MyNamedGameObject");
       
      // Find Objects by type  通過類型
      MyComponent[] Components = Object.FindObjectsOfType(typeof(MyComponent)) as MyComponent[];
      foreach (MyComponent Component in Components)
      {
              // ...
      }
       
      // Find GameObjects by tag 通過標籤
      GameObject[] GameObjects = GameObject.FindGameObjectsWithTag("MyTag");
      foreach (GameObject GO in GameObjects)
      {
              // ...
      }
      -----------------------------------------------------------------------------------------------
    • UE4:
      //C++
      // Find Actor by name (also works on UObjects) 
      AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));
       
      // Find Actors by type (needs a UWorld object) 
      for (TActorIterator<AMyActor> It(GetWorld()); It; ++It)
      {
              AMyActor* MyActor = *It;
              // ...
      }
      
      // Find UObjects by type
      for (TObjectIterator<UMyObject> It; It; ++it)
      {
          UMyObject* MyObject = *It;
          // ...
      }
       
      // Find Actors by tag (also works on ActorComponents, use TObjectIterator instead)
      for (TActorIterator<AActor> It(GetWorld()); It; ++It)
      {
          AActor* Actor = *It;
          if (Actor->ActorHasTag(FName(TEXT("Mytag"))))
          {
              // ...
          }
      }
  • Adding tags to GameObjects / Actors
    • unity:MyGameObject.tag = "MyTag";
    • UE4:MyActor.Tags.AddUnique(TEXT("MyTag"));
  • Adding tags to MonoBehaviours / ActorComponents 
    • unity:MyComponent.tag = "MyTag";
    • UE4:MyComponent.ComponentTags.AddUnique(TEXT("MyTag"));
  • Comparing tags on  Actors and ActorComponents
    • if (MyActor->ActorHasTag(FName(TEXT("MyTag"))))
    • if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
  • PrimitiveComponent組件,類似u3d中的Rigidbody組件
  • 碰撞體組件上帶有通道,通過自定義通道,可以自由的進行碰撞檢測的組合
  • UE4進行Trigger檢測
    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()
    
        // My trigger component
        UPROPERTY()
        UPrimitiveComponent* Trigger;
    
        AMyActor()
        {
            Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("TriggerCollider"));
    
            // Both colliders need to have this set to true for events to fire
            Trigger.bGenerateOverlapEvents = true;
    
            // Set the collision mode for the collider
            // This mode will only enable the collider for raycasts, sweeps, and overlaps
            Trigger.SetCollisionEnabled(ECollisionEnabled::QueryOnly);
        }
    
        virtual void NotifyActorBeginOverlap(AActor* Other) override;
    
        virtual void NotifyActorEndOverlap(AActor* Other) override;
    };
  • UE4射線檢測
    GameObject FindGOCameraIsLookingAt()
    {
        Vector3 Start = Camera.main.transform.position;
        Vector3 Direction = Camera.main.transform.forward;
        float Distance = 100.0f;
        int LayerBitMask = 1 << LayerMask.NameToLayer("Pawn");
    
        RaycastHit Hit;
        bool bHit = Physics.Raycast(Start, Direction, out Hit, Distance, LayerBitMask);
    
        if (bHit)
        {
            return Hit.collider.gameObject;
        }
    
        return null;
    }
  • 在UE4中,碰撞組件和剛體組件是同一個組件,它們的基類是 UPrimitiveComponent ,它有很多子類(USphereComponent, UCapsuleComponent等等)  可以滿足你的需求。
  • 監聽輸入事件:函數綁定,Project Seeting → Engine → Input
  • 設置啓動場景:Project Seeting→Map & Modes ;自動加載上次的項目:Edit/Editor Preference→Loading And Saving → Startup
  • .Net Framework UE4
    String FStringFText
    List TArray
    Dictionary TMap
    HashSet TSet
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章