UE4和C++ 开发-Unity 过度到 Unreal 4 对比简化版

 3、 两个引擎的部分术语对比:

4.7、From GameObjects to Actors 从GameObjects到Actors

    GameObject在UE4中如何体现?UE4有一个 Gameplay Framework 系统来使用这些Actors工作。

5.1、UE4中,系统也将提供给我们两个函数,他们分别是 InitializeComponent() 函数和 TickComponent()函数,这两个函数和Unity中Start()函数和Update()函数类似

5.2、Scriptable Actor Blueprint Classes 可以编辑的Actor蓝图类

  5.2.1、你新建的 Actor蓝图类(此处不是组件蓝图类)可以使用蓝图来实现可视化编辑

  5.2.2、代码实现功能的C++类。下面给出了三个的对应关系。

  5.2.2、UE4 C++

#pragma once
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class AMyActor : public AActor
{    
GENERATED_BODY()  
  int Count;  

  // Sets default values for this actor's properties.  
  AMyActor()   
  {      
  // Allows Tick() to be called    
    PrimaryActorTick.bCanEverTick = true; 
     }   
 // Called when the game starts or when spawned.  
  void BeginPlay()   
 {     
   Super::BeginPlay();    
    Count = 0;  
  }   
 // Called every frame. 
   void Tick(float DeltaSeconds)   
 {       
 Super::Tick(DeltaSeconds);   
     Count = Count + 1;   
     GLog->Log(FString::FromInt(Count)); 
   }};  

5.6、Transform Components  Transform组件

Actors有一个叫做RootComponent的组件,Actor在世界中拥有位置、旋转、缩放属性,

6.3、Writing Event Functions (Start, Update, etc.) 写事件函数

6.3.2、C++ :

UCLASS()
class AMyActor : public AActor{  
  GENERATED_BODY()   
 // Called at start of game.    
void BeginPlay(); 
   // Called when destroyed.  
  void EndPlay(const EEndPlayReason::Type EndPlayReason); 
   // Called every frame to update this actor.  
  void Tick(float DeltaSeconds);};  

 

6.3.4、UE4中的组件包含一些不同的函数,下面列举了一些简单例子:

C++ :

UCLASS()
class UMyComponent : public UActorComponent{  
  GENERATED_BODY()   
 // Called after the owning Actor was created  
  void InitializeComponent();   
 // Called when the component or the owning Actor is being destroyed   
 void UninitializeComponent();  
  // Component version of Tick   
 void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction);};  

请记住,在UE4中,调用父类的函数的版本是非常重要的。

比如说,在unity里面这样写:base.Update();而在UE4中则需要这样写:Super::TickComponent();

void UMyComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{  
  // Custom tick stuff here  
  Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}  

UE4的C++代码中,字母前缀'A'表示是Actor的子类,'U'表示Object的子类。当然还有一些其他的前缀,比如‘F’,表示是一些空白的数据结构或者不是Object类。

6.3.6、Writing gameplay code in UE4  在UE4中编写游戏代码

6.3.6.1、Instantiating GameObject / Spawning Actor  实例化一个物体

NewObject()函数是用来创建UObject类型的物体,SpawnActor()函数是用来创建AActor类型的物体。

UE4中,这样写:

  1. UMyObject*NewObj=NewObject<UMyObject>();  

那对于Actor类型的物体如何实例化呢?Actors物体是通过使用一个UWorld类型的World物体上的SpawnActor()函数来实例化的。一些UObject提供了GetWorld()函数,比如所有的Actors类就可以给你提供这个函数。观察下面的函数,我们发现,我们需要传递进来的第一个参数是我们想要实例化的Actor的类,而不是Actor本身。在我们的实例中,这个类可以使AMyEnemy的任何子类。

但是如果我想复制一个物体,我该使用哪一种盛丽华的函数呢?NewObject()函数和SpawnActor()函数都个可以提供一个“template(模板)”物体来使用。虚幻引擎将会从这个物体来复制,而不是从头开始实例化对象,这样做将会把他的所有的UPROPERTYs(属性特性)和组件拷贝到。

 ·

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);
}  

在UE中,使用物体的构造函数来实现相同的功能。

UCLASS()
class AMyActor : public AActor{  
  GENERATED_BODY()  
  UPROPERTY()  
  int32 MyIntProp; 
   UPROPERTY()  
  USphereComponent* MyCollisionComp; 
   AMyActor()    {   
     MyIntProp = 42; 
       MyCollisionComp = CreateDefaultSubobject<USphereComponent>(FName(TEXT("CollisionComponent"));     
   MyCollisionComp->RelativeLocation = FVector::ZeroVector;  
      MyCollisionComp->SphereRadius = 20.0f; 
   }};  

在AMyActor的构造函数中,我们给这个类设置了默认的参数值,要记住使用CreateDefaultSubobject()函数。我们可以使用这个函数来创建组件并且为其制定默认的参数。我们使用这个函数创建的所有子物体实际上就是一个默认的模板,因此我们可以在一个子类中或者蓝图中修改他们。

Casting from one Type to Another 类型转换

就是根据已有的组件转换成另一种类型来有条件的处理一些事情。

Collider collider = gameObject.GetComponent<Collider>;
SphereCollider sphereCollider = collider as SphereCollider;
if (sphereCollider != null)
{   
     // ...
}  
UE4 C++:
UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());

USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
if (SphereCollider != nullptr)
{ 
       // ...
}  

6.3.6.1.2、Destroying GameObject / Actor  销毁物体 

Disabling GameObjects / Actors  使物体处于不激活状态

6.3.6.1.3、Accessing the GameObject / Actor from Component 通过组件访问物体

Accessing a Component from the GameObject / Actor  通过物体访问组件 

 C++:

UMyComponent*MyComp=Cast<UMyComponent>(
MyActor->GetComponentByClass(UMyComponent::StaticClass())
);  

6.3.6.1.4、Finding GameObjects / Actors  查找物体
// 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)
{  
      // ...
}
// 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"))))  
  {   
     // ...  
  }
}  
// Checks if an ActorComponent has this tag

if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
{  
  // ...
}  

6.3.6.1.8、Physics: RigidBody vs. Primitive Component  物理部分:RigidBody 对比 Primitive 组件

虚幻引擎把可能的物理和可视化组合在PrimitiveComponent组件中。任何一个组件都在世界中拥有集合属性,他们可以被渲染出来也可以和拥有PrimitiveComponent组件的物体相互作用。

6.3.6.1.9、Layers vs Channels  Unity中的Layers和UE4中的Channels

6.3.6.1.10、RayCast vs RayTrace  光线投射

 6.3.6.1.10.2、C++

APawn* AMyPlayerController::FindPawnCameraIsLookingAt()
{   
 // You can use this to customize various properties about the trace    FCollisionQueryParams Params;  
  // Ignore the player's pawn  
  Params.AddIgnoredActor(GetPawn());  
  // The hit result gets populated by the line trace 
   FHitResult Hit; 
   // Raycast out from the camera, only collide with pawns (they are on the ECC_Pawn collision channel)  
  FVector Start = PlayerCameraManager->GetCameraLocation();  
  FVector End = Start + (PlayerCameraManager->GetCameraRotation().Vector() * 1000.0f);    bool bHit = GetWorld()->LineTraceSingle(Hit, Start, End, ECC_Pawn, Params); 
   if (bHit)  
  {      
  // Hit.Actor contains a weak pointer to the Actor that the trace hit    
    return Cast<APawn>(Hit.Actor.Get());  
  }  
  return nullptr;
}  

 6.3.6.1.11、Triggers 触发器

 6.3.6.1.11.2、UE4 C++:

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); 
   }  
  void BeginPlay()   
 {      
  // Register to find out when an overlap occurs        OnActorBeginOverlap.AddDynamic(this, &AMyActor::OnTriggerEnter);        OnActorEndOverlap.AddDynamic(this, &AMyActor::OnTriggerExit);   
     Super::BeginPlay();  
  }  
  void EndPlay(const EEndPlayReason::Type EndPlayReason)  
  {   
     OnActorBeginOverlap.RemoveDynamic(this, &AMyActor::OnTriggerEnter);        OnActorEndOverlap.RemoveDynamic(this, &AMyActor::OnTriggerExit);        Super:EndPlay(EndPlayReason);   
 }   
 UFUNCTION()  
  void OnTriggerEnter(AActor* Other); 
   UFUNCTION() 
   void OnTriggerExit(AActor* Other);
};  

6.3.6.1.12、Kinematic Rigidbodies 运动学

在UE4中,碰撞组件和刚体组件是一个东西。他们的父类是UPrimitiveComponent,他又很多子类来满足你的需求,比如USphereComponent,UCapsuleComponent等等。

6.3.6.1.12.2、UE4 C++:

UCLASS()
class AMyActor : public AActor
{ 
   GENERATED_BODY()    
UPROPERTY()    
UPrimitiveComponent* PhysicalComp;    
AMyActor()    
{        
PhysicalComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionAndPhysics"));        PhysicalComp->SetSimulatePhysics(false);        
PhysicalComp->SetPhysicsLinearVelocity(GetActorRotation().Vector() * 100.0f);    
}
};  

6.3.6.1.13、Input events  输入事件 

6.3.6.1.13.2、UE4 C++

UCLASS()
class AMyPlayerController : public APlayerController
{
    GENERATED_BODY()    
void SetupInputComponent()    
{        
Super::SetupInputComponent();        
InputComponent->BindAction("Fire", IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent); 
       InputComponent->BindAxis("Horizontal", this, &AMyPlayerController::HandleHorizontalAxisInputEvent); 
       InputComponent->BindAxis("Vertical", this, &AMyPlayerController::HandleVerticalAxisInputEvent); 
   }    
void HandleFireInputEvent();  
  void HandleHorizontalAxisInputEvent(float Value);
    void HandleVerticalAxisInputEvent(float Value);
};  

How do I see Log Output from my game? 怎么看调试输出信息?

UE4编辑器中:Window -> Developer Tools

How do I throw exceptions? 我怎么才能抛出异常错误?

UE4中没有这样的机制,而是使用check()函数。

Where is the .NET Framework? .NetFramework在哪里?

.Net Framework UE4
String FStringFText
List TArray
Dictionary TMap
HashSet TSet

猜你喜欢

转载自blog.csdn.net/2201_75598244/article/details/132927756