Script refuses to work in APK but works in Unity Remote/Editor.

(Repost to correct thread)
Hey guys , I have a script attached to a car game object that allows the player to tap the screen and then accelerate , it works fine in Unity Remote , but when I download the APK , as soon as I tap the screen , collisions go completely bezerk and the car just starts ignoring collisions , what’s going on? As I need this to work to complete my game , as the player can move side to side with the accelerometer but I also want them to move forward when they touch the screen. Also , my game is 2D.
The code I think is causing the error starts at line 32

using UnityEngine;
using System.Collections;
public class carController : MonoBehaviour {
    public float carSpeed;
    public float maxPos = 2.2f;
    Vector3 position;
    public UIManager ui;
    public AudioManager am;
    public float MaxPosY = 3.69f;
    public GameObject anim;
    bool currntPlatformAndroid = false;
    bool heldDown = true;
    Rigidbody2D rb;
    void Awake(){
        rb = GetComponent<Rigidbody2D> ();
        #if UNITY_ANDROID
                currntPlatformAndroid = true;
        #else
                currentPlatformAndroid = false;
        #endif
        am.carSound.Play ();
    }
    void Start () {
        position = transform.position;
        if (currntPlatformAndroid == true) {
            Debug.Log ("Android");
        }
        else {
            Debug.Log ("Windows");
        }
    }
    void FixedUpdate() {
        if (Input.touchCount > 0)
        {
            transform.Translate(new Vector3(0, 1, 0) * carSpeed * Time.deltaTime);
        }
        else {
            transform.Translate(new Vector3(0, -1, 0) * carSpeed * Time.deltaTime);
        }
    }
    void Update()
    {
        if (currntPlatformAndroid == true)
        {
            //android specific code
            //TouchMove ();
            AccelerometerMove();
        }
        else {
            position.x += Input.GetAxis("Horizontal") * carSpeed * Time.deltaTime;
            position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
            position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);
            transform.position = position;
        }
  
        position = transform.position;
        position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
        position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);
        transform.position = position;
  
    }
  
    void OnCollisionEnter2D(Collision2D col){
        if (col.gameObject.tag == "EnemyCar") {
            //Destroy (gameObject);
            Instantiate(anim, transform.position, transform.rotation);
            am.explosionSound.Play();
            Destroy(anim);
            Destroy(this.gameObject);
            am.carSound.Stop();
            ui.gameOverorNot();
        }
    }
    void AccelerometerMove(){
        float x = Input.acceleration.x;
        Debug.Log ("X = " + x);
        if (x < -0.1f) {
            MoveLeft ();
        } else if (x > 0.1f) {
            MoveRight ();
        }
        else {
            SetVelocityZero();
        }
    }
    void TouchMove(){
        if (Input.touchCount > 0) {
            Touch touch = Input.GetTouch (0);
            float middle = Screen.width / 2;
            if (touch.position.x < middle && touch.phase == TouchPhase.Began) {
                MoveLeft ();
            }
            else if (touch.position.x > middle && touch.phase == TouchPhase.Began) {
                MoveRight ();
            }
  
        }
        else {
            SetVelocityZero();
        }
    }
    public void MoveLeft(){
        rb.velocity = new Vector2 (-carSpeed, 0);
    }
    public void MoveRight(){
  
        rb.velocity = new Vector2 (carSpeed, 0);
    }
    public void SetVelocityZero(){
        rb.velocity = Vector2.zero;
    }
    /*void AccelerometerMove(){
        float x = Input.acceleration.x;
  
        Debug.Log (" X: " + x);
  
        if (x < -0.1f) {
            MoveLeft ();
        } else if (x > 0.1f) {
            MoveRight ();
        }
        else {
            SetVelocityZero();
        }
  
    }*/
}

The object that script is attached to has a rigidbody and a box collider , the objects it’s colliding with have box colliders.

