Double Question! Can blueprint nodes made by skookum have returns? And is there a way to get the closest actor from instances?


##Long title, hopefully short post.

#Part 1!

So I’m trying to set up some logic in skookum again, and I’ve got a few things going. I’ve run into a semi snag. I’d like to have a node that finds a nearby random point from a special NodeWeb_BP actor. It’s simple enough, and just contains an array of points. I’d like to make a node that returns said point, so I made a SK method script, and set it up like so:

Simple enough, just a return of vector 3, and I can let the blueprint handle the logic, right?

#WRONG. :rolling_eyes:

The return node is on the parameter side! Also, the error is not good either.

The error is a “signature mismatch” by the way.

So I have begun writing the node in skookum, because it’s a simple enough node, but I’m just trying out all the things currently.

So that leads us to:
#Part 2!

Here’s the gist of what the node needs to do :

So is there a way to find the closest instance to an actor? Or how do I do something similar with skookum?
I’m still trying to learn the ins and out of the syntax, so I’m currently a dunce.

Thanks in advance!

P.S. I’m currently downloading the newest launcher version of skookum, so if you’re like “Hey, we fixed that!” you might have, and I’m just not there yet. :stuck_out_tongue:

###[EDIT] Set up some code after looking around at how to handle lists in the docs.

() Vector3
  //Initially, this will be used to test web position
  !found_pos : Vector3!
  //Storing closest to reduce number of .distance() calls.
  !closest_dist : Real!
  !found_web : NodeWeb_BP.instances.first
  !current_pos : transform.@translation
     !dist : item.transform.@translation.distance( current_pos )
     //If closer than closest so far or just the first
     if [ [dist < closest_dist] or [closest_dist = 0.0] ]
       if not item = found_web [println( " is closer than " )]
       closest_dist := dist 
       found_pos := item.transform.@translation  
       found_web := item
  println("Chosen web : "
  //Now we start using 'found_pos' to store actual goal
  //Vectors are in local space, due to how UE4 handles placeable vectors
  found_pos := MathLib.transform_location(found_web.transform found_web.@points.any)

important part really is[...] and item. All seems good now!

#YAY! :smiley:

If there’s a more optimized solution, please share!
Otherwise, I think we might be cooking with gas now!


Sorry for the confusion! When you specify a &blueprint annotated method without a body, it is assumed to be a Blueprint event node. So its parameters become the output of the event (meaning you call the method from SkookumScript and they get translated to Blueprint and output to the event node’s output pins) and its return value is ignored. To specify a function you need to give the SkookumScript method a body and then you will see the parameters as input pins and the return value as ouput pin on the resulting node.

And just to clarify - have you resolved the issues on your end in the meantime or Is there still something right now that does not work for you at this point?


Thanks for the response! Everything seems to be working fine, but on the matter of return pins, can you make blueprint function with skookum? Or are you saying the output pins will be on the actual node you call?


Also! If you can setup blueprint function in skookum, how do I properly setup up one that can return? Like, how to add an empty body without an error. :smiley:


To create a function node you would specify an empty code block [] as the body. Of course, if the function has a return value, the body would need to contain a value to be returned to be valid at the very least, e.g. [Vector3!].


I might have worded that wrong.


() Vector3

Makes this :
Which I assume is correct…

Is there a way to make a blueprintable node that returns a value?
Like this case:

Let’s say this node was created in skookum, as imaginary_node, then somehow made overrideable by BP.

Then in skookum, you could call

println( imaginary_node )

"Magically Delicious!"

Or is that currently impossible?


Ah get it. You mean SkookumScript methods that can be overridden in Blueprints? That is currently not supported (yet). It might not be terribly hard to implement though. Can you explain your use case, i.e. what is it that you want to achieve by having this feature?


Well, one thing I’ve ran into is certain components don’t show up as variables in skookum.

For example, my Entity component exists on each character, and holds their life information. So it should be simple as:

if @entity.@health <= 50 println("Health below 50!")

However, since the variable entity (or whatever the component variable name is) doesn’t show up, little workarounds have to be made, like storing a dummy variable on the actor class, and update that whenever the entity health updates. Not a big deal, but having a blueprint overrideable function called get_health that in the BP graph accesses the variable on the entity would be nicer.

On a side note, noticed some weirdness when getting values this way:

  !entity_var : components_by_class( GameEntity.static_class ).first
  println( entity_var<>GameEntity.@health )

This doesn’t compile, because there seem to be no variables on GameEntity, when in fact there should be multiple. Do I need to use a different macro specifier?

Here’s the variable in C++:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Replicated, Category = "Stats") float Health;

