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? - unity3d

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.

Related

How do I check for and resolve collisions within FixedUpdate using a kinematic rigidbody?

I have been working on my own kinematic character controller for a while, but only recently learned that one should consider updating its position and rotation using Rigidbody.MovePosition and Rigidbody.MoveRotation instead of directly modifying the Transform component, which is what I am doing now. While my controller works fine, and does not cause any noticeable performance impact in my small games, I want to better understand the benefits of manipulating the Rigidbody component, and especially how this all works within FixedUpdate instead of Update.
To be clear about the supposed impacts on performance, Unity's manual on 2D rigidbodies says:
Any Collider 2D component added to the same GameObject or child GameObject is implicitly attached to that Rigidbody 2D. When a Collider 2D is attached to the Rigidbody 2D, it moves with it. A Collider 2D should never be moved directly using the Transform or any collider offset; the Rigidbody 2D should be moved instead. This offers the best performance and ensures correct collision detection.
Right now, my basic controller loop looks like this in the Update method:
Read the user's input velocity
Modify the controller's velocity based on this input (this velocity is distinct from Rigidbody.velocity)
Using Physics queries, sweep the controller's body against the appropriate collision layers by velocity * Time.deltaTime
Pick a collision resolution position based on a set of rules
Set the controller's Transform.position to this resolution position
I also have a method that moves the controller using Transform.Translate if no collision detection is needed.
As you can see, though my controller GameObject has a kinematic rigidbody attached to it, I never actually use it for anything. Unity's documentation on kinematic rigidbodies is conflicting, stating here:
Note: MovePosition is intended for use with kinematic rigidbodies.
but also here:
If isKinematic is enabled...The rigidbody will be under full control of animation or script control by changing transform.position
I am also unsure about how to manually check for collisions within FixedUpdate, as I have read that FixedUpdate can be called more than once per frame. Frankly, I thought FixedUpdate was only supposed to be used with dynamic rigidbodies to simulate real physics, and thus have only used this method for simple manipulation of those kinds of rigidbodies.
And then Rigidbody.MovePosition states that
2D rigidbodies have a fixed limit on how fast they can move therefore attempting to move large distances over short time-scales can result in the rigidbody not reaching the specified position during the next physics update. It is recommended that you use this for relatively small distance movements only.
What if my character needs to move a very large amount? Do I just set Rigidbody.position directly?
I guess I am trying to figure out how I can reconcile all of this logic to conform to what Unity says is best for performance. Perhaps I need to combine Update and FixedUpdate, but ultimately I am just hoping to receive some clarification and guidance regarding all of this.

Unity Player passsing through objects