EDIT: Just tested again and even if I just use the accelerometer and not touch the screen , the gameobject still goes bezerk and starts ignoring collisions. ( Keep in mind the script worked fine in the APK when I didn’tt have the Transform.Translate code , and just the Accelerometer code.

If you are using Translate you probably want to mark the rigidbody as isKinematic because otherwise you might be “driving” the object into other colliders, causing the physics system to react. Is your RB marked as kinematic?

Thanks for the reply man. My object isn’t kinematic , it has interpolate on and continuous collision. If I make it kinematic , wouldn’t that mean I couldn’t move it?(excuse my ignorance) I’m about to try it to see what’s up.

I tested it , and made the car kinematic , but then it wouldn’t collide with the other objects , so I added RB2D’s to them and the car just ignores the collision ( although the bouncing thing is gone).

Is this maybe happening because of interference with the accelerometer?

Anybody?

Can you rig something up to show you the accelerometer input values? Perhaps you need to do a low pass filter to get rid of the small changes in value.

But I doubt it.

I think if you started having trouble with Translate, you should try using MovePosition or something that incorporates the physics engine in the change. Translating pretty much represents a teleport to the Physics engine.

Do you mean like the values when I tilt the phone? if so , I have that so I’ll just make a quick GIF if you need it.
My problem isn’t even translate now , when my car collides with another car in the scene it literally just ignores it ( even if I take out the translate part), DESPITE it working in Unity Remote and the Editor , and I also have a RB and Box collider on my car and box colliders on all the enemies ( so I don’t know what the problem is).

Here’s my scripts so you can get the full details
(Scripts attached to my main game object)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CoinCollider : MonoBehaviour
{
    public UIManager ui;
    public AudioManager am;
    // Use this for initialization
    void Start()
    {
    
    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Coin")
        {
            ui.coinsCollected++;
            am.coinSound.Play();
            Destroy(col.gameObject);
        }
    }
}
using UnityEngine;
using System.Collections;

public class carController : MonoBehaviour
{
    public float carSpeed;
    public float maxPos = 2.2f;
    Vector3 position;
    public UIManager ui;
    public AudioManager am;
    public float MaxPosY = 3.69f;
    public GameObject anim;
    bool currntPlatformAndroid = false;
    bool heldDown = true;
    Rigidbody2D rb;
    void Awake()
    {

        rb = GetComponent<Rigidbody2D>();

#if UNITY_ANDROID
        currntPlatformAndroid = true;
#else
                currentPlatformAndroid = false;
#endif


        am.carSound.Play();

    }

    void Start()
    {

        position = transform.position;

        if (currntPlatformAndroid == true)
        {
            Debug.Log("Android");
        }
        else
        {
            Debug.Log("Windows");
        }



    }


    void Update()
    {


        if (currntPlatformAndroid == true)
        {
            //android specific code
            //TouchMove ();
            AccelerometerMove();
        }

        else
        {

             position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
            position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);


            transform.position = position;
        }

        position = transform.position;
        position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
        position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);

        transform.position = position;

    }

    void OnCollisionEnter2D(Collision2D col)
    {

        if (col.gameObject.tag == "EnemyCar")
        {
            //Destroy (gameObject);
            rb.freezeRotation = true;
            Instantiate(anim, transform.position, transform.rotation);
            am.explosionSound.Play();
            Destroy(anim);
            Destroy(this.gameObject);
            am.carSound.Stop();
            ui.gameOverorNot();


        }
    }

    void AccelerometerMove()
    {

        float x = Input.acceleration.x;
        Debug.Log("X = " + x);


        if (x < -0.1f)
        {
            MoveLeft();
        }
        else if (x > 0.1f)
        {
            MoveRight();
        }
        else
        {
            SetVelocityZero();
        }

    }


    void TouchMove()
    {

        if (Input.touchCount > 0)
        {

            Touch touch = Input.GetTouch(0);

            float middle = Screen.width / 2;

            if (touch.position.x < middle && touch.phase == TouchPhase.Began)
            {
                MoveLeft();
            }
            else if (touch.position.x > middle && touch.phase == TouchPhase.Began)
            {
                MoveRight();
            }

        }

        else
        {
            SetVelocityZero();
        }

    }


    public void MoveLeft()
    {
        rb.velocity = new Vector2(-carSpeed, 0);
    }

    public void MoveRight()
    {

        rb.velocity = new Vector2(carSpeed, 0);
    }

    public void SetVelocityZero()
    {
        rb.velocity = Vector2.zero;
    }

    /*void AccelerometerMove(){
        float x = Input.acceleration.x;
      
        Debug.Log (" X: " + x);
      
        if (x < -0.1f) {
            MoveLeft ();
        } else if (x > 0.1f) {
            MoveRight ();
        }
        else {
            SetVelocityZero();
        }
      
    }*/




}

And you can see how it look sin the inspector ( 1st and 2nd picture)

Here’s what’s attached to my enemy cars ( the ones that the main car collides with)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyCar : MonoBehaviour {
    public float speed ;
    public float acceleration = 0.5f;
    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        speed += Time.deltaTime * acceleration;

        transform.Translate(new Vector3(0, 1, 0) * speed * Time.deltaTime);
      
    }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Coin")
        {
            Destroy(col.gameObject);
        }
    }
}

You can see what’s attached to my enemy cars in the 3rd image.
So , why aren’t collisions occurring with some of my enemy cars?

3043056--228020--1.PNG
3043056--228021--2.PNG
3043056--228022--3.PNG

Supposedly this is a bug in Unity?

Nope. People have been colliding things on android for a long time.

I’d say you have too many variables to get a fix on the problem.

Go back to basics and collide two cubes. When that works, match their settings to the cars and see if it fails- since they don’t have scripts, you can rule out the rigid body settings.

Then add in translation movement, and so on until you find what makes it break.

2 Likes

Makes sense , I’ll try this.
EDIT : But wait , how would I collide them if I don’t add scripts?

I was thinking you’d place one cube above the other in view of the camera and see if they don’t fall through each other. This would verify that your collision layers are working correctly.

You want to rule out if the settings are responsible for the problem.

The thing to remember is that as long as your script isn’t moving the object and its only the physics, the script isn’t part of the equation.

Ok , so far I have two cubes , one with a RB2D and a Box collider , with this script attached.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Collider : MonoBehaviour {
    public float speed;

    // Use this for initialization
    void Start () {
       
    }
   
    // Update is called once per frame
    void Update () {
        transform.Translate(new Vector3(1, 0, 0) * speed * Time.deltaTime);

    }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Cube")
        {
          
            Destroy(col.gameObject);
        }
    }
}

The other just has the tag “Cube” and a box collider , and this works on Android. So I’m going to add the scale and stuff for my two cars and see if it still works.

Right , that does make sense , I’ll try that now , but is what I did above still valid?

Well , I did it the way you suggested , and the first cube has a RB2D and Box collider , the other one just has a box collider. They don’t fall through each other… My car RB has gravity scale set to 0 while the cube has 1 , could this be a problem?
EDIT : It works fine on Android , gonna add the Transform.Translate now.
Transform.Translate works fine on the cube on Android

I then added a much more watered down version of Car Controller to the cube

using UnityEngine;
using System.Collections;

public class CubeC : MonoBehaviour
{
    public float carSpeed;
    public float maxPos = 2.2f;
    Vector3 position;
    public float MaxPosY = 3.69f;
    public GameObject anim;
    bool currntPlatformAndroid = false;
    bool collided = false;
    Rigidbody2D rb;
    void Awake()
    {

        rb = GetComponent<Rigidbody2D>();

#if UNITY_ANDROID
        currntPlatformAndroid = true;
#else
                currntPlatformAndroid = false;
#endif



    }

    void Start()
    {

        position = transform.position;

        if (currntPlatformAndroid == true)
        {
            Debug.Log("Android");
        }
        else
        {
            Debug.Log("Windows");
        }



    }




    void Update()
    {
        position = transform.position;
        position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
        position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);

        transform.position = position;


        if (currntPlatformAndroid == true)
        {
            //android specific code
            //TouchMove ();
            AccelerometerMove();
        }

