Download

[Tutorial Request]Using C++ in conjunction with Blueprints

Hello! I am new here, is this the place to post such shtuff?

The Docs and tutorials for this engine and the community itself is really good, but I noticed an aspect that is particularly missing from both the Wiki and the general tutorials around the web - how to make different UE4 systems work together. This concerns pretty much all the systems (e.g. using particles with dynamic gameplay objects, as in using some logic/vars from the object to control particle and vice versa), but the one I am particularly interested in and one I think would be most useful is C++ AND Blueprints. It appears that the best way to make any sort of full project in UE4 is by combining C++ code with blueprints to keep the BP tidy, while still using their dynamic non-hard-coded values in your game. So here is my feature suggestion, I think it would be a great help if someone explain how to do this:

Use case:
Making a dynamic character controller with Aim Offsets and Blend Spaces. I want to have a character controller where Basic firing, movement and vector calculation logic is initialized in C++ and used in Blueprints (e.g. Spawn the Camera boom and set it’s initial values in C++, configure in Blueprints, Calculate Direction, Speed and AimOffset vectors in C++, use in Blueprints, Write AI reactions such as running towards target, attacking target, hiding and so on in C++, use BP to define when these reactions should occur etc.).
For the scope of tutorial I think just Aim Offset calculation would suffice.

**Workflow:
**

  1. Create a AimOffset(target=self) function in C++ that targets the BP called by default, but can have custom target, similar to for example “Get Control Rotation” node from animation blueprints.
  2. Make it visible to blueprints
  3. Use it to replace the following node set:
    bcbad4ba96717c5780b87841ad09976559e3eda9.png

BP function spec:
Pawn > Calculate Aim Offset
Inputs:
Pawn/Character Target - The Pawn for which to calculate Offsets, self by default
Interp speed - Speed at which to interpret rotation delta
Delta time - time function to use for interpreting (let’s say I am building an AI - I don’t want it to be frame-dependent or I will get Mass Effect 3 Multiplayer syndrome)
Clamp range - Maximum values supported by Offset animations

Outputs:
Pitch: AimOffset clamped pitch value ready to be set to the animation variable
Yaw: AimOffset clamped yaw value ready to be set to the animation variable
[Optional] Orientation - by own personal preference - the bottom set of nodes calculate character orientation Yaw and if AimOffset Yaw reaches certain threshold rotates the whole character. I would put it on every character (even turrets, I just wouldn’t use it), so I would like it to be included in the function too, just as a good practice.

Result:
After the tutorial the person following it should know how to make a function, expose it to all blueprints, and have configurable inputs, to greatly compress the blueprint construction. As you saw from the screenshot, in Blueprints, this very commonly used functionality takes quite a lot of nodes. If I was to program also the AI behaviour or gameplay mechanics completely in Blueprints, it would make them insanely huge and unreadable. It makes much more sense to create functions for things like AI that are responsible for processing data in C++ (e.g. calculate target, calculate where cover is, enter cover, swap weapons) and then use BP to define conditions for when these actions are performed.

As a small suggestion for Documentation: it would help A LOT if the Blueprint reference in UE docs also told of the equivalent or related C++ functions for the node. E.g. something like this:
828e871a9f39d9baf4b85435bd6c7c11d7dbcf53.png

I think this would be a very useful tutorial, please excuse me if there already is one for this, I haven’t been able to find any.

Have a look at this page https://docs.unrealengine.com/latest/INT/Engine/Blueprints/TechnicalGuide/ExtendingBlueprints/index.html.
Especially BlueprintCallable functions and BlueprintImplementableEvents are probably what you are searching for. In my project I’m doing most things in Code, except stuff like UMG and Animations etc. and for communicating between Code and Blueprint I’m always using BC functions and BIEs.

I have seen that page, but I don’t seem to be able to get my function to work. I have defined it inside the Character class and made it BlueprintPure, yet it doesn’t seem to behave properly. It shows two inputs instead of one, and one of them is incompatible with the character pawn when I call it inside animation blueprint.
The whole idea here is that a full tutorial on how to achieve a particular use case gives a better understanding of how components interact with each other, rather than just reading the rules and then trying to follow them, unaware of some small detail, that might have been mentioned in a different documentation page is interfering with the results. If I eventually figure it out, I will do the tutorial myself, but I am sure there are a lot more competent people who would be able to do such a tutorial much better than someone who just started out with Unreal a month ago.

