I have a simple scroller racing game where you move your car by dragging with your finger. I'd like to rotate the car to left and right when you move it. I was able to do it, but it was jittery since im doing movement not by Rigigbody, but by changing the transform itself.
In the end the problem was in the velocity calculation, it was making things so jittery;
Is there a way to calculate object's velocity (not Rigidboyd's) smoothly?
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerTouchControls : MonoBehaviour
{
float deltaX, deltaY;
float targetX, targetY;
Rigidbody2D rigidbody;
float velocityH;
[SerializeField] Vector2 velocity;
[Header("Speed")]
[SerializeField] float speedCap;
[Header("Sway")]
[SerializeField] float swayMultiplier;
[SerializeField] float swaySmoothness;
[SerializeField] float velocitySmoothness;
[SerializeField] float velocitySpeed;
private void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
Physics.IgnoreLayerCollision(3, 7, true);
}
private void Update()
{
TouchMovement();
StartCoroutine(CalculateVelocity());
}
private void FixedUpdate()
{
Sway();
}
void TouchMovement()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
Vector2 touchPos = Camera.main.ScreenToWorldPoint(touch.position);
switch (touch.phase)
{
case TouchPhase.Began:
deltaX = touchPos.x - transform.position.x;
deltaY = touchPos.y - transform.position.y;
break;
case TouchPhase.Moved:
targetX = touchPos.x - deltaX;
targetY = touchPos.y - deltaY;
Vector2 targetPos = new Vector2(targetX, targetY);
rigidbody.MovePosition(Vector2.MoveTowards(transform.position, targetPos, speedCap));
break;
case TouchPhase.Ended:
rigidbody.velocity = Vector2.zero;
break;
}
}
}
IEnumerator CalculateVelocity()
{
Vector2 lastPos = new Vector2(transform.position.x, transform.position.z);
yield return new WaitForFixedUpdate();
Vector2 vel = Vector2.SmoothDamp(lastPos, transform.position, ref velocity, velocitySmoothness, velocitySpeed, Time.deltaTime);
velocityH = vel.x;
}
void Sway()
{
float movementX = velocityH * swayMultiplier;
Quaternion rotationZ = Quaternion.AngleAxis(movementX, Vector3.forward);
Quaternion targetRotation = rotationZ;
transform.GetChild(0).localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, swaySmoothness * Time.fixedDeltaTime);
}
private void OnDrawGizmos()
{
#region Target Gizmo
Vector3 targetPos = new Vector3(targetX, targetY, 0);
Gizmos.color = Color.blue;
Gizmos.DrawSphere(targetPos, 0.05f);
#endregion
}
}
Tried multiple ways to smooth out the velocity calculation but italways turned out jittery;