SceneKit memory management issues - swift

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.

Related

Get Orientation of SCNNode Swift [duplicate]

I am working on a basic racing game using Apple's SceneKit and am running into issues simulating a car. Using the SCNPhysicsVehicle behavior, I am able to properly set up the car and drive it using the documented methods.
However, I am unable to get the car's position. It seems logical that the SCNPhysicsVehicle would move the SCNNodes that contain the chassis and the wheels as the car moves but the SCNNodes remain at their original position and orientation. Strangely enough, the chassis' SCNPhysicsBody's velocity remains accurate throughout the simulation so I can assume that the car's position is based off of the SCNPhysicsBody and not the SCNNode. Unfortunately, there is no documented method that I have found to get an SCNPhysicsBody's position.
Getting a car's position should be trivial and is essential to create a racing game but I can't seem to find any way of getting it. Any thoughts or suggestions would be appreciated.
Scene Kit automatically updates the position of the node that owns an SCNPhysicsBody based on the physics simulation, so SCNNode.position is the right property to look for.
The catch is that there are actually two versions of that node in play. The one you typically access is called the "model" node. It reflects the target values for properties you set, even if you set those properties through an animation. The presentationNode reflects the state of the node currently being rendered — if an animation is in progress, the node's properties have intermediate values, not the target values of the animation.
Actions, physics, constraints, and any scene graph changes you make inside update/render loop methods directly target the "presentation" version of your scene graph. So, to read node properties that have been set by the physics simulation, get the presentationNode for the node you're interested in (the node that owns the vehicle's chassisBody physics body), then read the presentation node's position (or other properties).
I have the same problem with my player node.
I move it with applyForce (to manage collision detection).
But when i check node position after some movement, the node position has not move (presentation node is the actual position as rickster write in his answer)
I manage to update the scnNode.position with renderer loop
You have to set position of your node with the presentationNode position.
node.position = node.presentationNode.position
Set this into renderer(_: updateAtTime) and your node position will sync with any animation you made to the physicsBody

How could I create a copy of a gameobject hierachy which mimics all positions, movements, etc of the original? Like a hologram of the original?

I am building a 3d Billiard game in VR using Unity3d.
I try to display a miniature copy of the billiard "table" (actually a cube), like it is at any given moment.
I tried instantiating the root of the billiard hierarchy, just to find out it will instantiate the original gameObject (runnings its Start() methods) which totally makes sense, just not what i am trying to do.
In practice I have a billiard root, which has all the geometry of the table, and all balls as children, those balls can interact physically.
On button press I try to create a hologram of the table, with all its balls at their position at any given time.
So If a player hits a ball and it moves in the original, it should display the same in the miniature.
I thought it might be possible to translate the ball positions (and table rotation etc) every frame to the miniature. but that seams very un optimal.
var midPoint = (leftHand.transform.position + rightHand.transform.position) / 2;
var miniature = Instantiate(gameObject, midPoint, transform.rotation);
miniature.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
this obviously does not work as i described above. It creates a completely new instance of the billiard cube. (this code was run from a script inside the billiard root)
The board itself probably doesn't move, so you can just make holograms and simulate the balls.
Since Unity 2018.2, you can create physics scenes and simulate them manually.
For that problem you would need to:
Stop physics simulations.
Physics.autoSimulation = false;
Create a new scene for independent physics simulation.
var physicsPreviewScene = SceneManager.CreateScene("Physics Preview Scene", sceneParams);
Copy the physics-relevant objects and components to the preview scene.
Many ways to do it, but basically colliders, rigidbodies, and for objects you need visuals for, renderers.
You can use caching to avoid creating these every time.
You can also, in theory, have the simulation on the main scene, but then you need to make kinematic all the stuff you don't want simulated, and there are some gotchas.
Then simulate manually.
Get the PhysicsScene from the preview scene: var physicsScene = physicsPreviewScene.GetPhysicsScene();
Simulate: physicsScene.Simulate();
So yea, short of avoiding the components unrelated to physics in the copies, you can't avoid the duplicates; only mitigate their impact with pooling and/or caching.
Another technique is to use casting (spherecasting, in this case) to make a mockup physics simulation, stepping multiple casts with velocity, acceleration (gravity for example) and Time.fixedDeltaTime, and reacting to intercepts/hits as collisions, with Vector3.Reflector something similar. But this will only give you an approximation of how physics would react, and is not going to be an actual (accurate) physics simulation like having multiple PhysicsScenes will.

SKEmitterNode explosion with force to another Object

I've an explosion in my SKScene and I want this Explosion even effect another objects close to its , Object are in all sides .I want to give them force to run away with this explosion .
It sounds like you need an SKFieldNode implementing a vortexField():
https://developer.apple.com/reference/spritekit/skfieldnode#1654415
SKFieldNode:
A node that applies physics effects to a portion of the scene.
vortextField()
Creates a field node that applies a perpendicular force to physics bodies.

Small, "bouncy" lags when pushing an SKShapeNode with another shape moved by an SKAction

I am creating a 2D autoscroller and when my player (with a circle physicsBody) collides with an SKAction moveTo-powered obstacle which is moving towards it, it makes small, almost unnoticable lags. I tried lowering the friction and the density of the objects, but nothing helped. Any ideas?
You have chosen to use a circle with phycsicsBody. An SKPhysicsBody object is used to add physics simulation to a node. When a scene processes a new frame, it performs physics calculations on physics bodies attached to nodes in the scene. These calculations include gravity, friction, and collisions with other bodies. After the scene completes these calculations, it updates the positions and orientations of the node objects.
You have also chosen to use SKActions, when using the actions to move a body such changes don't go through the physics engine, indeed usually you could add unwanted actions and unexpected events as "bouncy lags".
So, if you're using physics to move a body, you shouldn't use move actions, apply an impulse or force, or set it's velocity directly
Setting restitution to zero may help. This controls the elasticity, or bounciness of a sprite.

How to detect collision between three objects simultaneously in Box2D?

I am new to Objective-C. I am currently working on a game using Cocos2D and Box2D. My problem is that when 3 objects collide together, the game crashes. Now let me describe my game in details:
In my game I have a main character standing on top of a building. Below the building there's this the road. Enemies pass by the road at various random speeds entering the screen from right and exiting from the left. I have created the enemies as b2_kinematicBodies and set a random velocity for each of them using SetLinearVelocity(). The main character shoots the enemies. The projectile (the object being shot) is a b2_dynamicBody. When the projectile hits the enemies, both the projectile and the enemy are destroyed. During gameplay sometimes an enemy moving at a slow speed is crossed by one which is moving at a higher speed. If a projectile hits the two enemies just at the point when they are overlapping and one is about to pass the other one, the game crashes! Please help me with this.
I have detected collision using b2contactListener class.
One thing I didn't mention before is that I am not creating the enemies as individual distinct bodies. Instead, I am creating it once and making it move and I am calling this method (which creates the enemies and makes them move) inside init as below:
[self schedule:#selector(addRightTarget) interval:2.0];
I believe the issue is that the collisions are calculated before your handler gets any calls. Meaning that when your handler gets called, the bullet has hit 2 objects. So you get 2 call-backs as shown below.
Collision Detected: Bullet + Enemy1
Destroy Enemy1
Destroy Bullet
Collision Detected: Bullet + Enemy2
Destroy Enemy2
Destroy Bullet [CRAAAASH!!! You just tried to delete a non-existent object]
1st: You should not be removing anything except in your step function (as someone mentioned in another answer)
2nd: Pick one of these:
Make your list/array of objects-to-delete be a 'set' or implemented in such a way that duplicates are avoided.
Check for existence of your object in the world
The collision only happens between 2 objects in Box2D. So in your mentioned scenario your will get multiple collision events which could be,
Enemy-1 and Enemy-2
Enemy-1 and Bullet
Enemy-2 and Bullet
So one possible reason of crash could be that you are not expecting (Enemy-1 and Enemy-2) collision and you are handling it like you have collision between (Enemy-1 and Bullet) so you might be casting it into wrong class. Make sure you are checking the kind of class "isKindOf" before casting it.
Also you may want to use Contact Filtering and or assign category masks to your enemies so that they don't collide with each other and only collide with bullet.
But it will be more help full if you tell something about how and where you destroy your bodies (I hope its not inside your Collision Detection Functions) and also if you can share the exception text when your application crash, that will be helpful.
I used a rather cheap workaround. I alternately created enemy fixtures of different sizes(differing by few pixels). So now if i shoot them even when they overlap, the app doesn't crash(because only the bigger object collides and gets destroyed). This serves my purpose. Thanx a llot for your help. I really appreciate it! :)