[Solved]Weird Time.timeScale behavior
I have a bunch of spheres is a scene that all have this drag object script:
public class drag : MonoBehaviour { private Vector3 mOffset; private float mZCoord;
void OnMouseDown()
{
mZCoord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
// Store offset = gameobject world pos - mouse world pos
mOffset = gameObject.transform.position - GetMouseAsWorldPoint();
}
private Vector3 GetMouseAsWorldPoint()
{
// Pixel coordinates of mouse (x,y)
Vector3 mousePoint = Input.mousePosition;
// z coordinate of game object on screen
mousePoint.z = mZCoord;
// Convert it to world points
return Camera.main.ScreenToWorldPoint(mousePoint);
}
void OnMouseDrag()
{
transform.position = GetMouseAsWorldPoint() + mOffset;
Debug.Log(this.transform.position);
}
} This script works great until time.timescale is set to 0 via a UI button. while the game is paused, the object can be dragged once normally, but then to move the object again, you must move your mouse to the original location before the drag instead of the actual position.
Steps to re-create: 1.Make a new 2d game
2.Make a sphere, attach the above script
3.Set time scale to 0
4.Try and drag the sphere twice
I can send my project if necessary
I have tried to reproduce with no luck, it is working fine for me
What version of unity are you using? I tried 2018.3.14f1 and 2019.1.0f2.
Answer by BeanBoy29 · Jul 26, 2019 at 12:02 AM
I found a weird solution, first you need to save all the stats temporally and remove the rigidbody in the OnMouseDrag function. Then add the rigidbody and its stats back in the OnMouseUp function. I dont know why it works, but it dose.
Answer by xxmariofer · Jul 05, 2019 at 07:55 PM
ill share it as an answer, but you are right, tested now in the 2018 lts version and there is that bug, i have rechecked in the version 2018.1.9.f2 and in that version its working fine without issues the same script, the Collider component changed while in mousedrag event, but right after the onmouseup event is fired the center of the box collider gets reseted, ill report it as a bug
this doesnt feel correct but this is what i got answered:
Hello,
Upon further analysis, our developers concluded that this behavior is expected. Setting Time.timeScale to zero stops the "FixedUpdate" function from being called, and so the physics are not simulated (https://docs.unity3d.com/ScriptReference/Time-timeScale.html). It's unclear why it behaved differently in the past, but this behavior is logical and well documented.
If you still want to simulate physics while the timeScale is set to zero, I recommend using "Physics.Simulate" method to manually control the simulation on-demand (https://docs.unity3d.com/ScriptReference/Physics.Simulate.html). For example, I was able to implement your expected behavior in the attached case by using this method in "On$$anonymous$$ouseUp" function.
If you have more questions, do contact us again!
It doesn't sit right with me either, but it will have to do. What do I need to reset with On$$anonymous$$ouseUp? In the inspector everything is correct with the collider.
Answer by Fantasieleben · Jun 12, 2021 at 11:24 AM
Just had the same issue and discovered this thread, so I want to share the solution that I went with.
The problem we had is that by setting Time.TimeScale
to 0 we pause the FixedUpdate by Physics. This is however where transforms and the colliders that are required for clicking on the object with the mouse get synced.
In my project the preferred solution was to use Physics.SyncTransforms:
void OnMouseDrag()
{
transform.position = GetMouseAsWorldPoint() + mOffset;
Physics.SyncTransforms();
}
Sometimes you might want to change the setting more permanently with Physics.autoSyncTransforms, see documentation.
Documentation:
https://docs.unity3d.com/ScriptReference/Physics.SyncTransforms.html
https://docs.unity3d.com/ScriptReference/Physics-autoSyncTransforms.html
By the way the currently accepted solution circumvents the issue by deleting and re-adding a rigidbody, which if you look at the performance is less optimal than syncing transforms. Whilst I don't know for sure I am assuming what deleting/re-adding does for you is basically forcing an internal Physics.SyncTransforms() call, but it would come with a lot of additional calls and would produce garbage for the garbage collector.
Your answer
Follow this Question
Related Questions
My gameobject stops moving after entering the trigger?? 2 Answers
Detect overlapping objects 2D game 0 Answers
Transform.position of object not the same as shown on the inspector 1 Answer
How can i choose object with mouse ? 0 Answers
Is there a way to allow the user to change the position of the game object in game? 0 Answers