磨刀不误砍柴工
回过来看课本,另外右边的书也值得一读
Packt Publishing - Mastering Unreal Engine 4.x Game Development另外该教程的讲的过快,而且照着敲也到不到教程上的效果,极度不适应,不推荐学习。相应的Udemy推出的Unreal Engine 4 Mastery - Create Multiplayer Games With Cpp讲的还不错,后期会针对性的做整理。
1、打印信息的手段,
UE_LOG(LogTemp,Warning,Text("%s"),*yourstr);
GLog->Log("your string");
GEngine->AddonScreenDebugMessage(-1,3.f,FColor::Red,FString::Printf(TEXT("add your str")));
其中GEngine智能提示会提示有问题
2、合理使用蓝图和C++的思想:
蓝图强在配置
C++强在逻辑
最常用的UPROPERTY()和UFUNCTION()内部传参
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Give a Titile") 蓝图和Editor能看能写
UPROPERTY(EditDefaultsOnly,Caegory="...") 蓝图类能看能写
UPROPERTY() 能看不能写
UFUNCTION(BlueprintCallable)
另外对应书本Chapter3,Unreal垃圾回收和UPROPERTY,
如果在程序中使用了TArray<>来组织成员的话,有必要把成员设为UPROPERTY的,
强制垃圾收集:GetWorld()->ForceGarbageCollection( true );
3、TIIPS
把该项勾选去掉,这样每次新建工程时不会使得应为VA的parse操作导致VS占用高。其他操作技巧在上一节有综述
4.20版本相对于4.14需要加许多许多头文件,
复制时,alt比ctrl+W好使 ,另外创建材质时的快捷键数字键加左键
4、前期的重点一:Actor和Component章节
03篇有吐槽过一次书上本章节的内容,究其原因,还是在UE4的版本号的问题上,现在处于巩固学习阶段,还要再拿过来看一看
第一点:instance实例化Actor和Destory销毁Actor
GetWorld()的使用,不允许C++指针指向不完整的类型,出现该问题需要添加头文件
#include "Engine/World.h"
想要SpawnActor需要添加头文件
#include "Animation/AnimInstance.h"
对于GetWorldTimerManager()需要添加#include "TimerManager.h"
.h文件
virtual void BeginPlay() override;
UPROPERTY(EditDefaultsOnly, Category = MyActor)
TSubclassOf<class AMyActor> MyActorClass;
UPROPERTY()
AMyActor* SpawnedActor;
void DestroyActor();
.cpp文件
void AUnrealCookBookGameModeBase::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("Actor Spawning"));
FTransform SpawnLocation;
MyActorClass = AMyActor::StaticClass();
if (MyActorClass != nullptr) {
UWorld* const World = GetWorld();
if (World != nullptr) {
SpawnedActor=World->SpawnActor<AMyActor>(MyActorClass, SpawnLocation);
}
}
FTimerHandle Timer;
GetWorldTimerManager().SetTimer
(Timer,this,&AUnrealCookBookGameModeBase::DestroyActor,10);
}
void AUnrealCookBookGameModeBase::DestroyActor()
{
if (SpawnedActor != nullptr)
{
SpawnedActor->Destroy();
}
}
注意:可以在Actor的BeginPlay中声明SetLifeSpan()用于设置Actor的生命周期,生命周期结束会自动调用Destroy函数
第二点:使得Actor实用化(1):为Actor添加组件,为组件添加assets,为组件添加层级关系
.h
UPROPERTY(EditDefaultsOnly,Category="Mesh")
UStaticMeshComponent* Mesh;
.cpp
Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
通过EditDefaultsOnly属性,使得蓝图子类能够添加assets,最快速,最合理的方案
另外还有使用ObjectFinder的方案,了解有这个东西就好,还是那句话,
蓝图强在可视化配置,C++强在内部逻辑
对于构建层级关系,AttachTo基本上不用了,改为
SetupAttachMent()
第三点:使得Actor实用化(2):通过继承,一般使用蓝图继承C++写好的Actor
第四点:ActorComponent和SceneComponent
前两种Componet都不能被渲染,但是可以具备自己的行为。其中SceneComponent比较常用,
SceneComponent具备自己的transform。可以作为Actor的产生点,可以利用自身的transform来控制子组件的transform
第五点:InventoryComponent可以用来构建背包系统,等到有完整实例用到再看看
UparticleSystemComponent的头文件:#include "Particles/ParticleSystemComponent.h"
5、设置Collision
了解代码设置的方法,熟悉蓝图设置的方法
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
RootComponent = MeshComp;
MeshComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
SphereComp = CreateDefaultSubobject<USphereComponent>("SphereComp");
SphereComp->SetupAttachment(RootComponent);
//可以在蓝图中设置
SphereComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
SphereComp->SetCollisionResponseToAllChannels(ECR_Ignore);
SphereComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
重写Overlap
void AFPSObjectiveActor::NotifyActorBeginOverlap(AActor * OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
PlayEffect();
}
特别的,当一个Actor中有多个碰撞体需要自己的Ovelap事件时,需要动态的绑定Overlap
声明:
UFUNCTION(BlueprintNativeEvent, Category = Collision)
void OverlapInnerHole(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep,
const FHitResult&SweepHit);
绑定:
InnerHole->OnComponentBeginOverlap.AddDynamic(this, &ABlackholeActor::OverlapInnerHole);
注意点,函数要加Implementation
void ABlackholeActor::OverlapInnerHole_Implementation(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepHit)
{
if (OtherActor) {
UE_LOG(LogTemp, Warning, TEXT("get there"));
OtherActor->Destroy();
}
}
另一种写法:
UFUNCTION()内容为空时,不需要加Implementation。
注意
绑定语句:
InnerHole->OnComponentBeginOverlap.AddDynamic(this, &ABlackholeActor::OverlapInnerHole);
只有写在BeginPlay中才会生效,
另外,双方都需要把generateOverlap设置为true
自然,蓝图下的设置更快速一些
6、自定义Event
使用蓝图继承的UFUNCTION
UFUNCTION(BlueprintImplementableEvent,Category="GameMode")
void OnMissionCompeleted(APawn* InstigatorPawn);
注意设置GameMode