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 AcollectableIterator(GetWorld()); AcollectableIterator; ++AcollectableIterator) {
              ++CollectablesCntToEat;
          }
  • Log:UE_LOG(LogTemp, Warning, TEXT("InitCollectablesCount = %d"), CollectablesCntToEat);

总结:监听输入调用函数,碰撞检测


Unreal Engine 4 For unity

CategoryUnityUE4
Gameplay TypesComponentComponent
 GameObjectActor, Pawn
 PrefabBlueprint Class
Editor UIHierarchy PanelWorld Outliner
 InspectorDetails Panel
 Project BrowserContent Browser
 Scene ViewViewport
MeshesMeshStatic Mesh
 Skinned MeshSkeletal Mesh
MaterialsShaderMaterial, Material Editor
 MaterialMaterial Instance
EffectsParticle EffectEffect, Particle, Cascade
 ShurikenCascade
Game UIUIUMG (Unreal Motion Graphics)
AnimationAnimationSkeletal Animation System
 MecanimPersona , Animation Blueprint
2DSprite EditorPaper2D
ProgrammingC#C++
 ScriptBlueprint
PhysicsRaycastLine Trace, Shape Trace
 Rigid BodyCollision, Physics
Runtime PlatformsiOS Player, Web PlayerPlatforms
  • 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(ExistingActor->GetClass(), SpawnLocation, SpawnRotation, SpawnParams);
      }
  • Unreal 子类化 UObject 类似于 Unity 子类化 ScriptableObject,即.asset资源文件,不依赖于任何Actor或者需要生成到世界的物体,其实就是static数据
    • unity:MyScriptableObject NewSO = ScriptableObject.CreateInstance();
    • ue4:UMyObject* NewObj = NewObject();
  • 类型转换
    • unity:C#无指针
      Collider collider = gameObject.GetComponent;
      SphereCollider sphereCollider = collider as SphereCollider;
      if (sphereCollider != null)
      {// ...
      }
    • UE4:使用Cast进行指针转换
      UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
      USphereComponent* SphereCollider = Cast(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 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();
    • UE4:UMyComponent* MyComp = MyActor->FindComponentByClass();
  • 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(nullptr, TEXT("MyNamedActor"));// Find Actors by type (needs a UWorld object) 
      for (TActorIterator It(GetWorld()); It; ++It)
      {AMyActor* MyActor = *It;// ...
      }// Find UObjects by type
      for (TObjectIterator It; It; ++it)
      {UMyObject* MyObject = *It;// ...
      }// Find Actors by tag (also works on ActorComponents, use TObjectIterator instead)
      for (TActorIterator 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 componentUPROPERTY()UPrimitiveComponent* Trigger;AMyActor(){Trigger = CreateDefaultSubobject(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 FrameworkUE4
    StringFString, FText
    ListTArray
    DictionaryTMap
    HashSetTSet


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部