Hello! Currently, I have a very simple class that I’m trying to work with. It’s called Weapon, it extends from just the generic Object, and it has a couple variables, and (this is important) a few methods that I need to call. However, the problem is, I can’t seem to instantiate a class in Blueprint scripting: there’s no “constructor” of any sort. It’s not an actor, so I can’t spawn it, and since I need it to use methods, a struct isn’t an option. Any ideas on how to do this? Or is there some little cheaty workaround that I can do?
Edit: Here’s an important part I forgot. I need to instantiate a class that inherits FROM weapon: I don’t need to instantiate weapon itself, just it’s subclasses.
I’m guessing that there’s no blueprint “pure” way to do this? I’d rather stay away from C++ if I can, but if that’s my only option, then sure. Also, is there any way I can make this a “standard” blueprint function, so that I can call it anywhere (for any class)?
Better way of saying this: can I make this completely actor/target independent, where I can just say “make an instance of this class” and it will just return that?
create a c++ method that I can call in blueprints, that receives a Class as input parameter
implementation constructs an object
I call the method from blueprints and pass it a proper class.
You might have to be careful about the “outer” in order to avoid having an object have a reference path to a level, which caused me no small amounts of pain in 4.7. You might also have to store it in a UPROPERTY or add it to the Root Set so that it doesn’t get garbage collected.
Example in your header:
UFUNCTION(BlueprintCallable, Category = Character, meta = (DisplayName = "Add weapon with specific class"))
void AddWeapon(TSubclassOf<UWeapon> WeaponClass);
Example in your cpp:
void AYourCharacter::AddWeapon(TSubclassOf<UWeapon> UpgradeClass)
{
//I assume MyWeapon is a UPROPERTY, you might want to do something different
MyWeapon = ConstructObject<UWeapon>(WeaponClass, this);
}
In my blueprint class, the method looks like this (I add Upgrades instead of weapons):
I have a general variant of this that is a static factory method, and creates objects with the class itself as outer. Works like a charm and objects get garbage collected properly (maybe it is an abuse of my part)
Creating actors works differently than my proposal: they have to be “spawned”, which can be done in blueprints: Spawning actors
If you want to create UObjects anywhere, I would suggest introducing a C++ class with static methods to act as helpers. Then, you can just call the method anywhere in your blueprints. Such a method would look like:
// In the header
UFUNCTION(BlueprintCallable, Category = Character, meta = (DisplayName = "Add weapon with specific class"))
static UObject * CreateObject(TSubclassOf<UObject> ObjectClass);
// in the cpp:
UObject * FClassHelpers::CreateObject(TSubclassOf<UObject> ObjectClass, UObject *Outer)
{
return ConstructObject<UObject>(ObjectClass, Outer);
}
But then again, depending on the lifetime of your objects, the implementation might need more bells and whistles.
Basically, first, in the editor, I did an “Add Code to Project”, then selected (I think) Blueprint Function Library. Then, in the created code file, I added this code:
// CPPBlueprintUtilities.h
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "CPPBlueprintUtilities.generated.h"
/**
*
*/
UCLASS()
class GRAVITY_API UCPPBlueprintUtilities : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject", FriendlyName = "New Object From Type", CompactNodeTitle = "New", Keywords = "new create instantiate type"), Category = Game)
static UObject* NewObjectFromType(UObject* WorldContextObject, TSubclassOf<UObject> UC);
};
// CPPBlueprintUtilities.cpp
#include "Gravity.h"
#include "CPPBlueprintUtilities.h"
UObject* UCPPBlueprintUtilities::NewObjectFromType(UObject* WorldContextObject, TSubclassOf<UObject> UC)
{
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);
UObject* tempObject = StaticConstructObject(UC);
return tempObject;
}
Then, you can just call the function in an event graph, and there you go!
In UE 4.8 I just made a static blueprint function arround NewObject().
Creator.h:
#include "Creator.generated.h"
UCLASS(Blueprintable) // makes the object avaialble to UE. BlueprintType = makes it a variable type
class MYCPPPROJECT_API UCreator : public UObject
{
public:
GENERATED_BODY()
UFUNCTION(BlueprintCallable, Category = "Object")
static void Create(UClass *ObjectClass, UObject* &CreatedObject);
};
Ah, thank you, I’ll try that. Just curious, I’m guessing there’s no way to get rid of the exec pins on that? Pre-4.8 it didn’t need to have an execution pin, and I kinda liked that.
Actually, sorry, this DOES work. I wasn’t setting the outer object, because I assumed that it was set by default. I think I was misinterpreting the documentation.