Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

ue4-笔记(持续更新ing...)

$
0
0

学习ue4的一些笔记记录
之前也有写过点,这里做个汇总,顺便补上漏记得东东,持续更新……
这里以 MyTest 项目名说明。


视频教程集合


官方编码标准


包含头文件的一些规则

  • 包含引擎类。如果需要扩展或使用引擎类,都在项目模块的预编译头文件 MyTest.h 中包含进来。自己创建的头文件都会包含这个 MyTest.h 头文件。

    
    #ifndef __MYTEST_H__
    
    
    #define __MYTEST_H__
    
    
    
    #include "EngineMinimal.h"
    
    
    #include "EngineGlobals.h"
    
    
    #include "Engine/Engine.h"
    
    
    #include "GameFramework/GameMode.h"
    
    
  • 包含自己创建的类。

    • 头文件 MyGameMode.h 中的自动生成的头文件 MyGameMode.generated.h 一定要放在最后包含

      
      #pragma once
      
      //#include "MyUtil.h"
      
      #include "MyGameMode.generated.h"
      
      
      UCLASS()
      class MYTEST_API AMyGameMode : public AGameMode
    • cpp文件 中一定要先包含预编译头文件 MyTest.h 和对应的头文件 MyGameMode.h,在包含其他头文件

      
      #include "MyTest.h"
      
      
      #include "MyGameMode.h"
      
      
      //#include "MyUtil.h"
      AMyGameMode::AMyGameMode() : Super()

配置默认的GameMode、GameInstance、Map等

  • Edit->Project Settings
    这里写图片描述
  • 会保存在 MyTest\Config\DefaultEngine.ini 文件中

多人游戏的关卡切换

官网教程


