zoukankan      html  css  js  c++  java
  • 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要学习的内容太多了,时间真是不够用啊...

  • 相关阅读:
    P4675 [BalticOI 2016 day1]Park 题解
    AT4432 [ARC103B] Robot Arms 题解
    P4357 [CQOI2016]K 远点对 题解
    P2163 [SHOI2007]园丁的烦恼 题解
    P3157 [CQOI2011]动态逆序对 题解
    bzoj 1568. [JSOI2008]Blue Mary开公司
    P3120 [USACO15FEB]Cow Hopscotch G 题解
    CSP-S 2021 题解
    Maven简介与安装
    java 基本程序设计结构 一
  • 原文地址:https://www.cnblogs.com/vesnica/p/3632693.html
Copyright © 2011-2022 走看看