Reputation: 48
I'm developing a car racing game in Unity using Dreamteck Splines from the Asset Store for track generation. Currently, the car automatically follows the spline's rotation and position based on speed, but I want to implement player control where swiping on the phone allows the player to rotate the car manually, overriding the spline's rotation temporarily and make the car move in the direction it faces.
How can I achieve this while still maintaining automatic spline following when the player isn't swiping?
Removing the spline override entirely isn't an option as I still want the car to follow the track's rotation and position when the track curves and is not straight and when the touch input is stationary. Any suggestions or solutions would be greatly appreciated.
I attempted to disable spline control whenever touch movement occurs, enabling manual rotation, and implementing 'transform.Translate' functionality when touch movement ceases. Additionally, upon touch stabilization, the car automatically realigns with the center of the spline. But i want it to continue from where i last left it. I'll drop the code below:
public class playerController : MonoBehaviour
{
[SerializeField] private SplineFollower splineFollower;
[Header("Touch Controls: ")]
[SerializeField] private bool touchDetected = false;
private Touch touch;
[SerializeField] private bool isTouchStationery;
[SerializeField] private float localTouchStationeryTime = 0f;
[SerializeField] private float timeToReachStationery = 0.5f;
[Header("Car Speed Controls: ")]
[SerializeField] private float currentCarSpeed = 0;
[SerializeField] private float minimumCarSpeed = 0;
[SerializeField] private float maximumCarSpeed = 50;
[SerializeField] private float carAccelerationRate = 5;
[SerializeField] private float carDecelerationRate = 10;
[Header("Car Rotation Controls: ")]
[SerializeField][Range(0f, 20f)] private float rotationSpeed = 5f;
[Header("Touch Readonly Variables")]
[SerializeField] private Vector2 deltaPosition;
[Header("Physics Components: ")]
[SerializeField] private Rigidbody playerRigidBody;
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
switch (touch.phase)
{
case TouchPhase.Began:
localTouchStationeryTime = 0f;
touchDetected = true;
break;
case TouchPhase.Moved:
splineFollower.follow = false;
localTouchStationeryTime = 0f;
isTouchStationery = false;
deltaPosition = touch.deltaPosition;
//splineFollower.motion.offset += new Vector2(deltaPosition.x * Time.deltaTime, 0);
//splineFollower.motion.rotationOffset += new Vector3(0, deltaPosition.x * Time.deltaTime, 0);
transform.Rotate(Vector3.up * deltaPosition.x * rotationSpeed * Time.deltaTime);
break;
case TouchPhase.Stationary:
localTouchStationeryTime += Time.deltaTime;
if(localTouchStationeryTime > timeToReachStationery)
{
isTouchStationery = true;
splineFollower.follow = true;
}
break;
case TouchPhase.Ended:
localTouchStationeryTime = 0f;
touchDetected = false;
isTouchStationery = false;
splineFollower.follow = true;
break;
case TouchPhase.Canceled:
localTouchStationeryTime = 0f;
touchDetected = false;
isTouchStationery = false;
splineFollower.follow = true;
break;
default:
break;
}
}
if (touchDetected)
{
currentCarSpeed += carAccelerationRate * Time.deltaTime;
}
else
{
currentCarSpeed -= carDecelerationRate * Time.deltaTime;
}
currentCarSpeed = Mathf.Clamp(currentCarSpeed, minimumCarSpeed, maximumCarSpeed);
if(!isTouchStationery)
{
transform.Translate(transform.forward * currentCarSpeed * Time.deltaTime);
}
splineFollower.followSpeed = currentCarSpeed;
}
}
Upvotes: 2
Views: 212