UE4·究极·学习记录

UE4官方文档

2020/2/20

  • 周末需要整理一下,遗留的困惑点比较多,也可能在后续的学习中能够反映过来,之前的问题是可以解决的
  • 目前的计划:先学完官方文档,再回头去解答这些疑问

实现相机的切换,相机头文件,获取继承C++的蓝图的组件?

    UPROPERTY(EditAnywhere)
        AActor* CameraOne;

    UPROPERTY(EditAnywhere)
        AActor* CameraTwo;


    AActor *Player = UGameplayStatics::GetPlayerPawn(this, 0);
    UE_LOG(LogTemp, Warning, TEXT("~~~%s!!!!"), *(Player->GetName()));
    CameraOne = Player;
    //Player->GetComponentsByClass()
    TArray<UActorComponent*> ll(Player->GetComponentsByClass(UCameraComponent::StaticClass()));
    APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0);

// 立即切换到摄像机1。
    OurPlayerController->SetViewTarget(CameraOne);
// 平滑地混合到摄像机2。
    OurPlayerController->SetViewTargetWithBlend(CameraTwo, SmoothBlendTime);

和朋友探讨关于Lerp(待解决)

需要实践,这两天解决一下


TODO:明确哪个方向是“前进”,并记录玩家试图向此方向移动?

https://docs.unrealengine.com/zh-CN/Programming/Tutorials/FirstPersonShooter/2/3/index.html

void AFPSCharacter::MoveForward(float Value)
{
    // 明确哪个方向是“前进”,并记录玩家试图向此方向移动。
    //FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
    //AddMovementInput(Direction, Value);
    //UE_LOG(LogTemp, Warning, TEXT("Show Value %f"),Value);
    AddMovementInput(FVector(Value,0,0));
}

输入控制Input,如何确定Scale设置为-1,还是1?Turn?LookUp?WASD? (待解决)

MOUSEX(Turn):往右是正,往左是负

MOUSEY(LookUp):往上是正,往右是负

WSAD没问题的,和左手坐标系方向一样即可


Pitch(Y),Yaw(Z),Roll(X)

想象成一架飞机,飞机头对准X(红轴)

pitch:音调有高有低,即抬头或者低头,便是Y轴

Yaw:偏航,因此要绕z才能偏航

Roll:滚;绕X旋转


为什么跳跃要绑定两个函数??(待解决)

    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
    PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);

bpress会自动归零,暂时看不了源码。期待有天看源码的时候回顾这个问题。

来源:FPSProject


导入的模型或者添加的Mesh,为什么很多情况下要改Z(代码/蓝图内改)

https://docs.unrealengine.com/zh-CN/Programming/Tutorials/FirstPersonShooter/2/6/index.html

这个应该是美术建模的事情,程序只需要将这些作为可配置的数据,让策划去调就好了


一个默认相机?一个相机组件?它们之间是如何进行切换的?FPS项目中,相机是如何和人绑定的?


SetOwnerNosett(true)为何失效?重新建立BP就好了。。(整了两三个小时查不出BUG)

    // 拥有玩家无法看到普通(第三人称)身体模型。
    GetMesh()->SetOwnerNoSee(true);

暂时认为是引擎的BUG,不清晰具体的BUG原因


SetUpdatedComponent的作用?


UPROPERTY常用参数的总结

使用UPROPERTY暴露静态函数给蓝图有什么不同?


这是什么声明方法?Sub ,难道正常的类不能直接在蓝图内显示?

    // 生成的发射物类。
    UPROPERTY(EditDefaultsOnly, Category = Projectile)
        TSubclassOf<class AFPSProjectile> ProjectileClass;

AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);

TSubclassOf会更安全指定需要的类

 


        // 获取摄像机变换。
        FVector CameraLocation;
        FRotator CameraRotation;
        GetActorEyesViewPoint(CameraLocation, CameraRotation);

        // 将 MuzzleOffset 从摄像机空间变换到世界空间。
        FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
        FRotator MuzzleRotation = CameraRotation;


Mesh和collision都有物理碰撞?


    // 使用球体代表简单碰撞。
    CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
    CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile")); ???作用


蓝图如何调试?状态机如何切换?


控件类和控件实体   

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
        TSubclassOf<UUserWidget> StartingWidgetClass;

    /** 用作菜单的控件实例。*/
    UPROPERTY()
        UUserWidget* CurrentWidget;


