Creating custom Base class

I am trying to make guns for a FPS shooter, I had it all set up and working in blueprints using blueprint interfaces, but they have been corrupting my blueprints. I’ve made an answerhub question and have spoken with the devs, they are likely looking at my problem, but in the meantime I’d like to look at a C++ solution. The guns I’ve made have been based off the Actor class, and I’d like to make a subclass so that I can easily reference and control them. Example, store ‘Gun A’ reference into an ActiveWeapon variable, and then just use a command like ActiveWeapon -> Shoot. Each gun then can handle its line trace and whatever else it needs to do.

I’ve been trying to follow several tutorials, and for one brief moment I had it partially working, but I cant seem to get a custom function or event to show up in my blueprints. Using the FPS blueprint project base, I did “Add code to project”. From what I can discern from the tutorials, this code should get me an event in the blueprint:



// MyActor.h
//


UCLASS()
class TESTFPS1_API AMyActor : public AActor
{
	GENERATED_UCLASS_BODY()

public:
		UFUNCTION(BlueprintCallable, Category=Gun)
		void Shoot();
	
};

//MyActor.cpp
//

AMyActor::AMyActor(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{


}

void AMyActor::Shoot()
{
	// this does nothing! NOTHING!!!
}


I’ve tried BlueprintImplementableEvent as well, and even a combination, but nothing shows up in the blueprints after compiling with no errors. Solution Configurations is in DebugGame. It even says “1> Compiling game modules for hot reload” when I compile.

From what i can tell, in your UFUNCTION you’re missing the “” in the category. I’ve never tried without quotes, but its the only thing i can tell that is missing,



// MyActor.h
//


UCLASS()
class TESTFPS1_API AMyActor : public AActor
{
	GENERATED_UCLASS_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "Gun")
	void Shoot();
	
};

//MyActor.cpp
//

AMyActor::AMyActor(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{


}

void AMyActor::Shoot()
{
	// this does nothing! NOTHING!!!
}

Doesn’t matter. Category names are parsed both with and without quotes, though certain features like function subcategories (UFUNCTION(Category=“MyActor|MyCategory”)) require them. For the longest time, you couldn’t even use quotes in category names. And in 4.6, you don’t even need to specify a category anymore, it conveniently gets defaulted to “Default”.

Anyhow, without knowing what you’re trying to achieve, Interitus384, some ideas:

If you are indeed seeing “Compiling game modules for hot reload” when compiling, then you’re hot reloading rather than doing a fresh compile. As discussed in this thread and this accompanying AnswerHub question, it seems like there is an issue in 4.6 with hot reloading managed (Blueprint) properties, events, etc. Try shutting down the editor altogether before building and restarting, see where that takes you.

Beyond that, some quick ideas:

If you’re writing a native base to use in existing blueprints, be sure you reparent those blueprints. This can be done either through the File menu in the blueprint editor, or in the Blueprint Props pane by changing “Parent Class”.

BlueprintCallable functions show up only when using an instance of that blueprint. If you’re properly reparented, you will see that function either in a child AMyActor blueprint’s eventgraph, or in another eventgraph that uses a AMyActor blueprint.

BlueprintImplementableEvents/BlueprintNativeEvents have two possible cases:

If you don’t have a return value, you will only see your function in the eventgraph of a child AMyActor blueprint, when right-clicking the eventgraph:


If you do have a return value, it will instead show up in the blueprint elements pane (by default on the left-hand side):


That should cover all possibilities based on what you’ve provided, see if any of that addresses your issue.

Cheers,

Awesome, Closing the editor and reloading after a compile seems to do the trick.

Tho now I’ve tried both Callable and ImplementableEvent, and both just seem to get me a function that does nothing in the editor. Cant seem to get an actual event, like a custom event, but not per blueprint instance.

Ok, I seem to have it working now with:


		UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "Gun")
		void Shoot(int32 ThisIsAFloat);


The compiling seems to be wierd. I have to compile, close editor, Compile again, load editor, reparent, then things show up. Not sure what I’m doing wrong here, but I’m sure I’ll get it eventually. Thanks for the help!

edit- oh yeah, and apparently int32 isnt a float. I should read up on some of the basics again…

I’m still on 4.5 and not experiencing this bug so don’t take my word for it, but I think you can reduce that to:

Close Editor > Compile > Start Editor

The first recompile (hot-reloaded) is redundant because the fresh recompile gets rid of hot-reload modules. Reparenting persists after you save your blueprint, so once it’s done for the first time, it shouldn’t be necessary anymore.

As for functionality in the editor, BlueprintCallable and BlueprintImplementableEvent are pretty much direct opposites:

BlueprintCallable produces a native C++ function that can be called from Blueprint. The intent of these is generally C++ -> Blueprint communication.

BlueprintImplementableEvent produces a native C++ function thunk that does nothing unless you implement it in Blueprint. The intent of these is normally Blueprint -> C++ communication.

Tagging a function with both gives you a function that can be called from Blueprint (and C++) but won’t do anything until you also create an implementation in blueprint.

I don’t like hot reload. I don’t use it. I find just thinking about the code you write before you compile makes the need for hot compile naught, if you only have to compile one or twice who cares that you spent a little more time in the ide and not in the editor. you just write your c++ code and compile with the editor closed and then just open the project from the prj dir. just my my 2 cents.

Or you could embrace an advanced feature that makes your life easier instead of refusing to use it because “who cares”. Hot reload is a godsend for fast iterations, going from Slate layouts to plain old gameplay.

You cannot change the class memory layout with hot-reload. If you’re compiling changes that often with changes that do not change the class memory layout, you shouldn’t be compiling in the first place.(obviously there are times where a re compilation that doesn’t change class memory layout is needed)
But if you take a step back and program with some mental forethought, it’ll not only do you wonders to your code quality but to your programming speed and abilities aswell.

I was taught to think through a problem first, before you ever write code; break down the problems in to smaller sub-problems and then program the small sub-problems.
if you have to compile at every little small sub-problem to know that what you programmed for it actually works for the small sub-problem, then it’s terribly inconsistent, no ? by having that mental forethought you eliminate the need for fast iterations.

I actually wrote an entire slate based in game hud without compiling once until the entire hud was completed with 0 bugs, granted I worked with slate before, but without proper mental forethought, i’d have never been able to do that. I’m not saying hot reload isnt a good tool, I just feel people rely on hot-reload, when they should be relying on their brain.

Obviously you wouldnt think this if your in a TDD env.