SpriteKit: many assets with physicsBody on scene - swift

I'm trying to build a 2D, orthogonal game that generates the map randomly. Many of tiles in the map are gatherable resources that the player character can interact with. In order to achieve this, a Agents/Components approach is used, giving these entities a physics body (with isDynamic set to false to avoid unnecessary calculations) in order to detect collisions (i.e. when the player reaches a resource and attempts to gather it). SpriteKit seems to quickly be unable to handle anything bigger a small 150x150 map memorywise, on the actual target device.
Is this approach fundamentally flawed? Is Unity a better choice in this case?

This can be a solution:
Create a pool for physics body of each type, like pool for trees physics bodies, stones and etc.
It will be empty for a moment, for each element in the array at the beginning of a game check for close objects to the player, iterating through 60k array will be faster, then background calculation of all physics moments and holding 60k physics bodies in memory. To check for the close objects there is no need for you to count correct distance(doing pow(x, 2) + pow(y, 2) is not an easy operation), it will be enough for you to mark object as close if abs(player.x - obj.x) < 100 && abs(player.y - obj.y) < 100 is true. This operation costs less, and it is still better.
2.1 If true. Then you take a physics body from the pool and assign it to this node or create a new physics body of pool is empty.
2.2 If false. Then you save physics body of this node to the pool and remove it from the node
Its not a perfect solution, I'm not sure if it will give you a lot of profit, but it will decrease a number of physics body on a scene paying for such move with an iterating through a big array(that shall not take a lot of time), and making a basic operations like + and abs.
It's in your choice, when you should such checks, this can be by a Timer, or in update, or every time, you player moves on some constant distance(like every 100points), it can be an experimental part.

Related

How do I make a SKSpriteNode avoid another SKSpriteNode?

I am working on an AI mode for a SpriteKit game I am making in Xcode. I have dynamic physics bodies which can be launched towards the AI. I want to make it so that when one of these bodies is within a certain radius of the AI, the AI tries to dodge it. I have started working through different routes and got decent results.
1st method (pseudocode): Check AI.position.x and AI.position.y and compare to incomingSprite.position.x and incomingSprite.position.y. Break this comparison into quadrants if both x and y are within radius. (i.e. incomingSprite is bottom left relative to AI, bottom right, etc). Based on this info move the AI's position to move away from it.
cons:
-lots of code and calculations in update function to account for multiple incoming sprites
-depending on dx and dy of incoming sprite, the AI often make illogical decision
2nd method (pseudocode): Calculate distance from AI to incomingSprite. Then check dx and dy of incomingSprite and set dx and dy to go in reverse direction of incomingSprite. This seems logical. I am a little rusty on reversing vectors to do this. I feel like this might be possibly a good idea though.
Is there a better method to accomplish this? Perhaps a force field on the magnet I could use to repel the AI at a certain strength so that if the incomingSprite is fast enough it will override and still collide anyway? Im concerned about memory as most of the AI logic is in the update function, which can cause big problems if I'm not careful.
Edit: I decided to use the electric field and gave the incoming sprites a positive charge so that they are repelled by the AI. This makes things accurate/lightweight and more interesting. If the incoming sprites are fast enough, they will break through the electric field and still collide with AI. This also gives room as an additional difficulty parameter in my game (the stronger the field, the harder it is to get the incoming sprites to collide with the AI).

UE4 get all players in FoV

I'm trying to build an array of all player pawns that are in the players FoV cone. I'd prefer to not have to loop through GetAllActorsofClass for obvious performance reasons. This will be done every tick.
GetAllActorsOfClass iterates over a hash table of things of that class. Even with 100 players it is unlikely to be very costly. I would imagine that a "get actors in frustum" would just do that under the hood.
If you are okay with using it, from there you would use ConvertWorldLocationToScreenLocation and compare that to the screen bounds coordinates with GetViewportSize.
The only method the wouldn't use GetAllActorsOfClass I can think of offhand is to calculate the size of the rectangle at the "end" of the frustum, using a giant multi box trace, and filtering based on the dot product. Traces are cheap, dot product is cheap. Whether or not it's cheaper than GetAllActorsOfClass is going to be specific to your game.
If performance is really a problem the best solution is to use code. Depending on your implementation you might be able to use Blueprint nativization to get an extra boost without digging into code.
Use MultiSphereTrace from your player to his FOV direction and loop through hit results.
Make sure you set the collision layer correctly so the trace only interact with target player.
I do this on my mobile game with around 10-20 actors per frame, and it works fine.

SceneKit memory management issues