UE4_UI

依赖模块添加→在类(游戏模式)中定义切换控件的代码(其中和蓝图交互的类需要使用Subclass)→widget BluePrint→可在对应的蓝图中onclick添加功能→在GameMode中设置widgetBP→构建二级菜单也比较容易


UE4碰撞交互是如何实现的?

 


https://docs.unrealengine.com/zh-CN/Programming/Tutorials/UMG/index.html

官网中使用这么一段代码进行UI交互,在GM中PlayController选择此BP。疑问,切成普通的pc也没问题?其扮演着怎么样的角色??

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}

定时器实现方法


常见的类继承关系


UObjects 和 Actors

Actors是由AActor派生而来,是所有能够放进世界场景的类实例

对象是由Uobject派生而来,因此Actors,乃至整个UE4所有的实例类都是对象

但是,一般称Actors派生出来的,为Actor,不会称呼为对象;一般对象指的是组件

总结:Actor和对象,对象是Actor的组件

 

UObjects扩展:

 


Pawn和Character

Pawn

Pawn is an Actor that can be an "agent" within the world. Pawns can be possessed by a Controller, they are set up to easily accept input, and they can do various and sundry other player-like things. Note that a Pawn is not assumed to be humanoid.

Character

Character is a humanoid-style Pawn. It comes with a CapsuleComponent for collision and a CharacterMovementComponent by default. It can do basic human-like movement, it can replicate movement smoothly across the network, and it has some animation-related functionality.

Pawn可以设置默认类,Character是进化版,自带胶囊碰撞组件和移动组件


Controller的AIController,PlyatController

 

Controller

Controller is an Actor that is responsible for directing a Pawn. They typically come in 2 flavors, AIController and PlayerController. A controller can "possess" a Pawn to take control of it.

PlayerController

PlayerController is the interface between the Pawn and the human player controlling it. The PlayerController essentially represents the human player's will.

AIController

An AIController is what it sounds like; a simulated "will" that can control a Pawn.


HUD和Camera

 

HUD

HUD is a "heads-up display", or the 2D on-screen display that is common in many games. Think health, ammo, gun reticle, etc. Each PlayerController typically has one of these.

Camera

The PlayerCameraManager is the "eyeball" for a player and manages how it behaves. Each PlayerController typically has one of these as well. For more, see the camera workflow page.

总结:HUD(heads-up-display)其实就是,一些 “少而精”,必须要让玩家知道的数据。比如FPS游戏中的血量,弹药


GameMode,GameState,PlayerState

GameMode

The concept of a "game" is split into 2 classes. The Game Mode and Game State is the definition of the game, including things like the game rules and win conditions. It only exists on the server. It typically should not have much data that changes during play, and it definitely should not have transient data that clients need to know about.

GameState

The GameState contains the state of the game, which could include things like the list of connected players, the score, where the pieces are in a chess game, or the list of what missions you have completed in an open world game. The GameState exists on the server and all clients and can replicate freely to keep all machines up to date.

PlayerState

PlayerState is the state of a participant in the game, such as a human player or a bot that is simulating a player. Non-player AI that exists as part of the game would not have a PlayerState. Example data that would be appropriate in a PlayerState include player name, score, in-match level for something like a MOBA, or whether the player is currently carrying the flag in a CTF game. PlayerStates for all players exist on all machines (unlike PlayerControllers) and can replicate freely to keep things in sync.

GameMode(游戏模式)包括游戏的规则,比如胜利条件,存在于服务器上

GameState(游戏状态)包括整个游戏数据同步的入口,服务器和客户端都有

PlayerState(玩家状态)玩家数据的保存,比如姓名,得分,等级


Actors

  • 创建
  • 组件
    • UActor组件(UActorComponent):非物理概念,场景中无具体位置
    • U场景组件(类 USceneComponent、UActorComponent 的子项):只是一个物理概念,支持基于位置的计算,但不需要几何表示。例如音频,弹簧臂。只有场景组件可以彼此附加,主要是SetupAttachment 和 AttachToComponent两种方法
    • UPrimitive组件(类 UPrimitiveComponent、USceneComponent 的子项):需要几何表示,例如Mesh,Sprite,碰撞体等等
  • Ticking(没太理解)
  • 生命周期(没太理解,只知道是最后销毁流程一样)
  • 复制
  • 销毁

