Hi, I want to create an event that is callable from a static function, the event can be seen on blueprints but I can’t manage to fire it. Is there any form to do it? This is the code that I’m using:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "../ThirdParty/include/EDSDK.h"
#include "../ThirdParty/include/EDSDKErrors.h"
#include "../ThirdParty/include/EDSDKTypes.h"
#include <iostream>
#include <string>
#include "CameraNikon.generated.h"
UCLASS()
class THIRDTEST_API ACameraNikon : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACameraNikon();
UFUNCTION(BlueprintPure)
static ACameraNikon* GetInstance();
public:
UFUNCTION(BlueprintCallable, Category = "CanonObjSDK")
static void InitCanonSDK();
UFUNCTION(BlueprintPure, Category = "CanonObjSDK")
float GetApertureSDK();
UFUNCTION(BlueprintPure, Category = "CanonObjSDK")
float GetFocalLengthSDK();
UFUNCTION(BlueprintImplementableEvent, Category = "CanonObjSDK")
void ShutterDown();
public:
static EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,
EdsBaseRef object,
EdsVoid* context) {
static ACameraNikon* Cam=GetInstance();
if (event == kEdsObjectEvent_DirItemCreated) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Orange, ("DirItemCreated"));
Cam->ShutterDown();
}
// Object must be released
if (object)
{
EdsRelease(object);
}
return EDS_ERR_OK;
}
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
And the GetInstance function is written in the source file as:
ACameraNikon* ACameraNikon::GetInstance()
{
static ACameraNikon* i = 0; if (!i)
{
i = NewObject<ACameraNikon>();
i->AddToRoot();
// Do various other things here that you need to do
}
return i;
}
Hi Kehel18, and thanks for your time, since BlueprintImplementableEvent cannot have a static function, and I want to trigger that event from a static function, I wanted to create an object of the class inside the static function and then call the non-static function using that object, for that I first writed:
static EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,
EdsBaseRef object,
EdsVoid* context) {
ACameraNikon Camera; //Triggers the error: UE4Editor.exe has triggered a breakpoint.
static ACameraNikon* Cam=GetInstance();
if (event == kEdsObjectEvent_DirItemCreated) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Orange, ("DirItemCreated"));
Camera.ShutterDown();
}
// Object must be released
if (object)
{
EdsRelease(object);
}
return EDS_ERR_OK;
}
But, since it triggers the error: “UE4Editor.exe has triggered a breakpoint”, I was not able to make it work. Then I was trying to get an instance of the class as static and then use that instance to invoke my non-static ShutterDown function, but it still don’t work. I found the code for that instance from this discussion:
So the main thing is that I want to generate an event that can be used as blueprint and can be triggered from a static function.
Hi, what do you mean with register the event? I just created the event in C++ inside the actor as BlueprintImplementableEvent and then I tried to use it my actor blueprint editor.
Hi, since BlueprintImplementableEvent does not let me add a static function I was trying to do two things:
the first one was to create an class object like this:
EdsError EDSCALLBACK handleObjectEvent(EdsObjectEvent event,
EdsBaseRef object,
EdsVoid* context) {
ACameraNikon Camera;
if (event == kEdsObjectEvent_DirItemCreated) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Orange, ("DirItemCreated"));
Camera.ShutterDown();
}
// Object must be released
if (object)
{
EdsRelease(object);
}
return EDS_ERR_OK;
}
But this gives me the error: “UE4 created a Breakpoint”, and then it closes. So I was trying to get an instance of the class following the code in this discussion:
But still don’t know why it doesn’t work. I also deleted “static” in the line that you showed me, but still don’t have any response from the event.
I basically want to create an event that can be seen in Blueprints and that can be triggered from a static function. Thanks for your time
So you created a blueprint based on this class ?
thing is you did a “NewObject();” creating a base class object, you would need to instanciate an actor based on the blueprint
What do you plan to do with this actor ? ( many possibilities to handle this )
classic ones are :
place the actor yourself on the map you need it
have a configurable variable on map setting and read it before spawning
Yes, in the editor I created a blueprint based on that class and placed it directly on the map. Inside the blueprint I just dragged a print node from the event execution pin to see if the event is called.
Thing is, I know that the static function is working because I can see this line on the viewport
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Orange, (“DirItemCreated”));
but I cannot see the message from the print node inside the blueprint.
Ok. I think I found the problem - you create object with this
NewObject<ACameraNikon>()
But this is native class! It has no any implementation of BlueprintImplementableEvent. If you have some BP over ACameraNikon, then you need to create object of that class
PS. @Dream Powered is also right - if you create actor without any World there can be issues, so if this is not an actor on the scene you would better do it as UObject
Ok, I made an UObject and transfer my functions there as you suggested but still don’t have any response. Is there any other method to make a blueprint type event that can be triggered on a static c++ function?
Hello again! Just think of two points - what class is created and in which class you define (not declare but define!) BlueprintImplementableEvent. Can you answer on this?
The class that I first created was an Actor type Class, and in the header I declared the BlueprintImplementableEvent, but as far as I know it doesn’t need a definition in the source file, or should I define it on editor?
In editor mode I created an Actor Blueprint that has ThirdTest.CameraNikon as a parent, there I’m able to look at all the parameters that I declared including the “Event Shutter Button”, so I just dragged a node frome its execution to print a message in the viewport when the event is called.
So, thanks to Dream Powered and Kehel18 comments, I just realized that in my code I was not getting the actor from the world (in editor I created an actor blueprint from my ACameraNikon class and added to the level that I needed). So I made a function to look for all the actors of my class like this: