Greetings! I wonder what is the best way to implement Modular Space Ship concept in Space Engineers style.
That means that player will have ingame editor where he will select and snap ship blocks to the ship itself and then player will have ability to test his ship on playground flying around e.t.c.
My first noob idea is to snap blocks of a ship to each other as an actors through sockets. I thought in that way because Blocks have their unique functionality, parameters, animations and so on. Like subtype and parameters of thrusters/generators/armor/turrets will be unique to each block on the ship.
You get an inherited SMC, but also a full graph, variables, sockets, functions and so on. And all that without the overhead of a full-blown actor; and, most importantly, you can avoid pigeonholing yourself into relying on Child Actors.
Probably irrelevant if you have 10-20 pieces. May become relevant if you need 200 pieces in 20 ships. Look into inheritance if you’re not familiar with the concept, components support it; and exposing variables, too, thanks to this pretty node (Add Component by Class added in 4.26 or 4.27):
I’ve build modular mechanical entities with this. It also works with skeletal mesh components. The only (can be major) drawback is that components cannot own other components - but that’s what socket attachment is for. Whether it is a drawback depends on how you organise and build stuff.
Question with that implementation - can static meshes own animations/FX’s e.t.c.?
I want to pre assemble block in it full capacity in ue5 editor and then give it to player to attach to their ships.
For example that means that thruster block will be applying force to whole construct, will have sounds, FXes and so on.
I doubt this possible (complete pre assembly in full capacity) by your method… or am I wrong?
PS
One more point of input - Ship will be destroyable block-by-block just like in Space Engineers.
This means that ship cut in half will create two “ships” with their corresponding blocks.
It’s just variables referencing assets, so yes. You get a full graph to handle it. Or have the comps pull what they need from Data Tables. While the components cannot own other components, they can spawn them.
I want to pre-assemble block in it full capacity in ue5 editor and then give it to player to attach to their ships.
You can use an actor as a pre-assemble block base and then attach custom SMC (as in the original post) to said block. This will work well, both in the editor and with a fully dynamic setup in case the player wanted to detach a piece or blow it up or cut it off. The advantage here is that each extended SMC can have its own internal logic.
this could be a manually pre-assembled block actor:
The engine SMC can apply force (at location) thrust to the root of the actor (or to something else). Were you to attempt doing the above with Actors, you’d need to rely on Child Actor Components.
This means that ship cut in half will create two “ships” with their corresponding blocks.
This will take some (space) engineering, heh. But is doable. Look into procedural mesh slicing.
in case the player wanted to detach a piece or blow it up or cut it off.
One note about component destruction that catches people off guard:
You cannot destroy components as you please. You must politely ask the owner to do so for you or ask the component itself to self destruct. It’s safer like this anyway.
@Nawrot You’re into spaceships. Have you done something like this before? Any insights?
We might as well try to summon @Tefel - perhaps we’re lucky. They’re on a glorious modular adventure, although not sure how much physical simulation there is:
Somehow I feel their input could be invaluable.
Best concept of Modular Space Ship that is assembled in runtime by player?
Thnx for your answers!
I will wait for opinion of others but you convince me that I need to use one actor and bunch of SMC as blocks with their logic and everything else
PS
BTW I will not slice blocks on destruction. I mean if block destroyed, it is destroyed completely. Ship will contain hundreds of blocks.
Only one thing to engineer in that regard - the way to identify: was this clump of blocks cutted entirely from another clump of blocks?
On first picture I didnt understand what block is hitted by the laser. Is it 1 then 2 (horizontal ray) or just 2 (vertical ray)
One second picture I assume that laser hit block 5 and then block 4 (vertical top-down hit).
Assuming blocks 1, 2 and 3 was attached to block 4 by my logic happens next: Block 5 and 4 are destroyed (destroy component), blocks 1,2,3 are detached and becoming their own “ships” (in free flight) with impulse given from explosion of blocks 5 and 4.
But as I sad, I need to identify that block (or group of blocks) need to become their own ship by checking are they “physically” connected to each other body-to-body way.
I assume that will require creating a map of connected blocks and function to check connectivity if block dies.
Yes i am into space and ships. And that socket idea works wonderfully in “Galactic Civ 2”.
Currently I am doing some simple space game, and thinking about doing modular ships.
GalCiv 2 editor:
It works great for visual of ships, however if you want something for game-play like Space Engineers style It would require something better.
Gal Civ editor snapping works like tree structure, so probably you need to code that. Then add sockets (better in data struct than in meshes). Also there is problem of draw calls (this is why i am unsure my game needs ship editor). Each module will be separate piece.
This is why you need that tree structure, that remembers which mesh is “parent” and which is connected to it and which socket, and transform (relative location, rotation and scale). So you can build whole space ship out of that tree data.
Code would be quite “simple”
tree structure that remembers hierarchy
some struct that describes all sockets
another struct that holds mesh, which socket it is connected to , and its transform
That is simple, but making editor in game for this, is much harder.
ps.
Ahh you want it more like space engineers, then best would be some grid and locations on that grid.
Thats where “almost” comes in
Space Engineers ships is a grids. I want “Freeform building” which means there will be a lot of blocks but there will be no hard grid. Blocks will connect to other blocks via sockets but those sockets will not be strict oriented (not like in grids)
And you are absolutely right - I need “Block connection map”. But structure will not be hierarchical because one block can be connected to many, so it is not “who parent to who” but rather “who connected with who”
Then do not with such project, it will require some code like that.
Then you will have load order troubles, like when you need to reference actor that is not loaded yet, which is impossible, so you need rebuild whole logic of game, etc.
Start simpler project, like “galciv 2” snap to socket ship constructor.
I need “Block connection map”. But structure will not be hierarchical because one block can be connected to many, so it is not “who parent to who” but rather “who connected with who”
While you cannot dynamically create sockets in BPs, you can give meshes sockets manually and grant them unique tags:
Your component can keep track of other attached components either by using socket names or the abovementioned tags which could provide extra flexibility:
In my case, I had a specialised smart connector that performed that function - I needed to have an entity that would move data between components even though they were not attached. So it was a tad more complex. Think wireless cables.
Another way of keeping track of what is attached without mapping it, is to trace. You trace to each of the sides (or through every socket) and see what else is there. You’d need to create rules regarding what is considered attached - proximity / compatibility etc.
Yes. Sockets you showed is exactly my line of thoughts.
I already implemented socket spawn and connection.
BTW question about Sockets - I was forced to create custom function to attach child component not by its pivot but by its corresponded socket coordinates.
Is there a way to do that without custom functions?