Trying To Call Custom Functions on Custom Pawn From C++


#1

Alright, I have the following situation:

  1. A custom class extended from Pawn, MyPawn.
  2. A custom method called GetCurrentStats.

Here’s my Skookum:
(MyPawn pawn)
[
pawn.
]

I would expect GetCurrentStats to autocomplete… but it doesn’t. None of my custom methods nor variables populate the list, despite being public. How do I get them to show up here?

My eventual plan is to set this Skookum method as the called method from a delegate on MyPawn (i.e. calls to MyPawn.MyDelegate.Broadcast() will be redirected to the Skookim method). Is this possible? A good idea?

Thanks in advance for the help.

Edit: More detail, in case it would be helpful. My desired result is this:

MyPawn.h

public:
	UFUNCTION(BlueprintCallable, Category = "Stats")
	FMyPawnStats GetCurrentStats();

MyEffect.h

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FEffectDelegate, AMyPawn*, PawnToApplyEffectTo);
public:
	FEffectDelegate MyEffectDelegate;

Skookum method (assignDelegate) on MyEffect.h

() 
  [
	MyEffectDelegate = applyBuffConstant;
  ]

Skookum method (applyBuffConstant) on MyEffect.h

(MyPawn pawn) 
[
pawn.GetCurrentStats();
// do stuff to stats here, obviously assigning the return of the above function to a variable
]

Does this make sense? Is there a better way to do this? My goal is to be able to swap out my stats manipulation method at run-time between several options.

Also, I noticed that if I try to change the method signature to MyPawn* instead of MyPawn I get a compilation error, “Parameter specifiers must be named and no name was found.” Does Skookum automatically assume pass by reference and I don’t need the pointer? Or is something else going on?

I tried going through the four tutorials that were posted, but as far as I can tell none of them deal with delegates nor custom objects, which are the crux of my issue. I also checked the sample project.

Thanks again for the help.


#2

I am currently using: How to set up a UE4 C++ project to work with SkookumScript to try to solve my problem.


#3

It seems like this is not possible: Hello 3.0.5093 with support for event dispatchers, delegates, Blueprint functions, custom events, name collision resolution and more!

however, listening/subscribing to event dispatchers and multicast delegate events is not yet supported - stay tuned


#4

Assigning a C++ multicast delegate a Skookum method doesn’t work in Skookum, like so:

() 
 [
	MyEffectDelegate = applyBuffConstant;
  ]

Alternatively, I’ve investigated how to call Skookum methods from C++, but I haven’t figured out how to do that yet. This isn’t an ideal solution, as I’d rather be able to script which function I’m running and have multiple Skookum methods defined, but it’s a passable work around if I have to do it.


#5

With the goal of being able to swap out the stats manipulation method at run-time.

Here’s one way you might do this.

  1. Keep your normal C++ multicast delegate
  2. In the blueprint of your base class, bind to the delegate and call a generic :sk: handler.
  3. Have your generic handler execute a list of closures
  4. Add to or remove from the list of closures during runtime.

In your class data you’d define your list of closures:
List{()} !@stats_mod

Don’t forget to initialize it in !
!stats_mod : List{()}!

The generic handler you define would call all your closures

&blueprint
()
[
 stats_mod.do[item()]
]

Then during the course of gameplay you could add to this list of closures:

@stats_mod.append(^[println("Doing something with your stats")])
@stats_mod.append(^[some_existing_method()])

Or remove from it:
@stats_mod.remove_same(^[some_existing_method()])

You can also pass arguments etc. This is super powerful and really easy to use once you wrap your mind around it. Sometimes it can help to make some helpers to subscribe and unsubscribe so you have a common entry point.

For some more example material on lists of closures, check out this post.


Is there something analogous to callbacks as opposed to closures?
#6

Great, thank you, I’ll try that.


#7

Worked perfectly, if a bit roundabout. Thanks!

A minor correction, for anyone trying to follow along:


#8

Thanks for that, there are many ways of doing things and it’s easy for me to get confused when switching between passing in a closure vs a reference to one! :confused:

Looks like I was trying to mix the two. This would be passing in a reference to a closure:

!some : ()[println("Yo")]
!stats_mod : List{()}!
stats_mod.append(some)
stats_mod.do[item()]
stats_mod.remove_same(some)
stats_mod.do[item()]