Seems like a good idea actually. Ill play around with instancing when i get some time and let you know if i find an interesting way to get that to work. Should be simple enough though.
@6ixpool: Sounds good and best of luck! Looking forward to seeing what you come up with.
I had a bit of an epiphany tonight about how I might go about making my simple road system, so I elected to give the building generator a wee break and get into some splines instead. Basically, in the simplest form, my idea is this:
I’ll spawn some closed spline polygons (black shapes) and then bind the end and start points of some spline lines (red lines) to specific points on those polygons, linking everything together. And then I’ll run a linetrace in Z to get it all to conform to whatever ground is beneath it (which took me ages to get working xD ). With some randomization on the points, I think I could get some pretty neat shapes going.
I’ve run into a snag, though - it seems like the linetrace will only let me use completely random points in XY, and I’d definitely prefer it if I had some control over just how crazy it lays out the points - right now, with four points, they cross and become a figure 8 more often than not, or become weird elongated shapes that are unusable. Optimally, I’d want to predefine their position in a vector, and then add some light randomization to that.
This is a top-view - not exactly the most perfect circle I’ve seen.
Got any ideas for how I could get them to remain in sorta but not quite a proper circle, and still use the linetrace for Z? I’ve enclosed my (quite newbish) blueprint in case anyone can figure out what I need to do from it.
That idea is brilliant actually! I hope you dont mind me playing around with it myself.
As for your blueprint, wow. Im feeling pretty bad about my blueprints skillz now lol. Mine arent nearly as neat or efficient looking. Everything is so readble and organized o_O
As for the line trace, why are you sourcing root (unless i missed you setting it as a variable somewhere along the way)? Shouldnt you be tracing starting from each individual spline point then straight down from there? So a trace starting from the current vector in the array accessed by the loop, followed by a trace to the same x,y with a negative z offset (for straight down)?
Also, you probably want to make sure to place your box above ground otherwise the youll not return anything with the trace (maybe by starting the trace from a certain altitude by adding a +z offset to start and then just extending the distance of the trace by that amount).
Other than that, i think your thing should work as planned.
Clever method for doing it there with the roads. I haven’t started on my road part yet but I was considering a similar way.
To avoid the tight angles you will want to get the current direction and only allow the new point to be within a certain angle eg. 90 degrees max.
On the Z trace 6ixpool is correct. Don’t try and do it from the root. Get the location of each spline point and then trace from there.
The way I have been doing my building generator at the moment is to create everything up in the air and then use a similar function to align using a box trace to align the buildings to the ground, then I do a line trace on each corner of the building to generate a foundation which takes the longest trace distance and spawns a mesh at that scale/10 +50 so that it digs into the ground so no buildings are floating.
I would advise doing the same with the road. Generate the road up in flat space only on the X,Y axis. Then run a function to do the Z axis alignment with your landscape. You can then at the same time run another function to align the landscape up with the spline to clean up all the gaps
I also had to make some changes to my instancer so that it saves out the values for each instance. Pretty much just publicly exposing the mesh and the transform of each instance so that when it is generated it’s saved on the “Instancer” blueprint and then whenever the construction script is ran it regenerates it.
This also allows me to spawn new buildings and then add them into the instancer at later stages without needing to “un-instance” or add new instances to the current 1. Pretty much it lets me build each district of a city as and how I want to and then “instancify” that into the existing instance. Just don’t click on the actual instancer blueprint actor once it has a couple hundred thousand instances as an editable variable because the engine does not like that hah
Nice work around there zoltan! I was kicking around the idea of reading each actor to be desteoyed, matching it up to its corresponding class and saving all that + its world transform in an array stored god knows where but your method is much much cleaner.
I hope you guys dont mind me “borrowing” your ideas. So many good ones here already
Trace from Spline Point! Of course! I feel stupid now. I’m not actually tracing from source though, I think - rather, I’m tracing from the XY bounds of the Spawning Volume (with the source in the center), and the very top of it for the Z, so that the entire box volume is used for tracing (or at least that was the plan - I more or less stole that bit from a tutorial, I might have put it together wrongly). But yes, finding the XY of each spline point and then tracing down from there sounds obvious now that you mention it. Also that trace from each corner of a building and then selecting the longest trace is genius. I’ve been making my foundations unnecessarily deep to circumvent that problem; this way I can avoid a lot of overdraw and waste. Sweet (at least once I figure out how to do it ). The avoiding-tight-angles-thing Zoltan mentions sounds exactly like what I want, but I don’t think I can quite figure out how I’d do it. Any chance you can elaborate a bit on that?
As for using my road-idea (or anything else I post in this thread), by all means! I’m not that much into actual collab as I like working alone and feeling smart when I figure something out, but I love working in tandem and sharing ideas like this. So cool. You guys rock.
Also, yes, I’m a bit OCD when it comes to cleanliness in my blueprints. But mostly because I’m afraid of getting lost and losing my overview.
Keeping blueprints tidy is sometimes a tricky 1. Here is 1 of my most OCD 1s for the tower defense kit that I will eventually upload onto the marketplace. In most of the other blueprints in there everything is colour coded too. I will even in the comments put in a Trello card link so I know what work needs to happen and where.
@Blunti For your road 1 you will want to look for “get direction vector”. Or when you are going to place your point just spawn it in the same X/Y direction with a random value that goes max up to 90 and you wont go further than a right angle for each point.
@6ixpool That’s pretty much what I do. I just jump into each actor in my building class, which will be any number of randomly generated building. Scan for a new static mesh and add it as an instance then add all the instances it pops up into that instanced mesh with its transform.
Id show you guys my blueprints but id probably get banned seeing how closely my scripts resemble hentai tentacle monsters xD.
As for the angle limitation, the polygons would necessarily have to have at least 5 vertexes for it to work. Otherwise, at least 1 of your angles (in a 4sided polygon) would always be invalid.
Just a heads up
That BP is a beauty, Zoltan. <3
Come on, weekend! I wanna get stuck into this! Thanks for the hints!
A lot of progress tonight (at least by my standards). I finally got that [censored] LineTrace to work (I think I might even understand it now, which is even better!). Now I have a blueprint that generates a hexagon, applies some random positioning, and then conforms to whatever is below it as you move it around. It’s practically sexy.
Many bothans died to bring us this purple line.
My blueprint is in dire need of some cleanup though - that is the last time I generate a polygon this way. I shall follow 6ixpool’s suggestion of trying to pack that vector-beast at the bottom into a ForLoop and maybe being a bit smarter about it. What I’d really like to do is define a pivot, a radius, and an amount of points wanted, and then having the blueprint be smart enough to calculate the actual vectors itself. I am completely stumped as to how I’d go about doing that though. Input is more than welcome, as always.
Yellow. The color of defeat. But also victory. Sort of.
And finally, as a challenge, I wanted to replicate Zoltan’s house-wot-finds-the-lowest-corner-automatically. I actually succeeded, and it was even fairly easy, all things considered. Proud as a peacock, I.
Something tells me this, too, would probably benefit from some ForLooping.
Seeing that hexagon conform to that terrain is indeed very very sexy
I keep saying it man, get on the macro band wagon!
You do! I will! I’m just still at the point where I can’t tell the difference between a macro and a function and a collapsed node. I’ll get on it.
Man, you weren’t kidding about Macros, 6ixpool. A bit of fresh thinking, a new ForLoop, and a macro brought me from this:
to this:
As an artist, why has nobody ever told me how much fun coding/scripting is? This kind of optimization is just hnnnngh!
I need to find a way to properly auto-generate the points though - right now they are still all placed by hand-written vectors. I’m guessing I probably need math. And math is scary. O_O
And feel extremely free to point out if you see further stuff I could improve/optimize/be smarter about.
I think its a rare combination having a penchant for both art and programming. Not that they dont mix, its just that theyre quite different.
As for vector randomization, you do unfortunately probably need math to do things proper. Nothing more complicated than highschool geometry and trigonometry, but its still math xD.
A quick and dirty solution of the top of my head (with minimal math since i havent brushed up on it yet myself):
- generate a random vector (with the z coordinate locked)
2a. The tricky part that needs math; run the new vector through an “angle check algorithm” to see if its generating a valid angle.
2b. If the angle is invalid, change it until it is. Two methods i can think of off the top of my head;
Simply restarting the process from step 1 until you generate a valid angle
-OR-
Randomly generate an angle within the valid range and then use the power of math to calculate where the vector should be placed to make the appropriate angle.
3a Do a raycast from the old vector to the new one, with the trace distance randomly generated (with a min/max value to keep the polygon dimensions reasonable)
3b. And then set the new vectors location to the end of the linetrace. - Loop this process as many times as you want to produce a shape with as many sides as you want.
- Connect the first and last vectors to close the polygon.
Some notes about the above algorithm:
*-You WILL need to review the math that figures out the sum of all the inner (or outer if thats the way you roll) angle for a given n-sided polygon and make it so that your angle checker takes that into account when check for a valid angle.
-How you setup step 2 will determine if your script will produce shapes with concave angles or not.
-Its step 3 that you need to tweak to “normalize” the size of the generated polygon. Off the top of my head you can use either a second rescaling factor with the random number clamped to a narrower range of values (maybe even integer values) OR use the lerp node.
-You probably want to start with a line of random lenght before running this algorithm so step 2 actually produces an angle you can check straight after you generate the first vector.
-You probably want an additional step after the last vector is generated that checks to make sure you didnt just generate a zigzagging line with a long and straight connection between then first and last vectors (something like needing a minimum lenght between them).
-Making a polygon with too many sides will probably lead to poor aesthetic outcome for the polygon unless you build in a failsafe of some
sort.
*
I am very interested in this type of work as well. I have been playing around with Houdini by SideFX which is a procedural content creation system (much more than that), the indie version also has an unreal plugin ($199.00), and it works very in a very similar manner as blueprints when designing assets.
There are lots of procedural building and city videos out there if you google it. Check it out.
@AtticusFinch: Oooh, Houdini looks cool. Will have to look into that. Thanks for the heads-up! And feel very free to join the discussion here, the more the merrier.
@6ixpool: Thanks for the write-up, but I’m afraid that it’s still a bit above my paygrade. I did manage to find a McGuyver solution in the end though!
- I stuck a socket on a mesh, 100 units out in the X-axis.
- I then spawned that mesh into my blueprint, and read the socket location off that. Then I just had to rotate the mesh by 360 degrees divided by how many points I wanted. Then I just stuck my linetracer thing from last time on it, and destroyed the socket-mesh once the loop was complete. And voila, instant perfect procedural polygon with an arbitrary number of points that I can apply randomization to.
Houdini is definitely great with the procedural generation stuff, but since it’s not something you can use at runtime so great for an entire procedural city it’s good that we are working on ways that are purely done within the engine.
Nice job with your progress on the roads Bluntie.
Definitely have to say that’s a really odd and interesting way with the static mesh and socket generating stuff there hah. Good to see you get into the loops and macro’s side of things though. Personally I try and avoid macros as I like to be able to see whats going on with a single screen so im more into the custom function side of things. Thats why I am able to use blutilities to fire off all of my events independently.
Im not sure I would personally be going that route with your roads since it will become pretty tricky to add in more complexities through them. Eg, main road vs small street vs back alley etc. I am looking at mine as more of a tree branch, you start by growing the main roads, then do the smaller branching roads off of those until they run into something then start spawning smaller 1s again.
I am also progressing a bit with my generation stuff but didn’t get any time to screw around on the weekend with it. I tweaked around my generation stuff so that it just spawns cubes at the size of the building to be placed there so that I don’t have so much slowdown when generating stuff. I store that information and then generate the rooms of the same size in there. I have started setting up my different building 1s too. I am using a data table to store all the different static meshes and store information about how they should position and what they can attach to. Also will be adding in here a cost against them so that the buildings in each “district” will have a certain budget with some randomization in there so that it will be quite varied.
Also tweaked my instancer so that it can handle different materials better. I will change around things a bit too so that depending what blueprint it is on I can flag them against a single building so I can randomize the material but keep it the same on the building. And figured out a better way to use dynamic material instances with the instanced static mesh to generate some extra randomness in there without creating a tonne of different materials and just using the instance number for some randomization.
On my road generation I have got it setup with splines now as well and it spaces out the buildings based on the size of the random 1 it generates, but since they are just spawned into the world I can manipulate them and move them around at will. I am still doing my generation in the air at the moment and dropping them into the world afterwards but I might tweak this around so that they spawn straight onto the landscape.
Still lots and lots to go but starting to come together. I need to focus and finish 1 of my things and put them up on the marketplace, I have way too many half finished projects hah
Man i am so envious. All my time is taken up by work/school (the 36 hour shifts are pretty brutal) so i cant play around with this at all right now. All i can do is theorycraft and watch you guys have all the fun
@zoltan - do you mind sharing a bit more detail about your instanciator? I looked at the screenie you provided and you seem to be pulling meshes from an array of references. How does that work exactly? You pre-generate them and populate your list manually or something?
Hah I work full time, usually 50 hours a week on average (I also have 2 other companies), luckily I am a Creative Technologist so it’s my job to tinker and know everything about different tech so this is actually what I do at work a lot of the time You have to just try and squeeze the things in where you can and take advantage of the learnings.
That mesh array is generated when it steps through all of my building blueprints. Another event steps through all of those blueprints and finds all the static meshes and add’s them into that array if they don’t already exist in there. If it does exist then I just flag what mesh it should be. I don’t actually really need that array there anyway I think I might have removed it now.