I was able to easily locate my world camera and generate a reference to move the camera around. If anyone has input towards my other questions I’d appreciate the help very much.
Progress thus far
I created a camera blueprint named “CameraBP” and placed it in the viewport. I also created a variable within the MyCharacter(player controlled) blueprint named “WorldCamera” of CameraBP type and used the custom event below to find my CameraBP.
First if you do not develop this for mobile do not worry much with blueprint performance, well not until you have more than 100 objects to check.
Then top and best (or first line) optimization should be cull distance, either use trigonometry to find distance from Camera when to cull (if camera can zoom in), or use curve graph for it. Or just flat cull out above some distance. This is cheapest.
You have ortho camera, soo i assume some kind of scroller or strategy/tower defense or topdown view. For this you should dynamically create and destroy tiles (or objects).
Make 3 squares on your map froms smalles to biggest:
most inner one, that is in camera view or right next to it (like 2 times margin). the one where you just do not mess with create and destroy.
medium one. one that is mor than 2 tiles away from camera edge and less than 6-8 tiles (engine needs time for streaming in). you watch all tiles hare and create ones on sides that player is moving to.
outer one, that is outside camera view. You destroy everything there.
Now most efficient way of implementing this:
You need big array (x*y size) with pointers to tiles. Easiest way would be if every tile was very simple blueprint.
Now you need functions that can create row or column, and other that can destroy row or column.
You call that functions for edges that player is moving to and for ones that are outside of scope.
Easiest way, slightly slower, but much less code:
Depending on how fast player can move. Calculate shortest time for player to cross one tile, this will be you time to do the loop/update.
Make each tile as blueprint like above. Each one should have variable “last updated seconds” get this from “get game seconds”. When time is more than shortest crossing time (see above) update this tile.
This is quite big optimization compared to checking this all every tick. So when there is time to update, check distance to center tile. And create destroy stuff like i described on top. You can use event dispatchers here, register/unregister blueprints to create/destroy event. Or just do event tick with that checking for “last update” time at very beginning in each blueprint tile.
If you do not have tiles, apply above but with plain distance to camera location.
I must admit I hadn’t thought about this for my mobile project… Is there some sort of way to get a benchmark whether you’ll need to cull objects or not? My levels are fairly small, top down view and might get up 16 camera views wide.
I did come across the same problem though, parallaxing in an ortho view. I decided it wasn’t worth the effort and pulled my camera further back and made the lens longer. This way I don’t have to do tick event motions for all my placed actors, find what’s in view etc. It’ll also be quicker to develop maps as I can place them in 3d and that will dictate how fast the objects will move. I can also get a 3d feel to things should I want to (one element travels right into camera which would look lame in ortho).
I considered placing 3D objects but that would require a perspective camera and a lot of extra work for the artist. Can’t use 2D objects with perspective because the gap between the 2D terrain and the object becomes visible when you move on Z.
I actually had another idea which felt brilliant, but feel free to correct me if I’m wrong.
What if I make a very simple blueprint for my background sprites with a collision box that extruded on the Y axis (since this is a 2D game). The character would run along X and hit the Y axis of the object. When Collision Enter begin parallaxing, when exit stop or reset back to normal position.
Yup that is great idea with collision. Very simple.
Let me give some poiners: make invisible box collision around player, size bit bigger than camera view. Set that box collision to overlap only.
Have each actor 2 events: on begin overlap and on end overlap. Check if overlapping actor is that collision box ( == checks if values are equal, and it works for actor reference).
ON begin overlap turn visibility on, on end off.
That’s a pretty good idea. I’ll give it a shot. I actually did the opposite and made collision around the props but I feel like your idea would tidy up the level a bit and require less work.
One thing I’m wondering before I go about jumping into your method, would I be forced to make a blueprint for every prop or could I just drop sprites and set a custom object type, and set the player collision to only hit that object type. From there, try to manipulate said object types in array. I’m not 100% sure how difficult that will be.
I have an idea of how I would make the blueprint. Once a prop enters camera view the math below would run on a tick.
float ParallaxSpeed = 0.1; //higher values = more movement. I would use a static value for testing but ideally the value of this float would vary depending on the Z axis of the prop.
A = (PlayerXLocation - LastPlayerXLocation) * ParallaxSpeed;
B = (PropXLocation - A);
LastPlayerXLocation = PlayerXLocation;
//when player leaves prop vicinity set LastPlayerXLocation to 0
Adjust the prop to the new X and viola!
It works when moving both left and right. When moving Left to Right A is a positive value, which causes the prop to move left when subtracting A from it’s own X; the ideal effect for parallax.
When moving Right to Left A returns a negative value causing the prop to move right when you subtract.
Not yet tested but it seems pretty sound in my head.
If you make blueprint for every prop, then all logic for show hide is decentralized ie in blueprints, and this will be very simple blueprint code. But bit messy with all props.
You can make parent blueprint that has show hide logic, then extend that class for more advanced props.
Or you can read overlap results directly from collision box and do it all centralized in pawn blueprint. This will allow you to place any actors and hide/show them, for this make chain of casts from most common actor type to last, move to next cast type every time previous failed, so you do not cast every possible type on actor that was handled already. Choice is yours.
If you are not aiming at instanced meshes (and this would complicate whole idea of show/hide) I would suggest going parent/child blueprint way for every prop. It looks more elegant imo. And you have very very simple logic in parent blueprint class only, so should be easy to extend.
As to inherited blueprint classes, they are not really inherited, it is kind of fake (or not so powerful as one would expect). But it is quite nice feature and easy to use (when you know real inherited stuff).
To play with it:
make simple blueprint, compile it
right click on in in content browser and “create child blueprint”
Now make some functions in parent blueprint, compile. And then you can access them from child bp.
You can also access parents components, however simple dragging doe not work you need to use context menu to get them into graph.
Ah, pillar of inheritance, except not because it sounds like subclassing more than anything. I could definitely see it’s uses though. In my opinion it’s better than have one blueprint that has 4 childs that benefit from each other rather than four completely specific blueprints. I’d imagine the impact is extremely minimal while child blueprints open you up to working with easier code management.
What do you consider fake about it? Creating a Blueprint Subclass is exactly single-inheritance, the same as you would do in C++, creating a new class based off of a parent class (for that matter, creating a Blueprint based off of a native C++ class works in the same way as well). We don’t allow non-virtual multiple-inheritance for a variety of reasons, but you can multiple-inherit interfaces.
Yes that is why i wrote in brackets they feel not so powerful, but after few days i need to admit that they are quite powerful, cool factor raises slowly.
I am toying with them since last weekend, so i did not discover all cool uses for them yet.
Thinking of it they are very similar to ancient Turbo Pascal stuff.
My camera has a crazy long lens for this reason, and it works out ok. Looking at your game I would imagine you would too but things are progressing nicely for you this way anyway.
Do you (or anyone here) actually expect to have to kill the actors once outside the camera view? Shouldn’t just not moving them be enough for performance? I’m just wondering if this is common practice for mobile games, and obviously hope having just static meshes will be close to just as fast.
Really depends, if your actor is blueprint with heavy calculations in event tick, then either stop them or destroy actor.
Making it invisible will not stop all the event tick processing, so probably does not save much.
But if your actor is mostly static or something instanced do not bother, unreal has nice optimizations for those.
Well one case i would consider killing static actors that are out of view is low end mobile, or again mobile for things that can collide (or overlap) frequently.