Blueprint Asteroids field

[spoiler]


[/spoiler]

DOWNLOAD LINK
Asteroid Field 4.17

Hey all,

Time ago i was looking for how to use Instanced Static Mesh for an asteroid field and found this tutorial on youtube from Tech Art Aid [MENTION=5535]Oskar Świerad[/MENTION]

[spoiler]

[/spoiler]

the problem with ISM/HISM is that add rotation to a every single instance have an expensive cost in terms of performance.

MY SOLUTION

In simple words, check for instances in a “visible” range, destroy and replace these instances with a Blueprint actor that simulate physics to add rotation.

Demonstration:

Basically what i technically do is get all the instances that are inside a sphere that have center in the player camera and radius as the “visible” range you want, after that i “filter” all these instances with a dot product and if the result (in degrees) is inside the FOV value (in degrees) of the camera they will go to the second “filter” pass, i throw a linetrace between the camera and the instances, if i hit the player pawn i “discard” the instance from to be replaced, if i don’t hit something means the instance is “visible” and i remove and replace it with an actor blueprint that have the same Static Mesh in the same position and rotation with simulate physics active and an initial torque force to start the rotation.

Here some pictures with debug traces activated (FPS are very low because all the debug lines and spheres).

Red sphere and lines are the “discarded” instances from be removed and replaced with BP actor.
Blue sphere and lines are the instances that are removed and replaced with BP actors.
Green lines are the trace that hits the player pawn ship and “discard” instances to be removed and replaced.
Big purple sphere is the GetInstancesOverlappingSphere sphere (yep, is a sphere), sadly have the same color of asteroids in wireframe mode, i hope you can easily see it from the pictures (sorry for it).

[spoiler]
Perspective view


Side view


Top view


[/spoiler]

PROBLEMS

Basically the problems of my solution are performance, the function have a couple of for loop and it’s called every tick from pawn with an event dispatchers because you frequently need to know the camera position, after some debug test with frontend profiler seems the GetInstancesOverlappingSphere call is very expensive (something like 2ms) and in total the SwapAsteroids function take between 2ms to 5ms to be executed.

That means you don’t have to exxagerate with the “view” distance or you will encounter a massive framerate drop but if you manage with range and distance between asteroid values you can achieve a good effect with a stable framerate (over 150fps on my system).

Could be very nice have a funtion like GetInstancesOverlappingCone or Hemisphere to cut off the initial area we are looking for.

GENERAL INFO

Here how you can use BP AsteroidField SwapAsteroids function

[spoiler]
Create an event dispatcher in the player pawn and call it with FOV and camera transform


Bind it in at BeginPlay in the AsteroidField blueprint


[/spoiler]

BP_AsteroidField details panel (sorry if variables naming is not the best)

[spoiler]


[/spoiler]

OffsetX: distance on the X axis between asteroids
OffsetDeviationX: use it to add some random to the distance value (in default settings is at 100 that means distance will be between 900 and 1100 units).
OffsetY: distance on the Y axis between asteroids
OffsetDeviationY: use it to add some random to the distance value (in default settings is at 100 that means distance will be between 900 and 1100 units).
OffsetZ: position on Z axis, will be a random value between -OffsetZ and +OffsetZ

SwapRange: basically is the radius of “big sphere”, how far you will go to check instances.
OffsetFOV (in degrees): this value is added to the FOV on check if instances are in a visible range, you need it because line traces are from camera to the center of the asteroid and could be happen that you can see a portion of the asteroid but is not “swapped” because his center is out from the desired view angle.

ShowDebugHUD: as variable name said :slight_smile:
ShowDebugTraces: as above, enable it will cause an important framedrop

MaxInstancesX: how many asteroid instaces on X axis the field will have
MaxInstancesY: how many asteroid instaces on Y axis the field will have

AsteroidMesh: the static mesh for both instanced mesh and blueprint actor
MinAsteroidScale: the minimum value of how much the mesh will be randomly scaled
MaxAsteroidScale: the maximum value of how much the mesh will be randomly scaled
AccelChange: is a torque option, if you disable it you will need a very big torque value to start rotate your asteroid
MinRotationTorque: the minimum value for random torque force applied to the asteroid
MinRotationTorque: the maximum value for random torque force applied to the asteroid
OverrideMass: override the mass of the static mesh
MassInKg: custom mass value (used if OverrideMass is set to true)

StartCullInstance: distance from camera at which each instance begins to fade out
EndCullInstance: distance from camera at which each instance completely fades out

SPECIAL THANKS

Tech Art Aid [MENTION=5535]Oskar Świerad[/MENTION] for his nice and usefull tutorials.
Ketchum for the sun shader
DwunkenPenguin for the planet shader

1 Like

This is surprising to me. Visual range / culling aside, is simulating physics really faster than manually changing transforms? If I have a twin-stick shooter where the player can shoot a machine gun (up to say ~100 bullets being instanced at any given time), would it be better to simulate physics on the bullets or manually update their positions each frame?