暴露给蓝图的规则

  • class类,在类的头上加上标记 BlueprintableBlueprintable

    UCLASS(Blueprintable, BlueprintType)
    class MYTEST_API UCoolDownComp : public UActorComponent
    • Blueprintable:可在新建一个蓝图类时继承c++类,显示在可继承列表中
    • BlueprintType:这个c++类可作为一个类型选择,显示在类型选择中
  • enum枚举,加上 BlueprintType 即可,一般不用来继承使用

    UENUM(BlueprintType)
    enum class CharState : uint8 //动画状态
    {

SceneComponent


启动游戏添加参数解析


创建 .uproject的 vs2013解决方案 xxx.sln文件

  • 创建工程的时候如果创建的是蓝图工程,可以通过两种方式创建vs工程
    1. 直接在编辑器中创建
    2. 命令行创建
      • 其实就是使用ubt工具+参数
        这里写图片描述
        这里写图片描述
      • 先cd到这个目录中,再使用命令生成vs2013的解决方案,默认是2015,没有安装的话会报错

        I:\UnrealEngine_4.10\Engine\Binaries\DotNET>UnrealBuildTool.exe -projectfiles -project="F:/workplace_ue4/ShooterGame_4.10/data/ShooterGame.uproject" -game -rocket -progress -2013

        这里写图片描述
      • vs工程就蹦出了
        这里写图片描述

C++动态加载即替换character的 skeletal mesh 和 anim blueprint

  • 两者必须在同一帧同时替换,因为一个模型对应一个动画

    bool UMyBpFuncLib::TestChangeCharAnimInstance(AMyChar* _myChar, FString _pathMesh, FString _pathAnim)
    {
        FStreamableManager* stream = new FStreamableManager();
        FStringAssetReference ref1(*_pathMesh);
        USkeletalMesh* TmpMesh = Cast<USkeletalMesh>(stream->SynchronousLoad(ref1));
        _myChar->GetMesh()->SetSkeletalMesh(TmpMesh);
    
        FStringAssetReference ref2(*_pathAnim);
        UAnimBlueprint* TmpMeshAnim = Cast<UAnimBlueprint>(stream->SynchronousLoad(ref2));
        _myChar->GetMesh()->SetAnimInstanceClass((UClass*)TmpMeshAnim->GetAnimBlueprintGeneratedClass());
        delete stream;
        return true;
    }
  • 真相

C++中加载一个蓝图类

  • _path = /Game/TopDownCPP/Blueprints/MyChar/MyCharBP

    UObject* AMyText::TestLoadBPObject(FString _path)
    {
        auto cls = StaticLoadObject(UObject::StaticClass(), nullptr, *_path);
        if (!cls)
        {
            //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Failed to load UClass "));
            return nullptr;
        }
        else
        {
            //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("UClass LOADED!!!!"));
            UBlueprint* bp = Cast<UBlueprint>(cls);
            if (!bp)
            {
                //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Failed to load UClass 2  "));
            }
            else
            {
                //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("UClass LOADED!!!! 2 " + bp->GetName()));
                TSubclassOf<class UObject> MyItemBlueprint;
                MyItemBlueprint = (UClass*)bp->GeneratedClass;
                UWorld* const World = GWorld->GetWorld();
                if (World){
                    FActorSpawnParameters SpawnParams;
                    //SpawnParams.Instigator = this;
    
                    UObject* DroppedItem = World->SpawnActor<UObject>(MyItemBlueprint, GetActorLocation(), { 0, 0, 0 }, SpawnParams);
                }
            }
            return cls;
        }
    }

BlueprintFunctionLibrary中指定默认参数

这里写图片描述
这里写图片描述
这里写图片描述
- 转换WorldContextObject为Uworld

  • 在蓝图中调用时就不需要传Uobject了, 只需要传int32
    这里写图片描述
    这里写图片描述

C++动态调用蓝图方法CallFunctionByNameWithArguments,根据str调用到蓝图中对应得方法(没有Ufunction好用)

(只能传递string 和 int 两种类型参数)
这里写图片描述

这里写图片描述

  • 第一个是蓝图的方法名,
  • 第二个fstring类型的参数,必须用“”双引号包起来,不然会报找不到string value property的错
  • 第三个参数是int32类型的参数
  • 全部用空格隔开

CallFunctionByNameWithArgumentsUobject 的方法,所以只要是继承自Uobject的类都可以使用

这里写图片描述

  • Char中的蓝图方法testBpFunc,准备被c++中调用的
    这里写图片描述

继承FTickableGameObject,实现每帧Tick

  • 需要重写几个纯虚函数

    UCLASS()
    class UCoolDownMgr : public UObject, public FTickableGameObject, public USingleton<UCoolDownMgr>
    {
        GENERATED_BODY()
    public:
        // Sets default values for this character's properties
        UCoolDownMgr();
        virtual ~UCoolDownMgr();
    
        // Begin FTickableGameObject Interface.
        virtual void Tick(float DeltaTime) override;
        virtual bool IsTickable() const override;
        virtual TStatId GetStatId() const override;
        // End FTickableGameObject Interface.
    };

国际化:任何要显示到屏幕上的文字都要用FText,因为它带有国际化功能

void UMyBpFuncLib::TestNSLocatext(int32 _dayCount, int32 _hp)
{
    FFormatNamedArguments Args; //命名式参数
    Args.Add("DayCount", _dayCount);
    Args.Add("Hp", _hp);
    FText txt1 = FText::Format(NSLOCTEXT("Solus", "Day", "--- Day1 {DayCount}"), Args);
    FText txt2 = FText::Format(NSLOCTEXT("Solus", "HP", "--- HP1 {Hp}"), Args);

    FFormatOrderedArguments Args2; //索引式参数
    Args2.Add(_dayCount);
    Args2.Add(_hp);
    FText txt3 = FText::Format(NSLOCTEXT("Solus", "Day", "--- Day2 {0}"), Args2);
    FText txt4 = FText::Format(NSLOCTEXT("Solus", "HP", "--- HP2 {1}"), Args2);


    FString str = txt1.ToString()
        + TEXT("\n")
        + txt2.ToString()
        + TEXT("\n")
        + txt3.ToString()
        + TEXT("\n")
        + txt4.ToString();
        GEngine->AddOnScreenDebugMessage(0, 5.0f, FColor::Green, str);
}

整形暴露给蓝图只能使用 int32

  • 否则报错:error code: OtherCompilationError (5)

std::string 和 TCHAR* 之间的互转

#define TCHAR_TO_ANSIANSI_TO_TCHAR(str) (TCHAR*)StringCast<TCHAR>(static_cast<const ANSICHAR*>(str)).Get()
#define TCHAR_TO_UTF8(str) (ANSICHAR*)FTCHARToUTF8((const TCHAR*)str).Get()
#define UTF8_TO_TCHAR(str) (TCHAR*)FUTF8ToTCHAR((const ANSICHAR*)str).Get()

Blueprint中用代码spawn的actor使用自定义的AIController

  • 虽然可以在编辑器中默认设置中设置指定的自定义AIController,但这样只对拖进场景的Actor生效,对Blueprint调用spawn actor生产的actor无效,需要用代码生产自定的AIController,再指定哪个actor运行
    这里写图片描述

C++声明方法但不实现,蓝图负责实现(C++调用Blueprint的另一种实现),已经形参引用或const传递

/// This function is designed to be overridden by a blueprint. Do not provide a body for this function in C++; 不要给BlueprintImplementableEvent声明的方法提供c++方法实现,由蓝图实现

  1. C++定义,并声明 BlueprintImplementableEvent

        UFUNCTION(BlueprintImplementableEvent)
            void CountDownHasFinished();
  2. 蓝图实现:
    这里写图片描述

    这里写图片描述


C++ 与 蓝图 交互的 参数传递 及 多返回值

  • 如果形参是fstring,就必须是引用类型,一般不需要蓝图修改的都加const,需要修改的就加引用声明

    • 不需要蓝图修改
      cpp
      UFUNCTION(BlueprintImplementableEvent, Category = "MyBehavior")
      void OnDeath(const FString& _str, int32 _num);
    • 需要蓝图修改
      cpp
      UFUNCTION(BlueprintImplementableEvent, Category = "MyBehavior")
      void OnDeath(UPARAM(ref) FString& _str, int32 _num);
  • c++ 返回 多个值 给蓝图

    • 如果需要返回多个值,就不需要再c++中 return,使用 形参引用 就行。

      UFUNCTION(BlueprintCallable, Category = "UMyGameInstance")
          void MyMerge(AActor* PlayerPawn, TArray<USkeletalMesh*> SrcMeshList, AActor*& retActor, USkeletalMeshComponent*& retSkeletalComp);

      这里写图片描述


C++ 声明方法且实现,蓝图重写

  • /// This function is designed to be overridden by a blueprint, but also has a native implementation.
    /// Provide a body named [FunctionName]_Implementation instead of [FunctionName]; the autogenerated
    /// code will include a thunk that calls the implementation method when necessary.

    BlueprintNativeEvent,

    1. C++声明、实现

          UFUNCTION(BlueprintNativeEvent)
              void CountDownHasFinished();
          virtual void CountDownHasFinished_Implementation();
      
          void AMyText::CountDownHasFinished_Implementation()
          { ... }
    2. 蓝图实现重写
      这里写图片描述

    这里写图片描述


添加一个时间轴

  • 右键添加
    这里写图片描述

  • 编辑时间轴,双击MovementTimeline
    这里写图片描述

  • 平滑曲线
    这里写图片描述

  • 判断时间轴是否播放中
    这里写图片描述

- 利用时间轴做线性插值

蓝图接口的使用

  1. 新建一接口蓝图
    这里写图片描述

  2. 添加接口
    这里写图片描述

  3. 使用接口
    这里写图片描述


自定一个继承自ActorCompoment的组件,暴露在编辑器中

UCLASS(ClassGroup="MyCustom", meta=(BlueprintSpawnableComponent))
class UMyComp : public UActorComponent
{ ... };

只是用来做展示的Mesh,需要取消掉碰撞,不然会和其他Actor产生碰撞

这里写图片描述 -> 这里写图片描述


子弹每帧修改朝向,速度需要保持不变,方向需要归一化

void AMyBullet::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);

    //每帧修正到目标的飞行方向
    if (mTargetActor != nullptr)
    {
        FVector targetLoc = mTargetActor->GetActorLocation();
        if ( mLastTargetLoc != targetLoc)
        {
            FVector bulletLoc = GetActorLocation();
            FRotator rota = UKismetMathLibrary::FindLookAtRotation(bulletLoc, targetLoc);
            SetActorRotation(rota);
            MovementComp->Velocity = MovementComp->InitialSpeed * (targetLoc - bulletLoc).GetSafeNormal(); //子弹移动方向归一化,然后再乘以速度就成了速度矢量
            mLastTargetLoc = targetLoc;
        }
    }
}

