|
最近在学习UE4,以前用Unity比较多。在学习的翻阅官方文档时发现为了更方便地使开发者从Unity过度到UnrealEngine4,UE4官方专门给出了Unity各组件与UE4中的对应关系,可见Unity YYDS,我们将从以下两个方面参考官方文档对对应关系进行总结:基本条目和代码编写。下面是Unity和UE4的界面,图中已经将相同功能区域用相同颜色标注:
Unity的界面更简洁直观,UE4的图形化程度更高
基本条目
Category | Unity | Unreal | Editor UI | Scene View | Viewport | Hierarchy | World Outliner | Inspector | Details | Project Browser | Content Browser | ToolBar | Main Toolbar | Right Click in Hierarchy | Place Actors | Gameplay Types | Component(List) | Component(Level) | GameObject | Actor(Pawn(Player or AI),Character(双足类型Pawn),Controller(占有并控制一个Pawn),Player Controller(输入设备信息驱动)) | Prefab | Blueprint Class | Meshes | Mesh | Static Mesh | Skinned Mesh | Skeletal Mesh | Materials | Shader | Material, Material Editor | Material | Material Instance | Effects | Particle Effect | Effect, Particle, Cascad | Shuriken | Cascade | Game UI | NGUI,UGUI | UMG (Unreal Motion Graphics) | Animation | Animation | Skeletal Animation System | Mecanim | Persona , Animation Blueprint | 2D | Sprite Editor | Paper2D | Programming | C# | C++ | Script(MonoBehavior) | Blueprint/C++ | Start() | BeginPlay()/InitializeComponent() | Update() | Tick()/TickComponent() | OnDestroy() | EndPlay()/UninitializeComponent() | Physics | Raycast | Line Trace, Shape Trace | Rigid Body | Collision, Physics | Runtime Platforms | iOS Player,Web Player | Platforms | Files | .package | .uproject | Asset | Content | Save Format | Scene | Map File | 层级 | Layer | Collision Channel | Physics | Rigidbody | Primitive | 测量单位 | 米 | 厘米 | 坐标系 | 左手坐标系 | 左手坐标系,X 的正方向是"前",Y 的正方向是"右",Z 的正方向是"上"。 | 其中最大的区别就是UE4可以脱离C++脚本直接进行图形化编程,例如:虚幻 4 有一项很酷的功能,新建的 Actor 蓝图类会拥有自己的可视化蓝图脚本!这样你就能为整个对象添加逻辑,而不仅仅是单个组件,如新建一个Actor类
#pragma once
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()class AMyActor : public AActor{
GENERATED_BODY()
int Count;
// 为此Actor的属性设置默认值。
AMyActor()
{
// Allows Tick() to be called
PrimaryActorTick.bCanEverTick = true;
}
// 当游戏开始或此Actor生成时调用。
void BeginPlay()
{
Super::BeginPlay();
Count = 0;
}
// 每帧调用。
void Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
Count = Count + 1;
GLog->Log(FString::FromInt(Count));
}
};`
则会经过编译生成相应的构造函数蓝图
Unity 的 prefab 和虚幻 4 的蓝图类都可以在游戏中实例化,不过Unity 的 prefab 在相互嵌套时会产生比较复杂的状况,从而限制其可扩展性;在虚幻 4 中,你可以让新建的蓝图类继承某个现有的蓝图类,然后通过新的属性、组件和可视化脚本功能来增强它。
代码编写
实例化GameObject /生成Actor
注意:C++ 中有些类以 "A" 开头,而其他一些类以 "U" 开头。前缀 "A" 代表它是 Actor 的子类,而前缀 "U" 代表它是 Object 的子类。还有其他一些前缀,比如 "F" 通常表示一个简单的数据结构类,或者其他非 Uboject 类。
Unity 中,创建对象可使用:
public class MyComponent : MonoBehaviour
{
public int MyIntProp = 42;
public SphereCollider MyCollisionComp = null;
void Start()
{
// 创建碰撞组件(如果还未创建的话)
if (MyCollisionComp == null)
{
MyCollisionComp = gameObject.AddComponent<SphereCollider>();
MyCollisionComp.center = Vector3.zero;
MyCollisionComp.radius = 20.0f;
}
}
}
使用 Instantiate 函数来新建对象的实例:
public GameObject EnemyPrefab;
public Vector3 SpawnPosition;
public Quaternion SpawnRotation;
void Start()
{
GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
NewGO.name = &#34;MyNewGameObject&#34;;
}
在 Unity 中,如果要创建自己的 ScriptableObject 子类,你可以这样实例化:
MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();
在虚幻 4 中,创建新对象可使用构造函数:
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
int32 MyIntProp;
UPROPERTY()
USphereComponent* MyCollisionComp;
AMyActor()
{
MyIntProp = 42;
MyCollisionComp = CreateDefaultSubobject<USphereComponent>(FName(TEXT(&#34;CollisionComponent&#34;));
MyCollisionComp->RelativeLocation = FVector::ZeroVector;
MyCollisionComp->SphereRadius = 20.0f;
}
};
NewObject 用于新建 UObject 类型的实例, 子类化 UObject 很像在 Unity 中子类化 ScriptableObject。它们适用于实现一些不需要在游戏中生成的类,或者不需要像Actor那样添加组件的类。如果要创建 UObject 的继承类,是像下面这样的初始化:
UMyObject* NewObj = NewObject<UMyObject>();
SpawnActor 用于新建 AActor 类型的实例,如NewObject 和 SpawnActor 函数也能通过给一个 &#34;模板&#34; 对象来工作:
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);
}
销毁对象
Unity
Destroy(MyGameObject);
Unreal
MyActor->Destroy();
蓝图
禁用对象
Unity
MyGameObject.SetActive(false);
Unreal
MyActor->Destroy();
蓝图
通过组件访问GameObject/Actor
Unity
GameObject ParentGO = MyComponent.gameObject;
Unreal
AActor* ParentActor = MyComponent->GetOwner();
蓝图
通过 GameObject / Actor 访问组件
Unity
MyComponent MyComp = gameObject.GetComponent<MyComponent>();
Unreal
UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();
蓝图
通过 GameObject / Actor 访问组件
Unity
// Find GameObject by name
GameObject MyGO = GameObject.Find(&#34;MyNamedGameObject&#34;);
// 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(&#34;MyTag&#34;);
foreach (GameObject GO in GameObjects)
{
// ...
}
Unreal
// Find Actor by name (also works on UObjects)
AActor* MyActor = FindObject<AActor>(nullptr, TEXT(&#34;MyNamedActor&#34;));
// 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(&#34;Mytag&#34;))))
{
// ...
}
}
蓝图
添加标签
Unity
MyGameObject.tag = &#34;MyTag&#34;;Unreal
// Actors can have multiple tags
MyActor.Tags.AddUnique(TEXT(&#34;MyTag&#34;));蓝图
比较标签
Unity
if (MyGameObject.CompareTag(&#34;MyTag&#34;))
{
// ...
}
// Checks the tag on the GameObject it is attached to
if (MyComponent.CompareTag(&#34;MyTag&#34;))
{
// ...
}Unreal
// Checks if an Actor has this tag
if (MyActor->ActorHasTag(FName(TEXT(&#34;MyTag&#34;))))
{
// ...
}
// Checks if an ActorComponent has this tag
if (MyComponent->ComponentHasTag(FName(TEXT(&#34;MyTag&#34;))))
{
// ...
}蓝图
触发器
Unity
public class MyComponent : MonoBehaviour{
void Start()
{
collider.isTrigger = true;
}
void OnTriggerEnter(Collider Other)
{
// ...
}
void OnTriggerExit(Collider Other)
{
// ...
}}
Unreal
UCLASS()class AMyActor : public AActor{
GENERATED_BODY()
// My trigger component
UPROPERTY()
UPrimitiveComponent* Trigger;
AMyActor()
{
Trigger = CreateDefaultSubobject<USphereComponent>(TEXT(&#34;TriggerCollider&#34;));
// 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;
};
蓝图
刚体运动
Unity
public class MyComponent : MonoBehaviour
{
void Start()
{
rigidbody.isKinimatic = true;
rigidbody.velocity = transform.forward * 10.0f;
}
}
Unreal
在虚幻 4 中,碰撞组件和刚体组件是同一个组件,它的基类是 UPrimitiveComponent,
这个基类有很多不同的子类(USphereComponent,UCapsuleComponent 等)来配合不同的需求。
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
UPrimitiveComponent* PhysicalComp;
AMyActor()
{
PhysicalComp = CreateDefaultSubobject<USphereComponent>(TEXT(&#34;CollisionAndPhysics&#34;));
PhysicalComp->SetSimulatePhysics(false);
PhysicalComp->SetPhysicsLinearVelocity(GetActorRotation().Vector() * 100.0f);
}
};
输入事件
Unity
public class MyPlayerController : MonoBehaviour{
void Update()
{
if (Input.GetButtonDown(&#34;Fire&#34;))
{
// ...
}
float Horiz = Input.GetAxis(&#34;Horizontal&#34;);
float Vert = Input.GetAxis(&#34;Vertical&#34;);
// ...
}}
Unreal
UCLASS()class AMyPlayerController : public APlayerController{
GENERATED_BODY()
void SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction(&#34;Fire&#34;, IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent);
InputComponent->BindAxis(&#34;Horizontal&#34;, this, &AMyPlayerController::HandleHorizontalAxisInputEvent);
InputComponent->BindAxis(&#34;Vertical&#34;, this, &AMyPlayerController::HandleVerticalAxisInputEvent);
}
void HandleFireInputEvent();
void HandleHorizontalAxisInputEvent(float Value);
void HandleVerticalAxisInputEvent(float Value);};
蓝图
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|