        else
        {

            position.y = Mathf.Clamp(position.y, -4.25f, 4.25f);
            position.x = Mathf.Clamp(position.x, -2.5f, 2.5f);


            transform.position = position;
        }



    }


    void AccelerometerMove()
    {

        float x = Input.acceleration.x;
        Debug.Log("X = " + x);


        if (x < -0.1f)
        {
            MoveLeft();
        }
        else if (x > 0.1f)
        {
            MoveRight();
        }
        else
        {
            SetVelocityZero();
        }

    }


    void TouchMove()
    {

        if (Input.touchCount > 0)
        {

            Touch touch = Input.GetTouch(0);

            float middle = Screen.width / 2;

            if (touch.position.x < middle && touch.phase == TouchPhase.Began)
            {
                MoveLeft();
            }
            else if (touch.position.x > middle && touch.phase == TouchPhase.Began)
            {
                MoveRight();
            }

        }

        else
        {
            SetVelocityZero();
        }

    }


    public void MoveLeft()
    {
        rb.velocity = new Vector2(-carSpeed, 0);
    }

    public void MoveRight()
    {

        rb.velocity = new Vector2(carSpeed, 0);
    }

    public void SetVelocityZero()
    {
        rb.velocity = Vector2.zero;
    }

    /*void AccelerometerMove(){
        float x = Input.acceleration.x;

        Debug.Log (" X: " + x);

        if (x < -0.1f) {
            MoveLeft ();
        } else if (x > 0.1f) {
            MoveRight ();
        }
        else {
            SetVelocityZero();
        }

    }*/
    void OnCollisionEnter2D(Collision2D col)
    {

        if (col.gameObject.tag == "Cube")
        {
            Instantiate(anim, transform.position, transform.rotation);
            Destroy(anim);
            Destroy(this.gameObject);
     


        }
    }

It works fine on Android , I’m gonna add the Enemy Car Script to my other cube , and if that works , then what’s the problem with my cars?
EDIT : Enemy Car works fine on my cube, so what’s the problem with my cars? Is it because they are sprites and not 3D objects?

I think I’ve found the problem , I used your method and it worked perfectly on Android. I then went back to my main scene to try and apply the same settings and it refused to work , but it does work on Start. I think the reason why it doesn’t work is because of either two things , the fact that my enemy cars are instantiated
Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarSpawner : MonoBehaviour {
    public GameObject[] cars;
    int carNo;
    public float MaxPos = 2.2f;
    public float delayTimer;
    float timer;
    // Use this for initialization
    void Start () {
        timer = delayTimer;
    }
  
    // Update is called once per frame
    void Update () {
         timer -= Time.deltaTime;
        if (timer <= 0) {
            Vector3 carPos = new Vector3(Random.Range(-2.2f, 2.2f), transform.position.y, transform.position.z);
            carNo = Random.Range(0, 7);
            Instantiate(cars [carNo], carPos, transform.rotation);
            timer = delayTimer;
        }
    }
}

OR the fact that when I press Play ( to restart the game ) all goes ary , and collision acts up. Here’s the script that deals with gameover , etc.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour {
    public Text ScoreText;
    public Text CoinsText;
    public Text CoinsText2;
    public Text HighScoreText;
    public  int coinsCollected;
   public  int CoinsInBalance;
    int score;
    static int highScore;
    bool gameOver;
    public Button[] buttons;
    public Text[] texts;
    // Use this for initialization
    void Start() {
        gameOver = false;
        highScore = PlayerPrefs.GetInt("highscore");
          score = 0;
        InvokeRepeating("scoreUpdate", 1.0f, 0.5f);
    }

    // Update is called once per frame
    void Update()
    {
        CoinsInBalance = PlayerPrefs.GetInt("Coins");

        ScoreText.text = "SCORE: " + score;
        CoinsText.text = " COINS: " + coinsCollected;
        CoinsText2.text = "COIN BANK: " + CoinsInBalance;
        if (score > highScore)
        {
            highScore = score;
            PlayerPrefs.SetInt("highscore", highScore);
        }
            HighScoreText.text = "HIGH SCORE: " + highScore;
    }
      
  
    public void Pause() {
        if (Time.timeScale == 1)
        {
            Time.timeScale = 0;
        }
        else if (Time.timeScale == 0) {
            Time.timeScale = 1;
        }
    }
    void scoreUpdate() {
        if (gameOver == false) {
            score += 1;
        }
       
    }
    public void gameOverorNot() {
        gameOver = true;
        CoinsInBalance += coinsCollected;
        PlayerPrefs.SetInt("Coins", CoinsInBalance);
        foreach (Button button in buttons) {
            button.gameObject.SetActive(true);
        }
        foreach (Text text in texts) {
            text.gameObject.SetActive(true);
        }
    }
    public void Replay() {
        Application.LoadLevel(Application.loadedLevel);
    }
    public void Menu() {
        Application.LoadLevel("MainMenu");
    }
    public void Exit() {
        Application.Quit();
    }
  
 
}