In my case yes, because we are talking to manually update thousand of instances, for now spawn a few blueprints that simulate physics is a better solution. For a case like your could be different but keep in mind that avoid “heavy” operation on tick is usually a good practice.

:slight_smile:

Nice method to get some nice real physics asteroids .you can always add some delay to the tick to get better performance as not every single move/trace need to be calculated every frame , what was your PC spec if i may ask ?

I’ve updated this demo to be able to handle different asteroid field shapes (sphere, elipse, donut) and use several different meshes for individual asteroids. If anyone is interested, PM me and I will upload the demo.

this is really cool. i was wondering how could you change this so you could get a disc of asteroids around a sphere? like on ringed planets?

Have you set “Mark dirty” only on last instance that you update?

Sorry if i reply only now but i don’t understand what you mean :frowning:

He was referring to Update Instance Transform. On that node you have the checkbox for “Mark Render State Dirty”. Quoting from the doc:

Thanks, nope because in the visible range area i remove instances and spawn a separate single blueprint asteroid actor.

It’s the first time i see that node, could be was introduced after the 4.14?

This is interesting because probably i will able to remove the spawn system for asteroids that rotates and instead directly rotate the instances of the HISM and save performance! I need to do some test when i have time.

Hi there, i’m getting this issue where it says “Object Object reference is not compatible with Actor object reference” check this image: https://i.imgur.com/JjBlmtE.png
Same goes for connecting it to the Static mesh. I tried everything, even casting to the BP_Asteroid, which made it compile, but the asteroids are not showing up in the editor. Hope you can help, thanks in advance!

Is the BPInstances array variable type set to “BP Asteroid”?

Thanks for the help! it wasn’t set to BP Asteroid, for some reason it was set to Object. Anyway, everything in the blueprint looks good now, looks exactly how you original does (i created a PlayerCameraTransform event dispatcher for my pawn as well) - but it doesn’t seem to swap out the asteroids. Here’s an image if that helps: https://i.imgur.com/eyMnCnH.jpg

There’s no errors in the blueprint, so i don’t know what’s causing it. Thanks again.

EDIT: I’ve also enabled “Show Debug Traces” but as you can see, they’re not showing for some reason.

EDIT 2: Also, when turning on debug for the BP_Asteroid, it comes up with these errors: https://i.imgur.com/JFumWFQ.jpg

Hard to understand what’s wrong, are you calling the PlayerCameraTransform dispatcher on Tick in your pawn?

Like this:


EDIT:

Also have you set default values for variables (if are not already set)?

About your last errors, looks like some variable are not exposed, click on the link of error on the log to see about what variables the error occur.

Yes i did exactly that in my pawn, and yes all variables have default values.
Here’s some more images to maybe give you a better overview.

[Spoiler]Event graph:


Swap asteroids 1:
Swap asteroids 2:
BP_Asteroid: [/Spoiler]

Didn’t change anything in the ConstructionScript or CreateAsteroidField. As you can see, there’s a few “Variable not in scope”, don’t know if that might cause the issue?
Also do i need to add a default array element to the BPInstances? tried it, but it still doesn’t work.

EDIT: Here’s the errors i get when enabling debug on the BP_Asteroid:

[Spoiler]

[/Spoiler]

As you can see, it “Accessed none trying to read property… DynamicCast_AsSpaceship_I_BP” which connects to my Camera, which as you can see in the BP_Asteroid image i attached further up says “Variable not in scope”. So maybe that’s causing the issue, i’m not sure though. Don’t know how to fix the Variable not in scope thing, if it even is that, that causes the issue. Hope you can help, thanks again.

Could be there is something wrong with your pawn, i can only suggest to use break points and start debug step by step.

I’m quite frankly stuck, i’ve tried debugging using break points, but i can’t figure out what the issue is. I’ve connected the Get (a copy) node to Set Asteroid Field in the WB_DebugHUD, as it was disconnected for some reason in your original file, and that gave me the numbers in the HUD. The HUD is also telling me it doesn’t add any Blueprint Asteroids. There might be other nodes there should be connected but isn’t, i have basic BP knowledge, but i’m not good enough to fully understand why everything is and should be connected in your BP’s. I don’t suppose you could take a look at the files? Thanks again.

Yeah, it’s hard understand what’s going wrong without have hands on it, if you want you can upload somewhere your project and send me a link via pm, i will look into it and hope to solve your issue.

:slight_smile:

Thanks a lot Zio, i managed to figure out the issue though. It seems it was caused by not spawing in the pawn, but rather possessing it via my character. So now i’ve set the pawn to auto possess, and it works completely fine. I have no idea how to fix this though, maybe you have an idea?

Thanks again :slight_smile:

I know is a stupid question but have you set your character as default pawn in your game mode? :smiley: