• UE4学习笔记_07


    上一篇讨论了如何在C++中创建可被Blueprint调用的全局函数。如果想实现只供某一个类使用的Blueprint函数,方式是类似的,只是不要再继承UBlueprintFunctionLibrary类,同时函数也无需再声明成static即可。

    虽然能够在Blueprint中调用一个C++实现的方法是很不错,但在实际中我们还会需要其他的交互方式,比如由C++代码去触发一系列的Blueprint动作,以及让Blueprint能够和C++类的某些属性变量直接进行交互。

    我们先来看看如何将C++类中的某些属性变量暴露出去,让Blueprint(或Editor)能够看见、读或写这些变量,从而实现和C++的通信。

    其实非常简单:只需要在C++类的头文件中这样声明一下就可以了:

    1 /* What's the Player's current musical skill level? */
    2     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerMusicSkill")
    3     int32 MusicSkillLevel;

    只需要使用UPROPERTY宏,在加上一些枚举属性,就可以让一个变量以开发者希望的方式暴露给Blueprint,其中:

    • EditAnywhere表示该变量可以在Editor中任意进行修改,而VisibleAnywhere则表示Editor中只能看、但无法修改这个变量,还有几个其他的可选项供选择,可以自行研究代码
    • BlueprintReadWrite表示该变量可以在Blueprint中读或写,BlueprintReadOnly则表示在Blueprint中只能读
    • Category表示在Editor和Blueprint列表中这个变量归到那一分类,这主要是一个方便开发者寻找的功能,没有其他特别作用
    • 头部的注释不仅仅是代码中的注释,它也会作为这个参数的帮助提示显示在Editor的界面上

    上面的代码在编译后,只需要在Editor中基于这个类创建一个Blueprint,然后就能够在它的Default属性界面看到下面的内容:

    相当不错,而且简单。下面再来看看关键的:如何让C++去触发Blueprint,同时给Blueprint传递信息?

    其实也非常简单,主要是使用UFUNTION+BlueprintImplementableEvent属性:

    1 UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "Music skill is GOOD"))
    2         virtual void MusicSkillGood(int32 CurrentSkill);

    其中:

    • BlueprintImplementableEvent表示下面定义的函数会触发Blueprint里的一个事件,但事件触发后如何处理则由Blueprint自行实现,C++代码不负责,它只负责在适当的时候调用下面的函数并传递参数数据而已
    • meta相关内容和Category类似,主要是给用户提供一个更容易分辨的信息。在这里这个自定义事件在Blueprint中就会被显示为“Music skill is GOOD”,没有其他作用
    • MusicSkillGood就是用来在C++中触发Blueprint事件的函数,它一定要被定义为虚函数,而且返回值一定要为void,因为这个函数的实现不由C++来做,它只是提供一个触发的手段,且所有的数据都通过其参数传递给Blueprint

    完整的类代码如下:

    MyPlayerController.h:

     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #pragma once
     4 
     5 #include "GameFramework/PlayerController.h"
     6 #include "MyPlayerController.generated.h"
     7 
     8 /**
     9  * 
    10  */
    11 UCLASS()
    12 class AMyPlayerController : public APlayerController
    13 {
    14     GENERATED_UCLASS_BODY()
    15     
    16     /* What's the Player's current musical skill level? */
    17     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerMusicSkill")
    18     int32 MusicSkillLevel;
    19 
    20     UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "Music skill is GOOD"))
    21         virtual void MusicSkillGood(int32 CurrentSkill);
    22 
    23     virtual void PlayerTick(float DeltaTime) OVERRIDE;
    24 };

    MyPlayerController.cpp:

     1 // Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
     2 
     3 #include "HelloWorld.h"
     4 #include "MyPlayerController.h"
     5 
     6 
     7 AMyPlayerController::AMyPlayerController(const class FPostConstructInitializeProperties& PCIP)
     8     : Super(PCIP)
     9 {
    10 
    11 }
    12 
    13 void AMyPlayerController::PlayerTick(float DeltaTime) {
    14     Super::PlayerTick(DeltaTime);
    15 
    16     if (MusicSkillLevel > 50)
    17     {
    18         MusicSkillGood(MusicSkillLevel);
    19     }
    20 }

    上面代码的主要逻辑就是在每个Tick检查当前类实例的MusicSkillLevel变量值是否大于50,如果是,则对Blueprint触发MusicSkillGood事件,并将MusicSkillLevel的值传递过去。最终在Blueprint中可以这样用:

    这个Blueprint的逻辑就是:

    • 每当用户按M键,就将MusicSkillLevel变量的值加1
    • 而如前所述,C++代码会在每个Tick检查MusicSkillLevel的值是否大于50,如果大于50了,那么就会在每个Tick都触发一次MusicSkillGood事件(由于meta的设置,这个事件被显示成“Music Skill is GOOD”)
    • 当用户按了足够多的M键导致MusicSkillLevel变量的值超过50时,在游戏中就能看到MusicSkillLevel的当前值在刷屏了

    到此为止,Blueprint已经和C++代码实现了完全的交互:Blueprint能够主动调用C++中的函数,C++也能主动触发Blueprint的事件,而且双方还能通过暴露的变量进行交互。这样一来,整个游戏的底层平台模块完全可以用C++实现,然后给上层的Blueprint提供调用接口,由Blueprint来利用、组织这些模块来实现上层的完整游戏逻辑。这种结合方式既保留了C++的性能优势,又充分利用了Blueprint的易用性和灵活性来让游戏开发保持快速地迭代。这应该就是UE4所推崇的最佳开发模式。

    UE4要学习的内容太多了,时间真是不够用啊...

  • 相关阅读:
    Codeforces Round #344 (Div. 2) C. Report 其他
    Codeforces Round #344 (Div. 2) B. Print Check 水题
    Codeforces Round #344 (Div. 2) A. Interview 水题
    8VC Venture Cup 2016
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂
    CDOJ 1279 班委选举 每周一题 div2 暴力
    每周算法讲堂 快速幂
    8VC Venture Cup 2016
    Educational Codeforces Round 9 F. Magic Matrix 最小生成树
  • 原文地址:https://www.cnblogs.com/vesnica/p/3632693.html
Copyright © 2020-2023  润新知