So I am playing around with SceneKit (in Swift), and for pure fun, creating an endless runner style game. In the game scene, I have a character moving forward on the z-axis. I have setup a few objects that are repeatedly created when the last expires. Most of these objects are under a node hierarchy. So, I have attempted these two methods for memory management:
Method 1: I have an invisible plane. Only 'special' parent node bodies can collide with this plane. So when the parent node's physics body collides with it, I remove it from the parent, which in result the node removes all of its children.
Method 2: Again I have an invisible plane. Except in this method everything I would potentially like to remove, can and does collide with the invisible plane on it's own accord. So in plain, everything collides with the invisible plane and removes itself from it's parent.
Now. Everything runs and works well. Except when it comes to removing nodes from their parents, I see a noticeable jolt in the framerate or speed of the game. Just for a second or so. With method 1, the jolt happens once for every time a parent node collides with my invisible plane. With method 2, the jolts are continuous and framerate is continuously low and jumpy.
I would be interested in hearing knowledge on ways of achieving something like this smoothly!
A big thanks in advance.

AI Awareness with Unity3D

I am currently developing an AI system in Unity3D and am wondering if anyone could suggest which of the following awareness models are better?
Use Physics.OverlapSphere at a constant rate of about every 2 seconds to check a range for anything of interest.
Use a Sphere Trigger Collider that is attached to the AI, when an object enters this trigger it starts getting monitored.
Mostly worried about performance vs quality, I have a feeling that model 1 is faster until the AI needs to check everything around it for a particular item, in which case model 2 would return quicker as it already has the collection of local interests. However, will model 2 take up more resources as a trigger collider needs to be sending out checks every physics update?
Your 2nd approach is best way to do it, even though,i can easily say that it all depends on your requirements and both have their own uses. (I am "only absolute way of doing things kinda guy")
With Trigger
void OnTriggerEnter(Collider other)
you can only get one collision body out of many that have collided. It is faster if you have large collisions and u can definetly expand and contract the radius of your trigger to almost use it as the same effect as overlapping sphere (but not recommended for guaranteed results). As it detects only one collided body its not processor intensive.
With Overlap sphere approach you can
Collider[] OverlapSphere(Vector3 position, float radius, int layerMask, QueryTriggerInteraction queryTriggerInteraction);
you can get collider[] or multiple collision bodies that have collided. This is processor intensive, if you have 50 objects colliding and performance will drop the time you call upon this function.
Another Approach.
For simplicity and proper design of mechanics, Trigger bodies can solve for any complicated scenario. I must advice you, from my experience it is always the perspective you rely upon to solve your problem is the factor that will limit your thoughts and ultimately your results.
Keeping that in mind, I would like you try this approach...create a method that uses
public static float Distance(Vector3 a, Vector3 b);
to give you a boolean answer to detect your actor. It is a very good approach since only a language primitive is streamed (between 2 actors) and not an object and performance of in-built function is just negligible. You can have each enemy actor register themselves (their reference) in the List (to get all actors of interest) inside main actor actor if they are at desired proximity (so yes your enemy checks whether its close than the main actor and tells the actor that he is the one who is very close).
I have tested this approach with 20 other actors having their own scripts running in ipod gen 5, with almost no performance drop.

interaction with objects in xna

I'm new to using xna and I want to make my player collide with with multipe walls from the same class. So I looked around and I understood that the best way for doing that is to create a list of variables containing the walls id's and make a loop that circles them all and then returns the variable of the objects that collide.
My question is if there is a faster more efficient way for doing that? I mean if I have like 10000 objects that loop can cause a lot of memory use.
Thx in advance
Option 1) If these 10000 object are walls of a level, then you should probably use some sort of grid (like this very old example: https://en.wikipedia.org/wiki/The_Legend_of_Zelda#mediaviewer/File:Legend_of_Zelda_NES.PNG)
With a grid you only have to check collision with adjacent objects, or only with objects that are nearby.
Option 2) If these 10000 objects are enemies or bullets that move more freely, then you could also calculate the distance first and only check for collision if the objects are nearby.
But may I ask why you are using XNA? I used to work with XNA 4.x but in my understanding it is pretty much dead (http://www.computerandvideogames.com/389018/microsoft-email-confirms-plan-to-cease-xna-support). If you're new to XNA, I would advice to use other software to make games (like Unity3D). In Unity3D the hard part of collision detection is done for you (is has standard functions for collision detection) and Unity3D also works with C# (like XNA)
You always want to do the least amount of processing to get the job done. For a tiled 2D game you usually have a 2 dimensional grid. When the player want to walk on a certain tile you can check that tile if it is allowed to walk there. In this case you just have to check a single tile. If you have a lot of NPC's you could divide your map into sections and keep track of in what sections the NPC's are. Now you just have to do collision detection on the enemies within your section.
When you need expensive collision, pixel perfect or polygon collision you should first check if an object is even close with a simple radius float or BoundingSphere only then you go on with more expensive collision detection.
Same goes for pretty much anything, if you have a 100x100 tilemap but only need to draw 20x10 for the screen then you should just render that portion by calculations. In unreal, mappers create invisible boxes, when inside these boxes it only draws a certain part of the map and only checks collision within these boxes. GameDev is all about tricks to make things work smoothly.