I'm creating a small endless runner where the player has to swipe up and down on the screen to move a fish. Imagine Subway Surfers where you travel smoothly as opposed to just jumping a foot to the left or right. Anyway, I am trying to make the fish rotate in the approximate direction of the player's finger and gradually rotate back when the player lets go of the screen. The program was working almost smoothly -- except for the fact that the fish was rotating back to the default position constantly, so it looked really glitchy.
The way this script works is that it takes in two Vector2 variables - the current and previous positions of the fish. It then subtracts these to get a Vector2 denoting the change in position since the last frame. I then feed it into Mathf.Atan
to get the direction of this motion. Finally, I rotate the fish by this new amount - minus its current rotation - to get it going in the right direction. I'll show the code down below. Upon investigating why this was causing the fish to consistently rotate back to 0 degrees for a couple frames, over and over, I learned that the Unity thought that the change in y position was the thing switching to zero every other frame. All of my code is operating on FixedUpdate and I don't use Update anywhere, so I have no idea why it is switching so erratically. If user touch input is measured during Update, that might be the source of the problem, but it would be nice if I could find a solution. I'm just kind of confused, and would love if someone could clear this up for me as soon as possible.
Now here's my code for the class "RotateByTouch":
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateByTouch : MonoBehaviour
{
public TrackObjectMotion trackObjectMotion;
public GameObject thisObject;
public float rotationValue;
void FixedUpdate()
{
rotationValue = Mathf.Atan(trackObjectMotion.DeltaY / trackObjectMotion.DeltaX) * Mathf.Rad2Deg;
thisObject.transform.Rotate(Vector3.forward, rotationValue - thisObject.transform.rotation.eulerAngles.z);
}
}
And here's my code for the class "TrackObjectMotion":
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TrackObjectMotion : MonoBehaviour
{
public Vector3 CurrentPosition;
public Vector3 PreviousPosition;
public float DeltaX;
public float DeltaY;
// Update is called once per frame
void FixedUpdate()
{
PreviousPosition = CurrentPosition;
CurrentPosition = this.gameObject.transform.position;
DeltaX = CurrentPosition.x - PreviousPosition.x;
DeltaY = CurrentPosition.y - PreviousPosition.y;
}
}
And finally, here's the code I used for the actual moving of the fish:
public void FixedUpdate(){
foreach(Touch touch in Input.touches){
if(touch.Phase == TouchPhase.Moved){
this.transform.Translate(0, touch.deltaPosition.y, 0);
}
}
}
That last bit is just leaving out a little bit about multiplying by constants to get the desired result, but that's not important.
Thanks in advance!
Time Settings
. As you said all your code logic loop runs inFixedUpdate
, may I know the reason? are you trying to move, rotate a rigid body object? \$\endgroup\$FixedUpdate
to run 60 times a second in theTime Settings
. I had to convert everything to FixedUpdate because I wanted to make everything run smoothly and cleanly, as opposed to using theUpdate
method. \$\endgroup\$