It could also be because the enemy car’s speed is changed rapidly?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyCar : MonoBehaviour {
    public float speed ;
    public float acceleration = 0.5f;
    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        speed += Time.deltaTime * acceleration;

        transform.Translate(new Vector3(0, 1, 0) * speed * Time.deltaTime);
       
    }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Coin")
        {
            Destroy(col.gameObject);
        }
    }
}

I think it’s the second issue , considering collisions only go crazy when I press Play ( after thje player dies once)

I’ve figured it out , I thought it was the fact that collision isn’t updated. Basically , after collision , I have a button that allows the player to replay the game

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour {
    public Text ScoreText;
    public Text CoinsText;
    public Text CoinsText2;
    public Text HighScoreText;
    public  int coinsCollected;
   public  int CoinsInBalance;
    int score;
    static int highScore;
    bool gameOver;
    public Button[] buttons;
    public Text[] texts;
    // Use this for initialization
    void Start() {
        gameOver = false;
        highScore = PlayerPrefs.GetInt("highscore");
          score = 0;
        InvokeRepeating("scoreUpdate", 1.0f, 0.5f);
    }
    // Update is called once per frame
    void Update()
    {
        CoinsInBalance = PlayerPrefs.GetInt("Coins");
        ScoreText.text = "SCORE: " + score;
        CoinsText.text = " COINS: " + coinsCollected;
        CoinsText2.text = "COIN BANK: " + CoinsInBalance;
        if (score > highScore)
        {
            highScore = score;
            PlayerPrefs.SetInt("highscore", highScore);
        }
            HighScoreText.text = "HIGH SCORE: " + highScore;
    }
   
    public void Pause() {
        if (Time.timeScale == 1)
        {
            Time.timeScale = 0;
        }
        else if (Time.timeScale == 0) {
            Time.timeScale = 1;
        }
    }
    void scoreUpdate() {
        if (gameOver == false) {
            score += 1;
        }
     
    }
    public void gameOverorNot() {
        gameOver = true;
        CoinsInBalance += coinsCollected;
        PlayerPrefs.SetInt("Coins", CoinsInBalance);
        foreach (Button button in buttons) {
            button.gameObject.SetActive(true);
        }
        foreach (Text text in texts) {
            text.gameObject.SetActive(true);
        }
    }
    public void Replay() {
        Application.LoadLevel(Application.loadedLevel);
    }
    public void Menu() {
        Application.LoadLevel("MainMenu");
    }
    public void Exit() {
        Application.Quit();
    }
}

Collision works when I first start the game , but when the player dies and I press “Replay” , it goes crazy. Here’s the script that controls the enemy cars spawning , what the hell do I do to fix this?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyCar : MonoBehaviour {
    public float speed ;
    public float acceleration = 0.5f;
    // Use this for initialization
    void Start () {
    }
    // Update is called once per frame
    void Update () {
        speed += Time.deltaTime * acceleration;
        transform.Translate(new Vector3(0, 1, 0) * speed * Time.deltaTime);
     
    }
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Coin")
        {
            Destroy(col.gameObject);
        }
    }
}

But once again , what’s hilarious is that it still works fine on Editor/Remote , just not Android.lol

The above is why I think this is a Unity bug ( along with various other people having the same problem) , unless there’s a way to put Collision in Unity , as I don’t understand why it only goes wrong when I replay my game ( meaning it’s working on Start but not Update). Yet it still works fine on the Editor.

Do basic cubes still collide after you reload the level?

1 Like