Download

Create base property and multiple instance of it (C++)

Hi all, this is probably a really noob question, but I’m having some truble on it.

I would like to create a class that contain some property like this example:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Life Stats”)
float Life;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Life Stats”)
float LifeRegen;

The main problem is that i would like to instance this class on multiple Npc or object and so on, attaching it to them. How can I do it?

I have try something like the Character Controller (in most of the example), but I always get some error.

How I have to create this class? And how to link it to something?
Thanks a lot!

Can you post a snippet of where you are actually pasting the code in, and what the error message is?

Anyway this is really straight forward.

Firstly you wouldn’t want this in the Character Controller, as only character(s) that are possessed by the player(s) would have controllers to begin with, and as you said, you want this on all NPC’s and other objects. They could have AI controllers, but based from what you wrote it sounds like you want some inanimate objects to have some sort of life variable too. Therefore controllers will not work.

For Characters you’ll want to put these properties in their Character.h file, which .h is the only location you can declare variables and assign them property specifiers (ie UPROPERTY(…))

But since you want this to be an instance for NPC’s and perhaps other objects other than pawns, you can make a UObject Class, lets say its called “UMyLifeObject”, so itll look like this



#include "Object.h"
#include "MyLifeObject.generated.h"

/**
 * 
 */
UCLASS(BlueprintType)
class TDEXAMPLE_API UMyLifeObject : public UObject
{
	GENERATED_BODY()
	
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Life Stats")
float Life;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Life Stats")
float LifeRegen;
	
public:

//Next you will need a basic constructor
UMyLifeObject();

//Finally a function to instantiate this property, this is optional only if you are planning to do this in blueprints
UFUNCTION(BlueprintCallable, Category = "Life Stats")
static UMyLifeObject* ConstructUMyLifeObject(float LifeValue, float LifeRegenValue);
	
};

in the .cpp



#include "TDExample.h"
#include "MyLifeObject.h"


UMyLifeObject::UMyLifeObject(){
	//Default constructor code here, but lets say...
	Life = 100.f;
	LifeRegen = 50.f;
}

UMyLifeObject* UMyLifeObject::ConstructMyLifeObject(float LifeValue, float LifeRegenValue){

	UMyLifeObject* LifeObj = NewObject<MyLifeObject>();
	LifeObj->Life = LifeValue;
	LifeObj->LifeRegen = LifeRegenValue;

	return LifeObj;
}


So now to actually instantiate it and add it to an NPC can be tricky.

In C++ You could just add UMyLifeObject as a property to that NPC’s .h file, and instantiate it by calling NewObject() in the NPC’s constructor.

Or if you are doing this in blueprints make note of the


UCLASS(BlueprintType)

specifier in the above snippet. You need to specify this is a BlueprintType in order for this class to be declared as a variable in blueprints.

You then go into the NPC’s blueprint class, add a variable of type UMyLifeObject (though it will appear as “My Life Object” in the list)

In the end you should get something like this:

a36cd3119a58784321011ed16383b978ac884e23.png

It be best if you could get this to work in an actor component. I haven’t tried it, but in theory it should work, and then all you would need to do is add this component to all your NPC blueprints.

But personally I would just go the C++ route, and just inherit from some base NPC class that does this in the base constructor. That way I know it will always be instantiated in any class that would inherit from it.

I recommend you check out UE’s youtube channel. The programming tutorial helped me get going.

I will try to explain it better, but you give me some good suggestion.

I would like to have a class named:

NpcStats.h //Here i just put function that I can call, parameter to show, etc
NpcStat.cpp //Where I declare just base function.

Now I would like to have multiple

Npc1.cpp
Npc2.cpp
Npc3.cpp

That simply have a different constructor (so different stats in this case).
And I would like to attach Npc3.cpp to something in game (like a cube for now)

A good example of what I would like to reply is the TopDown Example.
The main character have:

The main “TopDownCharacter (self)” //This is the recap of all the thing inside it

CampsuleComponent
---- Mesh
---- CameraBoom
---------TopDownCamera


CharacterMovement (inherited)

I have try to build myself something like this looking at how is the TestsCharacter.h


#pragma once
#include "GameFramework/Character.h"
#include "TestsCharacter.generated.h"

UCLASS(Blueprintable)
class ATestsCharacter : public ACharacter
{
	GENERATED_BODY()

	/** Top down camera */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class UCameraComponent* TopDownCameraComponent;

	/** Camera boom positioning the camera above the character */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class USpringArmComponent* CameraBoom;


public:
	ATestsCharacter(const FObjectInitializer& ObjectInitializer);

	/** Returns TopDownCameraComponent subobject **/
	FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; }
	/** Returns CameraBoom subobject **/
	FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
};

So instead of TopDownCamera and the CameraBoom I just whant to se my Npc1 class that is derived (like I say) from NpcStats class.
This is possible I think, because the example i take don’t have CharacterMovement in .h file or .cpp but it comes from the other header.


#include "GameFramework/Character.h"

and if i look how is done:


#pragma once
#include "GameFramework/Pawn.h"
#include "Animation/AnimationAsset.h"
#include "Character.generated.h"

class UPawnMovementComponent;
class UCharacterMovementComponent;
class UPrimitiveComponent;

and if i check the main header CharacterMovementComponent.h it has all the parameter that TopDownCharacter show.
What I would like to have i something similar but with multiple rewrite of the contructor or the possibility to have some function that simply change base stat and can be rewrited for every NpcX class.
Another main problem is that something like CharacterMovementComponent is a component and not an actor, so it is a bit different i think.

I also would like to simply “attach” this Npc1 to something in game, but I don’t think is possible, because you have to create it in VS. I think I can’t take a “cube” and “attach the Npc1 class”, the only possibility is to create an actor with this class (and all derived) and attach to it a cube, is this right?

I hope I have explain better, yesterday was really late :smiley:

I have done some other stuff, but is not working.
I found that component can be attach to any object in game, so I have done this:


#pragma once

#include "Components/ActorComponent.h"
#include "HeroeStats.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class TESTS_API UHeroeStats : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UHeroeStats();

	//Proprety for life
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Life Stats")
		float Life;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Life Stats")
		float LifeRegen;

	// Called when the game starts
	virtual void InitializeComponent() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;	
};

So this is the main component that will have all the stat I need. If I attach it to any object i see all the property I have created.
Now comes the tricky part.

I have created a second component with a class HeroeStats:


#pragma once

#include "Components/ActorComponent.h"
#include "HeroeStats.h"
#include "Hero1.generated.h"

class UHeroeStats;

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class TESTS_API UHero1 : public UActorComponent
{
	GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
	class UHeroeStats* HeroeStats;

public:	
	// Sets default values for this component's properties
	UHero1();

	// Called when the game starts
	virtual void InitializeComponent() override;
	
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
};

But if I attach this to something, nothing is showed, why? I have done it following same step of the example i explained in the other post