|
Previous Step
Next Step
Programming Tutorials Home
This section of the tutorial involves using Blueprints to extend the functionality of C++ classes. However, it is only intended as a test that our C++ code was written correctly, not as a Blueprint tutorial. For a proper introduction to Blueprints, we recommend the 蓝图快速入门指南.
To change the behavior of our ACountdown instance, called "Countdown1", in the editor, we must first make an editable Blueprint version of it. To do this, we can select it from the World Outliner and click the Blueprint/Add Script button in the Details Panel.
From there, we can provide a path and name for the Blueprint asset that will contain our modified ACountdown class.
This will create a new asset that represents a Blueprint version of "Countdown1". It will also replace "Countdown1" with an instance of this new Blueprint, so that changes we make to the Blueprint will affect "Countdown1" in the game.
The Unreal Editor will automatically take us to our new asset in the Content Browser, and we can right-click it and choose "Edit..." to modify its Blueprint Graph, Component hierararchy, and Default Values.
Functions and events can be found in the Event Graph tab, so we'll select that first.
Then, by righting-click anywhere in the Event Graph window, we can add our CountdownHasFinished function as an event node to define its behavior.
We can now add any additional functionality we would like by left-clicking and dragging off of the white ("execution") pin on the right side of our new node.
When we release the left mouse button, we will be asked what function or event we would like to execute. For this tutorial, let's spawn a Particle System when the countdown finishes. We'll want a Spawn Emitter At Location node, so select that from the list. It can save time to type a partial phrase, like "spawn loc", into the search field. We can then left-click and drag the yellow "Location" pin and attach it to a Get Actor Location function.
Now we just need to select what effect we'd like to see. By clicking "Select Asset" under "Emitter Template", we can get a list of appropriate effect assets. "P_Explosion" is a good one, so we'll pick that.
If we press Play now, we'll see our countdown take place, and our explosion will happen when our countdown number hits zero.
However, we programmed our countdown to say "GO!" at the end, not "0". This is no longer happening because we have completely replaced our C++ functionality with our Blueprint visual scripting. This is not what we intended to do in this case, so we need to add a call to the C++ version of this function, which can be done by right-clicking the Countdown Has Finished node and selecting "Add call to parent function" from the context menu.
When this is done, a node labeled Parent: Countdown Has Finished will be placed in the Event Graph. The typical place to connect a "parent" node is directly to the event node, which is what we will do here. This is not required, though, as the parent-call node is like any other and can be called anywhere we like, even multiple times.
Note that this will replace the connection to Spawn Emitter At Location, so we'll need to connect our Parent: Countdown Has Finished node's right-side (outgoing) execution pin to it or it won't run.
Now when we run our game, we should see both the word "GO!" (from our C++ code) and an explosion (from our Blueprint Graph) after the countdown finishes!
Finished Code
Countdown.h
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#pragma once#include "GameFramework/Actor.h"#include "Countdown.generated.h"UCLASS()class HOWTO_VTE_API ACountdown : public AActor{ GENERATED_BODY()public: // Sets default values for this actor's properties ACountdown(); // Called when the game starts or when spawned virtual void BeginPlay() override; // Called every frame virtual void Tick( float DeltaSeconds ) override; //How long, in seconds, the countdown will run UPROPERTY(EditAnywhere) int32 CountdownTime; UTextRenderComponent* CountdownText; void UpdateTimerDisplay(); void AdvanceTimer(); UFUNCTION(BlueprintNativeEvent) void CountdownHasFinished(); virtual void CountdownHasFinished_Implementation(); FTimerHandle CountdownTimerHandle;};
Countdown.cpp
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#include "HowTo_VTE.h"#include "Countdown.h"// Sets default valuesACountdown::ACountdown(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = false; CountdownText = CreateDefaultSubobjectUTextRenderComponent(TEXT("CountdownNumber")); CountdownText-SetHorizontalAlignment(EHTA_Center); CountdownText-SetWorldSize(150.0f); RootComponent = CountdownText; CountdownTime = 3;}// Called when the game starts or when spawnedvoid ACountdown::BeginPlay(){ Super::BeginPlay(); UpdateTimerDisplay(); GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, ACountdown::AdvanceTimer, 1.0f, true);}// Called every framevoid ACountdown::Tick( float DeltaTime ){ Super::Tick( DeltaTime );}void ACountdown::UpdateTimerDisplay(){ CountdownText-SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));}void ACountdown::AdvanceTimer(){ --CountdownTime; UpdateTimerDisplay(); if (CountdownTime 1) {
// We're done counting down, so stop running the timer.
GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
//Perform any special actions we want to do when the timer ends.
CountdownHasFinished(); }}void ACountdown::CountdownHasFinished_Implementation(){ //Change to a special readout CountdownText-SetText(TEXT("GO!"));}
Previous Step
Next Step
Programming Tutorials Home
|
|