Hi, not quite sure where to ask this, but im using swipe controls on android, and you can see when the player has swiped but when they're in the lane, they're kinda glitching and moving about for some reason..
i have two scripts, a playercontroller and mobileinput script which is controlling this
https://youtu.be/Fvcp01oetwI
#Player glitching while in a lane
1 messages · Page 1 of 1 (latest)
ill post the scripts shortly
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
public float forwardSpeed = 20;
public float lrSpeed = 50;
public CharacterController player;
private int desiredLane = 1; // 0 left, 1 middle, 2 right
private void Start()
{
player = GetComponent<CharacterController>();
}
void Update()
{
if (MobileInput.Instance.SwipeLeft)
{
MoveLane(false);
}
if (MobileInput.Instance.SwipeRight)
{
MoveLane(true);
}
if (MobileInput.Instance.Tap)
{
FastButton();
}
//future moves
Vector3 targetPosition = transform.position.z * Vector3.forward;
if (desiredLane == 0)
{
targetPosition += Vector3.left * 5;
}
else if (desiredLane == 2)
{
targetPosition += Vector3.right * 5;
}
//move delta
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetPosition - transform.position).normalized.x * lrSpeed;
moveVector.z = forwardSpeed;
//move car
player.Move(moveVector * Time.deltaTime);
}
private void MoveLane(bool goingRight)
{
desiredLane += (goingRight) ? 1 : -1;
desiredLane = Mathf.Clamp(desiredLane, 0, 2);
}
public void FastButton()
{
forwardSpeed = 25;
}
}```
MobileInput.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using UnityEngine;
public class MobileInput : MonoBehaviour
{
private const float bounds = 100;
public static MobileInput Instance { set; get; }
private bool tap, swipeLeft, swipeRight, swipeDown;
private Vector2 swipeDelta, startTouch;
public bool Tap
{
get
{
return tap;
}
}
public bool SwipeLeft
{
get
{
return swipeLeft;
}
}
public bool SwipeRight
{
get
{
return swipeRight;
}
}
public bool SwipeDown
{
get
{
return swipeDown;
}
}
public Vector2 SwipeDelta
{
get
{
return SwipeDelta;
}
}
private void Awake()
{
Instance = this;
}
private void Update()
{
//reset bools
tap = swipeLeft = swipeRight = swipeDown = false;
//mobile input
if (Input.touches.Length != 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
tap = true;
startTouch = Input.mousePosition;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
startTouch = swipeDelta = Vector2.zero;
}
}
//calculate distance
swipeDelta = Vector2.zero;
if (startTouch != Vector2.zero)
{
if (Input.touches.Length != 0)
{
swipeDelta = Input.touches[0].position - startTouch;
}
}
// deadzone / bounds
if (swipeDelta.magnitude > bounds)
{
//confirmed swipe
float x = swipeDelta.x;
float y = swipeDelta.y;
if (x < 0)
{
swipeLeft = true;
}
else
{
swipeRight = true;
}
if (y < 0)
{
swipeDown = true;
}
else
{
swipeDown = false;
}
startTouch = swipeDelta = Vector2.zero;
}
}
}```
would a fixed or late update help in any of the scripts?
inputs in generall need to get caught in update, and as early as possible.
i would recommend trying the new input system, which invokes methods when specific inputs happen.
that said, I’m not very familiar with mobile controls, but inputsystem tends to be good at managing when different inputs go off
hmm okay ill see if i can implement the input system, im guessing it does come with mobile inputs also?
i have little experience with mobile tbh.
but the main thing that InputSystem does is invoke methods super early in the frame when an input happens
so you can do something like
playerInputCustom.Gameplay.Jump.performed += OnJumpButton;
private void OnJumpButton(InputAction.CallbackContext ctx) {
Jump();
}
then very early in the frame, whenever the Jump button tied to it is pressed, it will invoke Jump()
i do warn that InputSystem is more complex, so it will take some learning to figure it out
but it is generally way cleaner to make your game depend on inputs with it, then by a bunch of input checks in Update
sure. i know inputsystem has some weird peculiarities with touch controls
so just be prepared for it
long story short i've reverted back to the scripts above as the new input system along with all the tutorials i can find are confusing my brain lmao
Managed to get the player to stay still and not jitter/glitch using fixed update for the movement parts and normal update for input
But must've changed something with the box collect script, player/collectible/obstacle trigger, or collider because as you can see none of the boxes are being collected and if you run into an obstacle or the trigger at the end, nothing happens
idk how or why but this has solved this issue
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
public class PlayerController : MonoBehaviour
{
public float forwardSpeed = 20;
public float lrSpeed = 20;
public CharacterController cc;
private int desiredLane = 1; // 0 left, 1 middle, 2 right
private void Start()
{
cc = GetComponent<CharacterController>();
}
private void Update()
{
if (SwipeManager.swipeRight)
{
desiredLane++;
if (desiredLane == 3)
{
desiredLane = 2;
}
}
if (SwipeManager.swipeLeft)
{
desiredLane--;
if (desiredLane == -1)
{
desiredLane = 0;
}
}
if (SwipeManager.tap == true)
{
Fast();
}
else if (SwipeManager.tap == false)
{
Normal();
}
}
void FixedUpdate()
{
//future moves
Vector3 targetPosition = transform.position.z * Vector3.forward;
if (desiredLane == 0)
{
targetPosition += Vector3.left * 5;
}
else if (desiredLane == 2)
{
targetPosition += Vector3.right * 5;
}
//move delta
transform.position = Vector3.Lerp(transform.position, targetPosition, 90*Time.fixedDeltaTime);
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetPosition - transform.position).normalized.x * lrSpeed;
moveVector.z = forwardSpeed;
//move car
cc.Move(moveVector * Time.deltaTime);
}
public void MoveLane(bool goingRight)
{
desiredLane += (goingRight) ? 2 : 0;
desiredLane = Mathf.Clamp(desiredLane, 0, 2);
}
public void Fast()
{
forwardSpeed = 45;
}
public void Normal()
{
forwardSpeed = 20;
}
}```
SwipeManager.cs
using UnityEngine;
public class SwipeManager : MonoBehaviour
{
public static bool tap, swipeLeft, swipeRight, swipeUp, swipeDown;
private bool isDragging = false;
private Vector2 startTouch, swipeDelta;
private void Update()
{
tap = swipeDown = swipeUp = swipeLeft = swipeRight = false;
#region Standalone Inputs
if(Input.GetMouseButton(0))
{
tap = true;
}
if (Input.GetMouseButtonDown(0))
{
isDragging = true;
startTouch = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(0))
{
tap = isDragging = false;
Reset();
}
#endregion
#region Mobile Input
if (Input.touches.Length > 0)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
tap = true;
isDragging = true;
startTouch = Input.touches[0].position;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
tap = isDragging = false;
Reset();
}
}
#endregion
//Calculate the distance
swipeDelta = Vector2.zero;
if (isDragging)
{
if (Input.touches.Length < 0)
swipeDelta = Input.touches[0].position - startTouch;
else if (Input.GetMouseButton(0))
swipeDelta = (Vector2)Input.mousePosition - startTouch;
}
//Did we cross the distance?
if (swipeDelta.magnitude > 100)
{
//Which direction?
float x = swipeDelta.x;
float y = swipeDelta.y;
if (Mathf.Abs(x) > Mathf.Abs(y))
{
//Left or Right
if (x < 0)
swipeLeft = true;
else
swipeRight = true;
}
else
{
//Up or Down
if (y < 0)
swipeDown = true;
else
swipeUp = true;
}
Reset();
}
}
private void Reset()
{
startTouch = swipeDelta = Vector2.zero;
tap = isDragging = false;
}
}```