行为树中的几种节点(Service、Decorator、Task)的初始化方法

  • 重写父类这两个方法

    virtual void OnInstanceCreated(UBehaviorTreeComponent& OwnerComp) override;
    virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp) override;
  • 因为有些数据不能再类的构造方法中初始化,涉及到引擎必须用引擎提供的 初始化方法,如:

    void UBTDecorateMyBase::OnInstanceCreated(UBehaviorTreeComponent& OwnerComp)
    {
        //初始化成员都放在这个方法
        if (!mOwnerChar)
            mOwnerChar = GetMyChar();
    
        if (!mBTComp)
            mBTComp = &OwnerComp;
    }

行为树中的几种节点(Service、Decorator、Task)的每帧tick

  • 需要打开父类UBTAuxiliaryNode的开关,构造里默认设置为false

    /** if set, OnTick will be used */
    uint8 bNotifyTick : 1;
  • 需要在子类中的构造中把这个开关打开

    UBTDecorateMyBase::UBTDecorateMyBase()
        : Super()
    {
        //设置tick 开关
        bNotifyTick = true;
    }

模型导入

  1. 先导入骨骼,导入时可以选择是否导入 材质、贴图
  2. 在导入所有动画,导入时选择1中导入的骨骼

控制台执行 关卡事件

  1. 关卡中新建个自定义时间 moveCube
    这里写图片描述

  2. 控制执行这个事件,输入命令:ce moveCube

    • ce 的意思应该是 call event
      这里写图片描述

设置 Windows 打包的分辨率,及相关设置

作者:yangxuan0261 发表于2017/2/25 15:04:59 原文链接
阅读:32 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>