Jump to content
  • Advertisement

Unreal Blueprint - passing Constructor arguments for a spawned class

Recommended Posts

I didn't had much luck so far asking on the Unreal official forum (seems there is not much traffic over there :/ ), so I'll ask my question here as well in the hope that someone knows ^_^'

I'm trying to make a Worm game using Unreal mixing C++ and Blueprint, here some of the code I have:

struct TArrayBool {
	TArray<bool> BoolRow;
	inline bool& operator[](int Column) { return BoolRow[Column]; }
};
      
//Inside the WormGameMode.h

//...
      
//This multi-dimensional array holds bool to represent if a block in the grid of the game is already occupied or not
//This way I know in which grid blocks I am allowed to spawn Pickups
TArray<TArrayBool> GridSlotsOccupiedMap;
      
      
//Inside the WormGameMode.cpp
 
AWormGameMode::AWormGameMode():AGameModeBase()
{
	//Setup GridSlotsOccupiedMap
	TArrayBool Temp;
	Temp.BoolRow.Init(false, GridWidth / GridBlockSize);
	GridSlotsOccupiedMap.Init(Temp, GridHeight / GridBlockSize);
}

//This is a BlueprintNativeEvent
//It just Toggle the occupied status at a given [row][column] in the map
void AWormGameMode::ToggleOccupiedBlock_Implementation(int Row, int Column)
{
	GridSlotsOccupiedMap[Row][Column] = GridSlotsOccupiedMap[Row][Column] == true ? false : true;
}

As you see when I spawn a pickup I toggle the corresponding bool inside the "GridSlotsOccupiedMap" 2dArray inside the class and then use InitPickupID to store that same ID inside the pickup itself, so when the Worm collide with it and the pickup get destroyed I know which ID on the 2dArray should be toggled again (as allowed starting position for spawned stuff).
So my concern here is, is it possible that the SpawnActor by random chance spawns the pickup just in front of my Worm which steps on it before the InitPickupID is executed?
If that could happen I wouldn't be able to toggle the corresponding ID on the map thus that slot won't be able to spawn any more pickups.
So there is a way for me to pass those informations directly to the Pickup.h constructor so that the ID is recorded before the spawning? :/

BlueprintImageLink

QdBN8gP.png

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
Advertisement

First up, when you try to enforce a bidirectional link like this, between the occupied map and the pickup, you create the need to keep both sides in sync, forever, which is awkward. Try not to duplicate such information across 2 objects - store it directly in the object that needs to access it most often, and have the other object derive it somehow. That way, they can never get out of sync.

Secondly, in UE4, you shouldn't really be thinking about constructors, because they get called on your behalf. You can set the values in the next node in the Blueprint. I don't see that it is likely that there will somehow be a timing gap between the spawning node and the next node. Unless one of the nodes is explicitly marked as a latent one (which I think comes up with a little clock icon on it) then you can assume the whole graph will execute before any other logic takes place.

Share this post


Link to post
Share on other sites
5 minutes ago, Kylotan said:

First up, when you try to enforce a bidirectional link like this, between the occupied map and the pickup, you create the need to keep both sides in sync, forever, which is awkward. Try not to duplicate such information across 2 objects - store it directly in the object that needs to access it most often, and have the other object derive it somehow. That way, they can never get out of sync.

This seems really like a great suggestion, especially because is easy to derive that information based on the pickup position on the map, I was probably overtinking it and getting stubborn from the wrong perspective xD

I'll do that, Thanks Kylotan :)

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

Unrelated to your question (which Kylotan answered), flipping a bool can also be done like this (less error-prone and quicker to write):

 

//Somewhere.
bool myBool = false;

//Wherever you just want to flip the bool.
myBool = !myBool;

 

Share this post


Link to post
Share on other sites
43 minutes ago, Lactose said:

less error-prone and quicker to write

Interesting and true, I didn't had thought about that and judging by the code below seems also clearer to read, I'll do it this way from now on, thanks Lactose :)

 