player and object both have colliders and rigidbodies, object has position and rotation locked, player has only rotation locked. When the player goes to the blocks, the player goes through the blocks, although they do give a bit of resistance. To move the player im setting the rigidbody's velocity, and doing that in FixedUpdate.
i have no idea why this is happening, any ideas?
main part of the code is:
rigidBody.velocity = new Vector3(direction.x, rigidBody.velocity.y + (-Gravity * Time.deltaTime), direction.z);
(direction is determined by the WASD keys, and i'm using my own gravity)
First of all, you do not need to multiply the velocity by time.DeltaTime, because you are moving your object in the FixedUpdate() method; Which uses fixed time intervals since the physics engine does not run in sync with the regular game engine. Also, both objects do not need rigidbodies in order to collide with one another. I suggest looking at your collision matrix in settings and verifying that everything you need collision for is checked correctly. As others have said as well, check your kinematics on the rigidbody.
A last suggestion for working with your own gravity. Do not change the actual gravity value of the game engine. It is typically recommended that you use a multiplier variable and apply it to the constant gravity already set by the physics engine. If you are completely editing the gravity, than maybe consider using a character controller instead.
I guess it has something to do with what the documentation says "In most cases you should not modify the velocity directly, as this can result in unrealistic behaviour".
Try to use AddForce() or similar functions to alter the properties of the rigid body. Colliders etc will then work as expected.

How to change game speed in mid development without touching the Timescale in Unity (2D)?

I have a game similar to Sand balls and I was wondering how can I speed up the game a bit without touching the timescale? A nice and somehow correct approach would be to scale down all my objects so gravity can also "affect" the drop movement. I already tested that and works as expected, except I have to apply that for 100+ levels... and would break some prefabs (a mass level editor to scale by bounding box would work but that's another story)
On the other hand, I have timescale but feels like it's the incorrect approach since it also affects animations and leads to unwanted behaviors.
So... do you know any other ways to speed up the game?
If objects is falling down, you can increase gravity. Or without touching timescale, you can just create a public speed multiplier variable and set it to 1 at start.
If you only move balls (Assumed from give sand balls reference), just multiply speed variable of ball with public speed multiplier variable. When you want to change the speed, just change the variable. As an example:
var ballSpeed = baseBallSpeed * speedMultiplier;

Best way to move a game object in Unity 3D

I'm going through a few different Unity tutorials and the way a game object is moved around in each is a little different.
What are the pros/cons to each of these methods and which is preferred for a first person RPG?
// Here I use MovePosition function on the rigid body of this component
Rigidbody.MovePosition(m_Rigidbody.position + movement);
//Here I apply force to the rigid body and am able to choose force mode
Rigidbody.AddForce(15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
// Here I directly change a transforms position value, in this case the cam
Transform.transform.position = playerTransform.position + cameraOffset;
Thanks!!
EDIT;
Something I have noticed is that the applied force seems to memic wheeled vehicles while the position changes memic walking/running.
RigidBodies and Velocities/Physics
The only time, I personally have used the rigidbodys system was when implementing my own boids (flocking behaviour) as you need to calculate a few separate vectors and apply them all to the unit.
Rigidbody.MovePosition(m_Rigidbody.position + movement);
This calculates a movement vector towards a target for you using the physics system, so the object's velocity and movement can still be affected by drag, angular drag and so on.
This particular function is a wrapper around Rigidbody.AddForce I believe.
Pros :
Good if realistic physical reactions is something you are going for
Cons:
A bit unwieldy to use if all you are trying to achieve is moving a object from point A to point B.
Sometimes an errant setting set too high somewhere (for example: Mass > 10000000) can cause really screwy bugs in behaviour that can be quite a pain to pin down and mitigate.
Notes: Rigidbodies when colliding with another Rigidbody would bounce from each other depending on physics settings.
They are also affected by gravity. Basically they try to mimic real life objects but it can be sometimes difficult to tame the objects and make them do exactly what you want.
And Rigidbody.AddForce is basically the same as above except you calculate the vector yourself.
So for example to get a vector towards a target you would do
Vector3 target = target.position - myPosition;
Rigidbody.AddForce(target * 15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
If you don't plan on having any major physics mechanics in your game, I would suggest moving by interpolating the objects position.
As it is far easier to get things to behave how you want, unless of course you are going for physical realism!
Interpolating the units position
Pros :
Perhaps a little strange to understand at first but far simpler to make objects move how you want
Cons:
If you wanted realistic reactions to objects impacting you'd have to do a lot of the work yourself. But sometimes this is preferable to using a physics system then trying, as I've said earlier to tame it.
You would use the technique in say a Pokemon game, you don't stop in Pokemon and wait for ash to stop skidding or hit a wall and bounce uncontrollably backwards.
This particular function is setting the objects position like teleporting but you can also use this to move the character smoothly to a position. I suggest looking up 'tweens' for smoothly interpolating between variables.
//change the characters x by + 1 every tick,
Transform.transform.position.x += 1f;
Rigidbody.MovePosition(m_Rigidbody.position + movement);
From the docs:
If Rigidbody interpolation is enabled on the Rigidbody, calling Rigidbody.MovePosition results in a smooth transition between the two positions in any intermediate frames rendered. This should be used if you want to continuously move a rigidbody in each FixedUpdate.
https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html
Rigidbody.AddForce(15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
This will make the object accelerate, so it won't travel at a constant velocity (this is because of Newton's second law, Force=mass*acceleration). Also if you have another force going in the opposite direction this force could get cancelled out and the object won't move at all.
Transform.transform.position = playerTransform.position + cameraOffset;
This will teleport the object. No smooth transition, no interaction with any forces already in the game, just an instant change in position.

LookAt while Hinge Jointed

I do not understand, why jointed object can't look at target.
Example: 2 boxes with hinge joint (anchor is at the touching place) and a target object. When I say A-box to lookAt target, I think it will just turn on X-axis. But both of the boxes start to shake. Why?
Take a moment to reflect on what a call to LookAt is trying to do.
It's rotating the transform while ignoring physics.
That's bound to create problems, since you're not rotating the whole system, you're moving one part of it. Your rotation with LookAt is "fighting" with the adjustments the physics system is trying to make.
To solve that conflict you can do one of the following:
Rotate the entire system (both cubes). This will involve putting them all under one transform, and having that transform rotate.
Use a physics-based approach. It won't be too hard, but won't be as simple as a function call. You'll probably need a simple PID controller such as the one outlined in this thread.