【GAD翻译馆】实现带有参数的动作绑定

发表于2017-10-24
评论1 2.1k浏览

翻译:王成林(麦克斯韦的麦斯威尔 ) 审校:黄秀美(厚德载物) 

在这篇文章中我们将建立不同的含有参数的动作绑定。另外,我们将学习到一种能在游戏运行时改变我们参数内容的方法。

本篇教程假设你熟悉UE4的代理。如果你忘记了,或者不知道如何使用它们请查阅这篇文章


建立我们的输入

创建任何一个C 项目模板然后添加以下动作绑定:

然后打开你的角色的头文件并添加以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private:
 
    /*A simple function which prints its parameter*/
    UFUNCTION()
    void OneParamFunction(int32 Param);
 
    /*A simple function which prints its parameters*/
    UFUNCTION()
    void TwoParamsFunction(int32 IntParam, float FloatParam);
 
    /*A function that changes the our parameters and replaces a hardcoded action bind*/
    void ChangeParameters();
 
 
protected:
 
    /*The parameter which we will pass into the OneParamFunction*/
    UPROPERTY(EditDefaultsOnly, Category=InputsWithParameters)
    int32 FirstIntParam;
 
    /*The int parameter that will get passed into the TwoParamsFunction*/
    UPROPERTY(EditDefaultsOnly, Category = InputsWithParameters)
    int32 SecondIntParam;
 
    /*The float parameter that will get passed into the TwoParamsFunction*/
    UPROPERTY(EditDefaultsOnly, Category = InputsWithParameters)
    float FloatParam;

然后在你的角色的源文件中添加以下OneParamFunctionTwoParamsFunction的实现:

1
2
3
4
5
6
7
8
9
10
11
void AInputsWithParametersCharacter::OneParamFunction(int32 Param)
{
    //printing the given parameter
    GLog->Log("The parameter you've entered:" FString::FromInt(Param));
}
 
void AInputsWithParametersCharacter::TwoParamsFunction(int32 IntParam, float FloatParam)
{
    //printing the given parameters
    GLog->Log("Input with two parameters. First param: " FString::FromInt(IntParam) " Second param: " FString::SanitizeFloat(FloatParam));
}

在继续之前我们先退一步解释一下输入功能在UE4C 中的工作原理。

你的角色包含一个名为InputComponent的组件(至少在模板项目中是这样),它负责检查是否存在一个有效的输入设备(例如游戏手柄/键盘/鼠标等)。另外,该组件包含某个特定角色所有可用的输入。

当前在虚幻引擎中有两种绑定:

·       轴绑定

·       动作绑定

主要区别在于轴绑定在每一帧中都会执行,而动作绑定在特定情况发生时(例如玩家双击鼠标,或者按下一个按键)执行。

在这篇文章中我们将集中探讨动作绑定。

为了声明一个动作绑定你需要:

·       将我们使用编辑器指定的动作映射和一个输入事件(例如按下一个按键)关联起来

·       声明当输入事件发生时哪些函数会触发

在第一人称C 项目模板中你可以在SetupPlayerInputComponent中找到以下代码:

1
2
     
InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);

这是添加动作绑定的一个标准方法。在这篇文章中,我们将探索一种不同的方法来添加动作绑定。

事实上,在C 中一个动作绑定就是一个包含有用信息的结构体,例如:

·       动作代理(我将稍微解释一下这是什么)

·       动作名称(这是你的绑定的实际名称——它必须和你在编辑器中指定的动作绑定相关联)

·       一个关键事件(描述了输入类型。在我们的例子中我们将使用IE_Pressed关键事件,它描述了一次按下键盘按键的动作)

动作代理其实就是一个句柄,当我们拥有一个它指向将要执行的函数  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//First param action binding...
 
//Declaring an action binding
FInputActionBinding ActionBindingOneParam;
//Specifying the associated action name and the key event
ActionBindingOneParam.ActionName = FName("OneParamInput");
ActionBindingOneParam.KeyEvent = IE_Pressed;
 
//Creating a handler which binds to the given function with a fixed int parameter
FInputActionHandlerSignature OneParamActionHandler;
 
//Binding the function named OneParamFunction to our handler
//The first parameter (this) means that the handler will search the given function inside the current class
OneParamActionHandler.BindUFunction(this, FName("OneParamFunction"), FirstIntParam);
 
//Associating our action binding with our new delegate
ActionBindingOneParam.ActionDelegate = OneParamActionHandler;
 
//Performing the actual binding...
InputComponent->AddActionBinding(ActionBindingOneParam);
 
//Second Param - identical code to the first param action bind but with a different function and parameters!
 
FInputActionBinding ActionBindingTwoParams;
 
ActionBindingTwoParams.ActionName = FName("TwoParamsInput");
ActionBindingTwoParams.KeyEvent = IE_Pressed;
 
FInputActionHandlerSignature TwoParamsActionHandler;
TwoParamsActionHandler.BindUFunction(this, FName("TwoParamsFunction"), SecondIntParam, FloatParam);
 
ActionBindingTwoParams.ActionDelegate = TwoParamsActionHandler;
 
InputComponent->AddActionBinding(ActionBindingTwoParams);
 
//Binding the change parameters function
InputComponent->BindAction("ChangeParameters", IE_Pressed, this, &AInputsWithParametersCharacter::ChangeParameters);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void AInputsWithParametersCharacter::ChangeParameters()
{
    //Choosing a different random param!
    SecondIntParam = FMath::Rand();
 
    FloatParam = FMath::RandRange(-1000.f, 1000.f);
 
    GLog->Log("Changed params: " FString::FromInt(SecondIntParam) " " FString::SanitizeFloat(FloatParam));
 
 
    //Search all the action bindings until we find the binding with the two parameters
    for (int32 i = 0; i < InputComponent->GetNumActionBindings() - 1; i )
    {
        if (InputComponent->GetActionBinding(i).ActionName.IsEqual("TwoParamsInput"))
        {
            //Declaring a new binding with the same action name and key event as the TwoParamsInput initial action binding
            FInputActionBinding NewActionBinding;
            NewActionBinding.ActionName = FName("TwoParamsInput");
            NewActionBinding.KeyEvent = IE_Pressed;
 
            //Creating an identical handler with the same bind as before
            FInputActionHandlerSignature NewDelegate;
            //However, this bind contains our new values!
            NewDelegate.BindUFunction(this, FName("TwoParamsFunction"), SecondIntParam, FloatParam);
 
            //Associating our handler with our action binding
            NewActionBinding.ActionDelegate = NewDelegate;
             
            //The GetActionBinding function returns the action binding by reference
            //This means that in the following line we replace the old binding (which contains old values)
            //with a new binding (which contains the updated values)
            InputComponent->GetActionBinding(i) = NewActionBinding;
 
            GLog->Log("changed the action binding");
        }
    }
}


【版权声明】

原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引