Delegate单播和多播

  • 单播
  •     DECLARE_DELEGATE(FSingleDelagateWithNoParam);
        FSingleDelagateWithNoParam SingleDelagateWithNoParam;
    
        DECLARE_DELEGATE_OneParam(FSingleDelagateWithOneParam, FString);
        FSingleDelagateWithOneParam SingleDelagateWithOneParam;
        void Func1();
        void Func2(FString param);
    
    
        //绑定
        SingleDelagateWithNoParam.BindUObject(this, &AMyActor::Func1);
        SingleDelagateWithOneParam.BindUObject(this, &AMyActor::Func2);
    
        void AMyActor::Func1()
        {
            UE_LOG(LogTemp, Error, TEXT("AMyActor Func1"));
        }    
    
        void AMyActor::Func2(FString param)
        {
            UE_LOG(LogTemp, Error, TEXT("AMyActor Func2 param = %s"), *param);
        }
        
        //调用
        SingleDelagateWithNoParam.ExecuteIfBound();
                SingleDelagateWithOneParam.ExecuteIfBound(FString("PerformSingleDelagateWithOneParam"));
  • 多播
    //多播一个参数的委托
    DECLARE_MULTICAST_DELEGATE_OneParam(FMuitiDelagateWithOneParam, FString);
    FMuitiDelagateWithOneParam MuitiDelagateWithOneParam;
    
    //绑定
    MuitiDelagateWithOneParam.AddUObject(this, &ThisClass::f4);
    MuitiDelagateWithOneParam.AddUObject(this, &ThisClass::Func2);
    //执行多播
    MuitiDelagateWithOneParam.Broadcast(FString("PerformMultiDelagateWithOneParam"));

    void AMyActor::Func2(FString param)
    {
        UE_LOG(LogTemp, Error, TEXT("AMyActor Func2 param = %s"), *param);
    }

    void AMyActor::f4(FString param)
    {
        UE_LOG(LogTemp, Error, TEXT("duoboTestActor Func2 param = %s"), *param);
    }

FName,Fstring,FText

FString 类似于普通字符数组,
FName是放在全局字符串表里的,通常用来表示不可变的大小写不敏感的字符串
FText一般是表示处理本地化的字符串

范例

FName

FString

TestHUDString = TestHUDName.ToString();

FName

FText

TestHUDText = FText::FromName(TestHUDName);

FName -> FText 在一些情况下有效,但需注意 — FNames 内容不会从 FText 的“自动本地化”中受益。

FString

FName

TestHUDName = FName(*TestHUDString);

FString -> FName 不可靠。因为 FName 不区分大小写,所以转换存在损耗。

FString

FText

TestHUDText = FText::FromString(TestHUDString);

FString -> FText 在一些情况下有效,但需注意 — FString 内容不会从 FText 的“自动本地化”中受益。

FText

FString

TestHUDString = TestHUDText.ToString();

FText -> FString 不可靠。它在一些语言的转换中存在潜在损耗。

FText

FName

FText 到 FName 的转换不存在。但可先转换到 FString,再转换到 FName。

FText -> FString -> FName 不可靠。因为 FName 不区分大小写,所以转换存在损耗。


TArray的Add和Emplace

Add要临时变量,Emplace无临时变量


TMap,TSet

可用Append合并两个TMap


UE4行为树使用相关

  • BTT 代表行为树任务节点,BTD 代表行为树装饰器节点,BTS 代表行为树服务节点
  • Enemy_Character→Default Class设置默认AI控制类→创建黑板存储公共变量,Use Controller Rotation Yaw(Rotate to face BB entry)
  • 创建行为树→指定黑板资源→构建行为树布局架构→构建新的Tesk→先添加Event Receive Execute AI,自定义具体Tesk,通过公开变量/设置变量类型的方法在行为树中进行赋值。通过添加装饰器节点,设立if语句
  • Enemy_Controller中Event On Possess节点→Run Behaviour Tree设置BTAsset→添加AIPerception Component组件→该组件中添加AI视觉配置→On Target Perception Updated 做检测到人后的逻辑
  • Player_Controller 设置TAG=Player

UE4的行为树,是事件驱动架构

疑问:行为树中,什么时候会能选择公共变量?什么时候可以和黑板联系?

指定变量类型后


如何让一个BP_蓝图类事件失效?

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值