学习资源: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;
}
- CollectablesCntToEat = 0;
- Log:UE_LOG(LogTemp, Warning, TEXT("InitCollectablesCount = %d"), CollectablesCntToEat);
总结:监听输入调用函数,碰撞检测
Unreal Engine 4 For unity
Category | Unity | UE4 |
---|---|---|
Gameplay Types | Component | Component |
GameObject | Actor, Pawn | |
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 | Material, Material 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) {// ... }
- unity:C#无指针
- 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 componentsMyActor->SetActorHiddenInGame(true);// Disables collision componentsMyActor->SetActorEnableCollision(false);// Stops the Actor from tickingMyActor->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")))){// ...} }
- unity:
- 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 componentUPROPERTY()UPrimitiveComponent* Trigger;AMyActor(){Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("TriggerCollider"));// Both colliders need to have this set to true for events to fireTrigger.bGenerateOverlapEvents = true;// Set the collision mode for the collider// This mode will only enable the collider for raycasts, sweeps, and overlapsTrigger.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 FString, FText List TArray Dictionary TMap HashSet TSet