bool& Bool = GridSlotsOccupiedMap[Row][Column];
Bool = !Bool;

 

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Stalefish
      Automated builds are a pretty important tool in a game developer's toolbox. If you're only testing your Unreal-based game in the editor (even in standalone mode), you're in for a rude awakening when new bugs pop up in a shipping build that you've never encountered before. You also don't want to manually package your game from the editor every time you want to test said shipping build, or to distribute it to your testers (or Steam for that matter).
      Unreal already provides a pretty robust build system, and it's very easy to use it in combination with build automation tools. My build system of choice is  Gradle , since I use it pretty extensively in my backend Java and Scala work. It's pretty easy to learn, runs everywhere, and gives you a lot of powerful functionality right out of the gate. This won't be a Gradle tutorial necessarily, so you can familiarize yourself with how Gradle works via the documentation on their site.
      Primarily, I use Gradle to manage a version file in my game's Git repository, which is compiled into the game so that I have version information in Blueprint and C++ logic. I use that version to prevent out-of-date clients from connecting to newer servers, and having the version compiled in makes it a little more difficult for malicious clients to spoof that build number, as opposed to having it stored in one of the INI files. I also use Gradle to automate uploading my client build to Steam via the use of steamcmd.
      Unreal's command line build tool is known as the Unreal Automation Tool. Any time you package from the editor, or use the Unreal Frontend Tool, you're using UAT on the back end. Epic provides handy scripts in the Engine/Build/BatchFiles directory to make use of UAT from the command line, namely RunUAT.bat. Since it's just a batch file, I can call it from a Gradle build script very easily.
      Here's the Gradle task snippet I use to package and archive my client:
      task packageClientUAT(type: Exec) { workingDir = "[UnrealEngineDir]\\Engine\\Build\\BatchFiles" def projectDirSafe = project.projectDir.toString().replaceAll(/[\\]/) { m -> "\\\\" } def archiveDir = projectDirSafe + "\\\\Archive\\\\Client" def archiveDirFile = new File(archiveDir) if(!archiveDirFile.exists() && !archiveDirFile.mkdirs()) { throw new Exception("Could not create client archive directory.") } if(!new File(archiveDir + "\\\\WindowsClient").deleteDir()) { throw new Exception("Could not delete final client directory.") } commandLine "cmd", "/c", "RunUAT", "BuildCookRun", "-project=\"" + projectDirSafe + "\\\\[ProjectName].uproject\"", "-noP4", "-platform=Win64", "-clientconfig=Development", "-serverconfig=Development", "-cook", "-allmaps", "-build", "-stage", "-pak", "-archive", "-noeditor", "-archivedirectory=\"" + archiveDir + "\"" } My build.gradle file is in my project's directory, alongside the uproject file. This snippet will spit the packaged client out into [ProjectDir]\Archive\Client.
      For the versioning, I have two files that Gradle directly modifies. The first, a simple text file, just has a number in it. In my [ProjectName]\Source\[ProjectName] folder, I have a [ProjectName]Build.txt file with the current build number in it. Additionally, in that same folder, I have a C++ header file with the following in it:
      #pragma once #define [PROJECT]_MAJOR_VERSION 0 #define [PROJECT]_MINOR_VERSION 1 #define [PROJECT]_BUILD_NUMBER ### #define [PROJECT]_BUILD_STAGE "Pre-Alpha" Here's my Gradle task that increments the build number in that text file, and then replaces the value in the header file:
      task incrementVersion { doLast { def version = 0 def ProjectName = "[ProjectName]" def vfile = new File("Source\\" + ProjectName + "\\" + ProjectName + "Build.txt") if(vfile.exists()) { String versionContents = vfile.text version = Integer.parseInt(versionContents) } version += 1 vfile.text = version vfile = new File("Source\\" + ProjectName + "\\" + ProjectName + "Version.h") if(vfile.exists()) { String pname = ProjectName.toUpperCase() String versionContents = vfile.text versionContents = versionContents.replaceAll(/_BUILD_NUMBER ([0-9]+)/) { m -> "_BUILD_NUMBER " + version } vfile.text = versionContents } } } I manually edit the major and minor versions and the build stage as needed, since they don't need to update with every build. You can include that header into any C++ file that needs to know the build number, and I also have a few static methods in my game's Blueprint static library that wrap them so I can get the version numbers in Blueprint.
      I also have some tasks for automatically checking those files into the Git repository and committing them:
      task prepareVersion(type: Exec) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "reset" } task stageVersion(type: Exec, dependsOn: prepareVersion) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "add", project.projectDir.toString() + "\\Source\\[ProjectName]\\[ProjectName]Build.txt", project.projectDir.toString() + "\\Source\\[ProjectName]\\[ProjectName]Version.h" } task commitVersion(type: Exec, dependsOn: stageVersion) { workingDir = project.projectDir.toString() commandLine "cmd", "/c", "git", "commit", "-m", "\"Incrementing [ProjectName] version\"" } And here's the task I use to actually push it to Steam:
      task pushBuildSteam(type: Exec) { doFirst { println "Pushing build to Steam..." } workingDir = "[SteamworksDir]\\sdk\\tools\\ContentBuilder" commandLine "cmd", "/c", "builder\\steamcmd.exe", "+set_steam_guard_code", "[steam_guard_code]", "+login", "\"[username]\"", "\"[password]\"", "+run_app_build", "..\\scripts\\[CorrectVDFFile].vdf", "+quit" } You can also spit out a generated VDF file with the build number in the build's description so that it'll show up in SteamPipe. I have a single Gradle task I run that increments the build number, checks in those version files, packages both the client and server, and then uploads the packaged client to Steam. Another great thing about Gradle is that Jenkins has a solid plugin for it, so you can use Jenkins to set up a nice continuous integration pipeline for your game to push builds out regularly, which you absolutely should do if you're working with a team.
    • By MoreLion
      Hey all! we are a team of 7 looking for a game designer, im a game designer but need help as i am doing multiple things at once, the game is being developed in UE4.
      the game is a futuristic action adventure game where you play as a 21 year old female who has woken up in a simulation not knowing who or where she is, but when all is unfolding the simulation gets hacked leaving eveline with no choice but to escape before she is killed inside the simulation.
      we are also looking for other members aswell wether you be a animator a ue4 game developer or that just email me below.
      if interested email liondude12@gmail.com
    • By nihitori
      This is the official Sales topic for the acclaimed Colossal Game Music Collection (100+ five-star ratings on the Unity Asset Store) and its Lite version, the Essential Game Music Collection.

      Updates will be made here every time a sale is taking place on either the Unity Asset Store or the Unreal Engine Marketplace.

      Current Sales:

      Version 2.0 Intro Sale on the Unreal Engine Marketplace -

      - Colossal Game Music Collection at 50% OFF - https://www.unrealengine.com/marketplace/colossal-game-music-collection


      Please feel free to post here any questions you might have about either the sales or the collection itself.
    • By CountBram
      Hello I am looking for advice to what I should do next as I just completed the Unreal Developer Course on Udemy and now am at a lost as what to do farther as practice and to expand my knowledge. My background is 2 years studying college in Videogame Design and 3 years working on 4 years studying Software Engineering in college. I am mainly focusing on using my C++ knowledge with Unreal Engine to make indie games but I do also know Java, and C# as well, but I do not know Unity. I am welcoming any advice that can help with my current situation with my current skill set
    • By Silverlan
      As I understand it, you're supposed to use Unreal's Online Subsystem when doing anything with the Steam SDK. However, when I look into the available interfaces (Engine/Plugins/Online/OnlineSubsystem/Source/Public/Interfaces), there doesn't seem to be a controller interface. Does Unreal not have that (yet)?
      If so, do I have to link against the steamworks libraries manually and use the SDK directly?
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!