1.头文件缺失
Alt + G: 快速追根溯源
2.向Actor中添加组件
MyActor.h
Protected:
UPROPERTY(VisibleAnywhere,Category = "Component")
USphereComponent* SphereComponent;//.h中使用前向声明class可不重复include
MyActor.cpp
头文件使用Alt+O快速查找定义位置
#include "Components/SphereComponent.h"
构造函数中赋予组件属性:如
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
SphereComponent->SetupAttachment(RootComponent);//指认父子关系
SphereComponent->SetCollisionEnabled(ECollisionEnable::QueryOnly);//定义刚体属性
SphereComponent->SetCollisionResponseToAllChannels(ECR_Ignore);//定义碰撞通道
Rootcomponent = SphereComponent;//指定为新根组件
3.向Actor中添加函数
MyActor.h
Protected:
UFUNCTION(BlueprintCallable,Category = "Function")
void MyFunction();
MyActor.cpp
void AMyActor::MyFunction()
{
}
4.绑定Overlap代理
MyActor.h
UFUNCTION()
void OverlapSphere(UPrimitiveComponent* PrimitiveComponent, AActor* OtherActor, UPrimitiveComponent* PrimitiveComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
MyActor.cpp
构造函数中绑定
ShpereComponent->OnComponentBeginOverLap.AddDynamic(this,&AMyActor::OverlapSphere);//若绑定失败可在BeginPlay或PostInitializeComponents中绑定
函数体
void AMyActor::OverlapSphere(UPrimitiveComponent* PrimitiveComponent, AActor* OtherActor, UPrimitiveComponent* PrimitiveComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
}
5.遍历
TArray<UPrimitiveComponent*> OverlappingComponent;
SpherhComponent->GetOverlappingComponents(OverlappingComponent);
for (int32 i = 0; i < OverlappingComponent.Num(); i++)
{
UPrimitiveComponent* PrimitiveComp = OverlappingComponent[i];
if (PrimitiveComp && PrimitiveComp->IsSimulatingPhysics())
{
}
}
6.Debug球
DrawDebugSphere(GetWorld(), GetActorLocation(), 32.0f, 12, FColor::Red, false, 10.0f);
7.转化Gamemode;
AGameMode* GM = Cast<AGameMode>(GetWorld()->GetAuthGameMode());
8.Log
UE_LOG(LogTemp, Log, TEXT(" "));
GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, FString);
9.GetAllActorsOfClass
TArray<AActor*> ReturnedAtors;
UGameplayStatics::GetAllActorsOfClass(this, TheActorClass, ReturnedAtors);
if (ReturnedAtors.Num() > 0)
{
AActor* NewViewTarget = ReturnedAtors[0];
}
10.生成联级粒子
#include "Kismet/GameplayStatics.h"
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), EmitterEffect,GetActorLocation());
11.施加力
对Characer:
MyCharacter->LaunchCharacter(NewVelocity, true, true);
对UPrimitiveComponent:
OtherComp->AddImpulse(NewVelocity,NAME_None, true);
12.另一种代理
Actor.h
public:
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
Actor.cpp
void AActor::NotifyActorBeginOverlap(AActor* OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
ACharacter* MyCharacter = Cast<ACharacter>(OtherActor);
if (MyCharacter)
{
Destroy();
}
}
13.枚举
UENUM(BlueprintType)
enum class EState :uint8
{
State1,
State2.
State3
};
14.SimpleMoveToActor新API
#include "Blueprint/AIBlueprintHelperLibrary.h"
UAIBlueprintHelperLibrary::SimpleMoveToActor(GetController(), CurrentPatrolPoint);
add this in the Game.Build.cs PublicDependencyModuleNames:
"NavigationSystem"
15.服务器与客户端:
默认条件下,服务器与客户端,各自内容只在各自界面拥有
若要从服务器同步到客户端,所需同步内容的构造函数中加入
SetReplicates(true);
SetReplicateMovement(true);
具体函数改写为
if(role == ROLE_Authority)
{
原function();
}
但客户端无法传数据到服务器。
此时可将客户端命令移植到服务器,即利用服务器函数:
.h
UFUNTION(Server,Reliable,WithValidation)//Server:服务器函数,Reliable:确保连接,防丢包,WithValidation:验证可靠性
void ServerFunction();
.cpp(***.generated.h将自动为以下两个函数创建头文件)
void ***::ServerFunction_Implementation()
{
}
bool ***::ServerFunction_Validate()
{
return true;
}
void ***::MyFunction()
{
ServerFire();//原内容移至ServerFire()内实现;
}
若还需将服务器中值传递到客户端,则
.h
UPROPERTY(ReplicatedUsing=OnRep_MyState)
EState MyState;
UFUNCTION()
void OnRep_MyState();
.cpp
void ***::OnRep_MyState()
{
OnStateChange(MyState);
}
void ***::SetMyState(EState MyState)
{
MyState =NewState;
OnRep_MyState();
//OnStateChange(MyState);被代替
}
//配合ReplicateUsing宏 将变量复制到所以客户端
void ***::GetLifetimeReplicatedProps(TArray<FLifeTimeProperty>&OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(***,MyState);//该宏需要#include "Net/UnrealNetwork.h"
//DOREPLIFETIME_CONDITION(***,MyState,COND_OWNERONLY);//高级版,对于较差网络环境进行引擎优化,延迟期间自动模拟数据
}
客户端上gamemode为空,因此gamemode内容需改写入GameStateBase
-
创建组播函数;(gamemode为空不合适)
-
Game State Base;(与gamemode类似,但能复制函数、变量,用做容器,装入gamemode中需要Rep的东西)
GameState.h
public:
UFUNCTION(NetMulticast,Reliable)
void MulticastOnMissionComplete(APawn* InstigatorPawn,bool bIsMissionSuccess);//函数被服务器调用时,会发送至所以client以在client上运行该函数,包括服务器。
GameState.cpp
void AGameState::MulticastOnMissionComplete(APawn* InstigatorPawn,bool bIsMissionSuccess)
{
for (FConstPawnIterator It = GetWorld()->GetPawnIterator();It;It++)//迭代器源于World.h
{
APawn* Pawn = It->Get();
if(Pawn&&Pawn->IsLocallyControlled())
{
Pawn->DisableInput(nullptr);
}
}
}
GameMode.cpp
#include "GameState.h"
构造函数增加:
GameStateClass =AGameState::StaticClass();
原函数处替换为:
AGameState* GS=GetGameState<AGameState>();
if(GS)
{
GS->MulticastOnMissionComplete(InstigatorPawn,bIsMissionSuccess);
-
客户端gamemode中被执行内容转移至Player Controller
Player Controller在服务器和拥有该控制器的客户端上均存在。与Pawn不同,服务器有几个Pawn,客户端亦有几个pawn。Player Controller客户端各存一,服务器存数量与客户端同。
PlayerController.h
public:
UFUNCTION(BlueprintImplementableEvent,Categoty="PlayerCntroller")
void OnMissionCompleted(APawn* InstigatorPawn,bool bIsMissionSuccess)
GameState.cpp
#include "PlayerController.h"
void AGameState::MulticastOnMissionComplete(APawn* InstigatorPawn,bool bIsMissionSuccess)
{
/*
for (FConstPawnIterator It = GetWorld()->GetPawnIterator();It;It++)//迭代器源于World.h
{
APawn* Pawn = It->Get();
if(Pawn&&Pawn->IsLocallyControlled())
{
Pawn->DisableInput(nullptr);
}
}
*/
for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator();It;It++)//组播函数中新增迭代器
{
APlayerController* PC=Cast<AplayerController>(It->Get());
if(PC&&PC->IsLocallyControlled())
{
PC->OnMissionCompleted(InstigatorPawn,bIsMissionSuccess);
APawn* Mypawn =PC->GetPawn();
if(MyPawn)
{
MyPawn->DisableInput(PC);
}
}
}
}
IsLocalController表示我们是否是该计算机上的实际播放器。该服务器具有每个玩家的所有玩家控制器,但其中只有一个是本地控制器(除非它是专用服务器,这意味着该服务器上有0个本地控制器)