Does it need to be BlueprintReadWrite to be accessable in skookum?


Hi - so first of all, attached components do not currently automatically show up as variables/methods. What you’d need to do is create a member method entity() on Actor (or Pawn/Character) that returns component_by_class(GameEntity.static_class)<>GameEntity, you can then say (since empty parentheses are not required on methods that take no parameters) if entity.@health <= 50 println("Health below 50!") (assuming you get @health to work).

In regards to @health, do other PROPERTYs defined in your C++ game module show up in SkookumScript? Or is this the first variable that you are trying to get to work? Is your game module’s name listed in SkookumScript.ini in your project’s Config folder (see our FireBot example project for an example)? The parameters to the PROPERTY macro should not matter to SkookumScript.


Did search of my current project, and the only skookum config file in there is Skookum-project, which contains the following:

[Script Overlays]

In the engine plugin folder however, there is a SkookumScript.ini there. Maybe the .ini file didn’t generate in the project properly?


I recommend you download the FireBot project and check how it’s set up. There should be a SkookumScript.ini file in the Config folder of your project, listing your game module (if there’s no Config folder, create one). You have to manually create SkookumScript.ini. You also need to make changes to your main game module file. Look at FireBot.cpp for reference. Hope it’s not too confusing. Let me know how it goes!


I’ll check that out, and see what happens when it’s set up like that. :smiley:


Hi again! Downloaded and checked out the 4.12 FireBot project from that link. There doesn’t seem to be a SkookumScript.ini file in that project anywhere. I went back to my main project and made a SkookumScript.ini file inside Saved/Config/. Following the marketplace plugin config text, I put the following in the file :
[CommonSettings] +ScriptSupportedModules=BeastHuntPrototype
(‘BeastHuntPrototype’ was the name of the project.)

Also tried putting the file in BeastHuntPrototype/Config. It appears that no C++ variables exist on any of my classes. Do I need to do something in my code solution to make it connect? Or should it be finding the variables on its own?

Just noticed you said the module would need to be changed. Also, the FireBot demo says it is a C++ demo, but there isn’t a Source folder.

[EDIT 2]
I’m an idiot, I had to cancel the firebot demo earlier, and then restarted it, and somehow downloaded the SkookumDemo, not the FireBot. Will update when I download the right thing. :stuck_out_tongue:


Trying to set up everything the same as the FireBot example, but I’ve gotten down to this error:

1>------ Build started: Project: UE4, Configuration: BuiltWithUnrealBuildTool Win32 ------
2>------ Build started: Project: BeastHuntPrototype, Configuration: Development_Editor x64 ------
2>  Performing 2 actions (4 in parallel)
2>  [1/2] Link UE4Editor-BeastHuntPrototype.dll
2>     Creating library D:\MyData\UE Projects\BeastHuntPrototype\Intermediate\Build\Win64\UE4Editor\Development\UE4Editor-BeastHuntPrototype.lib and object D:\MyData\UE Projects\BeastHuntPrototype\Intermediate\Build\Win64\UE4Editor\Development\UE4Editor-BeastHuntPrototype.exp
2>Module.BeastHuntPrototype.cpp.obj : error LNK2001: unresolved external symbol "public: static class SkClass * SkUEProjectGenerated::SkUEEDrawDebugTrace::ms_class_p" (?ms_class_p@SkUEEDrawDebugTrace@SkUEProjectGenerated@@2PEAVSkClass@@EA)
2>D:\MyData\UE Projects\BeastHuntPrototype\Binaries\Win64\UE4Editor-BeastHuntPrototype.dll : fatal error LNK1120: 1 unresolved externals
2>ERROR : UBT error : Failed to produce item: D:\MyData\UE Projects\BeastHuntPrototype\Binaries\Win64\UE4Editor-BeastHuntPrototype.dll
2>  Total build time: 2.45 seconds
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.MakeFile.Targets(41,5): error MSB3075: The command ""C:\Program Files\Epic Games\4.12\Engine\Build\BatchFiles\Build.bat" BeastHuntPrototypeEditor Win64 Development "D:\MyData\UE Projects\BeastHuntPrototype\BeastHuntPrototype.uproject" -waitmutex" exited with code 5. Please verify that you have sufficient rights to run this command.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

So, doesn’t [1/2] Link UE4Editor-BeastHuntPrototype.dll mean that it finished linking? If so there’s only one other module in the game, BeastHuntPrototypeEditor. That’s an editor only module, but do you think it’s causing the linking error? I think I’ve set it up the same as FireBot, but I could have easily missed something.