In case you want to have a look by the way, my code is this:
ThirdPersonCharacter.h



UCLASS()
class SHOOTSOMEBALLS_API AThirdPersonCharacter : public ACharacter
{
	GENERATED_BODY()

	//camera boom and follow camera

public:
	//mouse sensitivity, begin play, tick

protected:	

	//input controller, OnFire, movement
public:
	/** Returns CameraBoom subobject **/
	FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
	/** Returns FollowCamera subobject **/
	FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }

	UFUNCTION(BlueprintPure, Category = Rotation)
	FRotator GetAimOffsets(APawn* target);
	virtual FRotator GetAimOffsets_Implementation(APawn* target);

	/** Gun muzzle's offset from the camera location */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
	FVector MuzzleOffset;

	/** Projectile class to spawn */
	UPROPERTY(EditDefaultsOnly, Category = Projectile)
	TSubclassOf<class ABaseProjectile> ProjectileClass;
};


ThirdPersonCharacter.cpp



FRotator AThirdPersonCharacter::GetAimOffsets_Implementation(APawn* target) { //how do I make pass it "self" reference by default? Says "this can only be used inside a non-static member function"
	FRotator CurrentRotation = target->GetActorRotation(); //Current rotation of the character
	FRotator ControllerRotation = target->GetControlRotation();

	FRotator Rdiff = ControllerRotation - CurrentRotation; //Difference between directions?
        //Need to also break rotation into pitch and yaw to return
        //how do I return multiple values to the blueprint?

	return Rdiff;
}


And here is what is shows up like in BP:
ljCbcGq.png
I read in a different documentation page that I have to put the word _Implementation in the function code. Yet I would expect it not to show in the blueprint. Yet it does.

As you can see there is a LOT of confusion from trying to follow multiple disjointed documentation pages and rules. A cohesive tutorial would help immensely to clear this confusion up. I am sure it seems trivial to you, but it is not trivial to a beginner.

Ok, I see.
I can’t help you regarding the tutorial but with the two input pins: I suggest, that one of the input pins is the Pawn the function is executed on and one is the input for your function, that should be more clear if you rename the parameter passed into the function.

Yes you were correct. I didn’t want that kind of behaviour, I wanted to have a default parameter for target, but not for it to be called on the instance of the Character class I was putting it in. After tons of searching, I decided to move out the function into a separate library, and got stuck on that for days. There is no way to actually find out how to perform the steps required to make it work. Half the material online is outdated and another half is dealing with a case ripped out of context, and can’t be applied if you have even a slightly more complex structure. The code I have now is

MyUtils.h


UCLASS()
class SHOOTSOMEBALLS_API UMyUtils : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
		UMyUtils(const class FObjectInitializer& PCIP);

	public:
		UFUNCTION(BlueprintPure, Category = Rotator)
		static void GetAimOffsets(const APawn* target, float& AimX, float& AimY, float& AimZ, FRotator& Rotation_Offset);
	
	
};

MyUtils.cpp


void UMyUtils::GetAimOffsets(const APawn* target, float& AimX, float& AimY, float& AimZ, FRotator& Rotation_Offset) {
	FRotator CurrentRotation = target->GetActorRotation(); //Current rotation of the character
	FRotator ControllerRotation = target->GetControlRotation();

	FRotator Rdiff = ControllerRotation - CurrentRotation; //Difference between directions?

	AimX = Rdiff.Yaw;
	AimY = Rdiff.Pitch;
	AimZ = Rdiff.Roll;
	float Aim_Yaw = AimX;
	float Aim_Pitch = AimY;
	float Aim_Roll = AimZ;
	Rotation_Offset = Rdiff;
}

And it simply doesn’t show in blueprints. By now I have suffered through HUNDREDS of compilation errors, from deprecated notices, to some weird aspects of their C++ slang (mostly that), and have made absolutely zero progress. For something as trivial as making a tiny utility function for finding aim offsets, you can probably see why I requested a tutorial on the topic :stuck_out_tongue: