okay so i made a game… https://play.google.com/store/apps/details?id=com.ATaleInWinter.CosmicRush
the problem is…
on majority of phones it works perfectly…
however on some phones (like motorolla in this case), it speeds up randomly at places and plays wierdly… why is this happening?
I’m 100% sure the code is perfect…
How can i fix this?
Thank You So Much!!
This is why you’re unable to find the issue ^^^
2 Likes
I’m not kidding… It works perfectly on windows platform and on some mobiles like oneplus and samsung… Only some phones like motorolla have the issues… how is that possible??
You haven’t given hardly any information about the specific problem. When a game appears to speed up and slow down it often is caused by the pace of the game being tied to the frame rate in your code, so on high performing hardware you don’t notice it because it is capable of a stable frame rate, but on lower performing hardware when the frame rate drops you see the pace of the game drop with the frame rate.
Often this is resolved by multiplying anything you do by Time.deltaTime. If that isn’t your issue, you’ll need to explain the problem better and probably provide some code related to the problem area(s).
1 Like
As was stated, “I’m 100% sure the code is perfect” is likely covering the real issue. Apparently your code is NOT perfect, and not correctly handling this (possible edge) case. Please provide the code that you believe is perfect, but not functioning correctly. You can recreate it, right? If you can recreate it, then you can (likely!) fix it.
1 Like
okay so i can’t post the code here but I’ll tell you how it was.
in Update -
first all inputs were taken and i set the rotation of player based on inputs
if jump button pressed a Force.IMPULSE was given to player
in FixedUpdate -
a constant forward velocity * time.deltaTime was given to player if input is not 0.
Every obstacle just has Transform.Translate with speed multiplied by time.deltaTime in Update().
I tried putting everything in Update() and everything in FixedUpdate() too… didn’t work.
PS - i have noticed that the game loses control when approaching certain obstacles…
Please help…
Without seeing the actual code, unfortunately I would not be able to help.
I’m really sorry for replying late my laptop stopped working…
okay so here is the code… it randomly speeds up the player too much and again randomly goes back to normal…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerActionsAndroid : MonoBehaviour {
Rigidbody playerRigidbody;
Animator playerAnimator;
[SerializeField] float speed;
Vector3 prevEulers, curForward;
[SerializeField] Transform groundCheckPos;
[SerializeField] float gcBoxLength, gcBoxWidth, gcBoxHeight;
[SerializeField] LayerMask whatIsGround;
bool isGrounded;
[Space(10)]
[SerializeField] float jumpSpeed;
bool canDoubleJump;
bool doJump, doDoubleJump;
[Space(10)]
public static bool gameFinished;
[Space(10)]
[SerializeField] AudioClip jumpAudio, doubleJumpAudio;
[SerializeField] AudioSource audioPlayer;
[Space(10)]
[SerializeField] float mobileJoystickDeadzone;
bool mobileMoveOriginSet;
Vector2 moveOrigin;
int moveTouch, moveFingerID;
float jumpStart;
[SerializeField] float timeBetweenJump;
[SerializeField] GameObject touchJoystick;
GameObject currJoystick;
void Start()
{
playerRigidbody = transform.GetComponent<Rigidbody>();
playerAnimator = transform.GetComponent<Animator>();
prevEulers = Vector3.up * transform.rotation.eulerAngles.y;
isGrounded = false;
canDoubleJump = true;
doJump = false;
doDoubleJump = false;
gameFinished = false;
mobileMoveOriginSet = false;
currJoystick = null;
}
void Update()
{
// Grounded Check -------
isGrounded = (Physics.OverlapBox(groundCheckPos.position, new Vector3(gcBoxWidth, gcBoxHeight, gcBoxLength), Quaternion.identity, whatIsGround).Length) > 0;
if (isGrounded) canDoubleJump = true;
// Grounded Check End -------
// Movement -------
// Get axes input
float Horizontal = Input.GetAxis("Horizontal");
float Vertical = Input.GetAxis("Vertical");
bool isRunning = false;
// Mobile Input --------------
float half = Screen.width / 2f;
Touch[] touches = Input.touches;
bool mobileJump = false;
if (touches.Length > 0 && Time.timeScale != 0)
{
for (int i = 0; i < Input.touchCount; i++)
{
if (mobileMoveOriginSet && touches[i].fingerId == moveFingerID) moveTouch = i;
else if (touches[i].position.x > half)
{
if (touches[i].phase == TouchPhase.Began)
{
mobileJump = true;
}
}
if ((touches[i].position.x < half) && (!mobileMoveOriginSet) && (touches[i].phase == TouchPhase.Began))
{
mobileMoveOriginSet = true;
moveFingerID = touches[i].fingerId;
moveTouch = i;
moveOrigin = touches[i].position;
if (!gameFinished) { currJoystick = Instantiate(touchJoystick) as GameObject;
currJoystick.transform.SetParent(GameObject.FindGameObjectWithTag("MainCanvas").transform);
currJoystick.transform.position = new Vector3(moveOrigin.x, moveOrigin.y, 0f); }
}
}
if (mobileMoveOriginSet)
{
Vector2 newPos = (touches[moveTouch].position - moveOrigin).normalized;
Horizontal = newPos.x;
if (Mathf.Abs(Horizontal) < mobileJoystickDeadzone) Horizontal = 0;
//else Horizontal = 1f;
Vertical = newPos.y;
if (Mathf.Abs(Vertical) < mobileJoystickDeadzone) Vertical = 0;
//else Vertical = 1f;
}
else if(moveTouch < touches.Length)
{
if (touches[moveTouch].phase == TouchPhase.Ended || touches[moveTouch].phase == TouchPhase.Canceled)
mobileMoveOriginSet = false;
}
}
else
{
mobileMoveOriginSet = false;
Horizontal = 0;
Vertical = 0;
}
if(!mobileMoveOriginSet && currJoystick != null)
{
Destroy(currJoystick);
currJoystick = null;
}
// Mobile Input End ----------
// If no input then dont move
float curSpeed = 0;
if ((Horizontal != 0 || Vertical != 0) && !gameFinished)
{
curSpeed = speed;
isRunning = true;
}
// Forward movement
curForward = transform.forward * curSpeed * Time.deltaTime;
// Rotation Settings
float right = 0, up = 0;
// Get input Horizontal
if (Horizontal == 0) right = 0;
else right = Horizontal > 0 ? 1f : -1f;
// Get input Vertical
up = Vertical;
// If no Horizontal input, set Vertical direction accordingly
if (right == 0 && up >= 0) up = 0;
else if (right == 0 && up < 0) up = 4;
// Store last rotation for keeping it for next update
if ((Horizontal != 0 || Vertical != 0) && !gameFinished)
//prevEulers = new Vector3(0, (90f * right) + (45f * (right > 0 ? -1f : 1f) * up) + cam.rotation.eulerAngles.y, 0);
prevEulers = new Vector3(0, (90f * right) + (45f * (right > 0 ? -1f : 1f) * up) -90f, 0);
// Movement End -------
// Double Jump -------
if ((Input.GetButtonDown("Jump") || mobileJump) && !isGrounded && canDoubleJump && !gameFinished && !doJump)
//if ((Input.GetButtonDown("Jump") || mobileJump) && !isGrounded && canDoubleJump && !gameFinished)
{
if (!((Time.time - jumpStart) < timeBetweenJump))
{
// Start Jump
isGrounded = false;
playerAnimator.SetTrigger("DoubleJump");
// Remove any Y-Velocity then add jump velocity
//curForward.y = 0;
//playerRigidbody.AddForce(0, jumpSpeed, 0, ForceMode.Impulse);
doJump = true;
doDoubleJump = true;
// Cannot double jump now
canDoubleJump = false;
//audioPlayer.loop = false;
//audioPlayer.clip = doubleJumpAudio;
//audioPlayer.Play();
}
}
// Double Jump End -------
// Jump -------
if ((Input.GetButtonDown("Jump") || mobileJump) && isGrounded && !gameFinished && !doJump)
//if ((Input.GetButtonDown("Jump") || mobileJump) && !isSliding && isGrounded && !gameFinished)
{
// Start jump
isGrounded = false;
playerAnimator.SetTrigger("Jump");
// Remove any Y-Velocity then add jump velocity
//curForward.y = 0;
//playerRigidbody.AddForce(0, jumpSpeed, 0, ForceMode.Impulse);
doJump = true;
doDoubleJump = false;
// Can double jump now
canDoubleJump = true;
jumpStart = Time.time;
//audioPlayer.loop = false;
//audioPlayer.clip = jumpAudio;
//audioPlayer.Play();
}
// Jump End -------
curForward.y = 0;
// Setting properties Finally -------
transform.rotation = Quaternion.Euler(prevEulers);
playerRigidbody.MovePosition(transform.position + curForward);
playerAnimator.SetBool("isRunning", isRunning);
playerAnimator.SetBool("isGrounded", isGrounded);
}
void FixedUpdate()
{
if (doJump && !gameFinished)
{
playerRigidbody.velocity = new Vector3(playerRigidbody.velocity.x, 0, playerRigidbody.velocity.z);
playerRigidbody.AddForce(0, jumpSpeed, 0, ForceMode.Impulse);
audioPlayer.loop = false;
audioPlayer.clip = (doDoubleJump)?((doubleJumpAudio)?doubleJumpAudio:null):((jumpAudio)?jumpAudio:null);
if(audioPlayer.clip != null) audioPlayer.Play();
doJump = doDoubleJump = false;
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireCube(groundCheckPos.position, new Vector3(gcBoxWidth, gcBoxHeight, gcBoxLength));
}
}
Please help me i really can’t figure out what the problem is.
I’m really greatful to you all… TYSM
PS - the rigidbody of player has 40 mass and 0 drag…
also i tried moving player with Rigidbody.velocity also… but that gives even worse results…
Rigidbody.MovePosition is intended to be used from FixedUpdate, not Update. If you have Rigidbody.interpolation set to Interpolate, that should do a smooth movement to the new position on frames between calls to FixedUpdate.
I’m not sure how this behaves when called from Update, especially if you get multiple MovePosition calls from multiple Update calls on the same object before the physics update, but I wouldn’t be surprised if you were getting some unexpected movement behavior.
Joe-Censored:
Rigidbody.MovePosition is intended to be used from FixedUpdate, not Update. If you have Rigidbody.interpolation set to Interpolate, that should do a smooth movement to the new position on frames between calls to FixedUpdate.
I’m not sure how this behaves when called from Update, especially if you get multiple MovePosition calls from multiple Update calls on the same object before the physics update, but I wouldn’t be surprised if you were getting some unexpected movement behavior.
I tried using it in FixedUpdate too… the only difference is that in fixedupdate the input feels a little laggy…
Well, you don’t want to take your input in FixedUpdate. You take your input in Update, and apply rigidbody movement in FixedUpdate. Rigidbody movement is applied during the physics update, which immediately follows FixedUpdate (it won’t be applied any faster if moving it to Update). FixedUpdate is generally unreliable for taking user input though, because the Input class is designed to be called from Update and only provides the input that has come in since the last frame. Since there can be multiple frames between each call to FixedUpdate, if you just moved everything from your current Update over to FixedUpdate some data from the Input class will be lost.
So, do everything with the Input class in Update, and do everything involving the Rigidbody in FixedUpdate.
Joe-Censored:
Well, you don’t want to take your input in FixedUpdate. You take your input in Update, and apply rigidbody movement in FixedUpdate. Rigidbody movement is applied during the physics update, which immediately follows FixedUpdate (it won’t be applied any faster if moving it to Update). FixedUpdate is generally unreliable for taking user input though, because the Input class is designed to be called from Update and only provides the input that has come in since the last frame. Since there can be multiple frames between each call to FixedUpdate, if you just moved everything from your current Update over to FixedUpdate some data from the Input class will be lost.
So, do everything with the Input class in Update, and do everything involving the Rigidbody in FixedUpdate.
That’s what i meant previously… ofcourse i always take input in Update only… never changed that… but moving rigidbody and applying forces… i tried using them in both Update and FixedUpdate… still same problem…