Your main problem is that you're checking for input in FixedUpdate.
FixedUpdate is not guaranteed to run every frame, or only once per frame. It will run however many times the physics simulation needs to "catch up" to the current frame time, acting in fixedTimestep intervals.
So by handling input here, you run the risk of skipping or double-handling ...
I changed the code to the following by adding a TouchPhase.Began to the if statement:
public void Update()
if (Input.touchCount == 1)
if (Input.GetTouch(0).phase == TouchPhase.Began)
Touch touch = Input.GetTouch(0);
rb.gravityScale *= -1;
Then testing it on a device using unity ...
If you had input and rendering share a thread, that would allow you to mix input and output(rendering) code, making it easier to make messy code.
What I suggest you to do is to have an Input Model. That is some object that contains a representation of the input of the user. Then you update it from your event handlers (listeners? ...
Waited more than I expected. I found a simple solution for this.
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 direction = new Vector2(mousePos.x - transform.position.x, mousePos.y - transform.position.y
transform.up = direction;
Thanks @DMGregory for pointing this out.
Fixed it by initializing xAxisRotation and yAxisRotation variables to camera's start rotations and by changing the target rotation.
Initialized those at start method and i have also carefully set clamping values according to default camera x and y rotations. My start method now looks like this: