Search Unity

Bug script works on editor but not on android

Discussion in 'Scripting' started by adiseagle, Dec 4, 2021.

  1. adiseagle

    adiseagle

    Joined:
    May 15, 2019
    Posts:
    5
    I have this script which records the car movement and then spawns a "ghost" which copy the recorded car movement from previous lap. it works fine on the editor but not not on android for whatever reason. what went wrong is that the ghost doesn't have the car movement data thus it just spawns and stayed still. i'm assuming it has something to do with array or list though i could be wrong.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Xml.Linq;
    5. using System.Xml.Serialization;
    6. using System.IO;
    7.  
    8. public class Ghost : MonoBehaviour
    9. {
    10.     public string trackName;
    11.     public bool newPb;
    12.     [SerializeField] checkPoint checkPoint;
    13.     [SerializeField] GameObject[] ghostCar;
    14.     public GameObject[] ghostCarInHierachy;
    15.     private GameObject[] cars;
    16.     private GameObject car;
    17.     private List<GhostRecord> ghostRecords = new List<GhostRecord>();
    18.     private GhostRecord[] fastestGhost;
    19.     private GhostRecord[] personalBest;
    20.     private bool spawned = false;
    21.     private int p;
    22.     private int workpls;
    23.  
    24.     private void Start()
    25.     {
    26.         cars = GameObject.FindGameObjectsWithTag("car");
    27.         car = cars[0];
    28.         LoadXMLGhost();
    29.     }
    30.  
    31.     private void FixedUpdate()
    32.     {
    33.         ghostRecords.Add(new GhostRecord { position = car.transform.position, rotation = car.transform.rotation });
    34.         p++;
    35.         if (spawned)
    36.         {
    37.             if (PlayerPrefs.GetString("ghost") == "session")
    38.             {
    39.                 if (p < fastestGhost.Length && p >= 0)
    40.                 {
    41.                     PlayingGhost(p);
    42.                 }
    43.                 else
    44.                 {
    45.                     Destroy(ghostCarInHierachy[0]);
    46.                     Debug.Log("Ghost destroyed (Session)");
    47.                     spawned = false;
    48.                 }
    49.             }
    50.             else if (newPb)
    51.             {
    52.                 if (p < fastestGhost.Length && p >= 0)
    53.                 {
    54.                     PlayingGhost(p);
    55.                 }
    56.                 else
    57.                 {
    58.                     Destroy(ghostCarInHierachy[0]);
    59.                     Debug.Log("Ghost destroyed (NewPB)");
    60.                     spawned = false;
    61.                 }
    62.             }
    63.             else
    64.             {
    65.                 if (p < personalBest.Length && p >= 0)
    66.                 {
    67.                     PlayingGhost(p);
    68.                 }
    69.                 else
    70.                 {
    71.                     Destroy(ghostCarInHierachy[0]);
    72.                     Debug.Log("Ghost destroyed (PB)");
    73.                     spawned = false;
    74.                 }
    75.             }
    76.         }
    77.     }
    78.  
    79.     private void PlayingGhost(int index)
    80.     {
    81.         if (!PlayerPrefs.HasKey((PlayerPrefs.GetInt("selected_car").ToString() + trackName + "ghost")))
    82.         {
    83.             GhostRecord actionReplayRecord = fastestGhost[index];
    84.             ghostCarInHierachy[0].transform.position = actionReplayRecord.position;
    85.             ghostCarInHierachy[0].transform.rotation = actionReplayRecord.rotation;
    86.         }
    87.  
    88.         else if(PlayerPrefs.GetString("ghost") == "session")
    89.         {
    90.             GhostRecord actionReplayRecord = fastestGhost[index];
    91.             ghostCarInHierachy[0].transform.position = actionReplayRecord.position;
    92.             ghostCarInHierachy[0].transform.rotation = actionReplayRecord.rotation;
    93.         }
    94.         else if (newPb)
    95.         {
    96.             GhostRecord actionReplayRecord = fastestGhost[index];
    97.             ghostCarInHierachy[0].transform.position = actionReplayRecord.position;
    98.             ghostCarInHierachy[0].transform.rotation = actionReplayRecord.rotation;
    99.         }
    100.         else
    101.         {
    102.             GhostRecord actionReplayRecord = personalBest[index];
    103.             ghostCarInHierachy[0].transform.position = actionReplayRecord.position;
    104.             ghostCarInHierachy[0].transform.rotation = actionReplayRecord.rotation;
    105.         }
    106.     }
    107.  
    108.     public void SaveFastestGhost()
    109.     {
    110.         fastestGhost = ghostRecords.ToArray();
    111.     }
    112.     public void SavePersonalBestGhost()
    113.     {
    114.         var ghost = new PersonalBestGhost()
    115.         {
    116.             Nickname = PlayerPrefs.GetString("nickname"),
    117.             Time = PlayerPrefs.GetFloat(PlayerPrefs.GetInt("selected_car").ToString() + trackName + "ghost"),
    118.             Track = trackName,
    119.             Car = PlayerPrefs.GetInt("selected_car"),
    120.             PBGhost = fastestGhost,
    121.         };
    122.         var doc = new XDocument();
    123.         using (var writer = doc.CreateWriter())
    124.         {
    125.             var serializer = new XmlSerializer(typeof(PersonalBestGhost));
    126.  
    127.             serializer.Serialize(writer, ghost);
    128.         }
    129.  
    130.         doc.Save(Application.persistentDataPath + "/" + PlayerPrefs.GetString("nickname") + "@" + trackName + "Ghost.xml");
    131.     }
    132.     private void LoadXMLGhost()
    133.     {
    134.         if (PlayerPrefs.GetString("ghost") == "external")
    135.         {
    136.             var serializer = new XmlSerializer(typeof(PersonalBestGhost));
    137.             using (FileStream fs = File.OpenRead(Application.persistentDataPath + "/" + PlayerPrefs.GetString("nickname") + "@" + trackName + "Ghost.xml"))
    138.             {
    139.                 PersonalBestGhost pbGhost = (PersonalBestGhost)serializer.Deserialize(fs);
    140.                 personalBest = pbGhost.PBGhost;
    141.             }
    142.         }
    143.            
    144.         else if (PlayerPrefs.GetString("ghost") == "adiseagle")
    145.         {
    146.             var serializer = new XmlSerializer(typeof(PersonalBestGhost));
    147.             using (FileStream fs = File.OpenRead(Application.persistentDataPath + "/" + PlayerPrefs.GetString("nickname") + "@" + trackName + "Ghost.xml"))
    148.             {
    149.                 PersonalBestGhost pbGhost = (PersonalBestGhost)serializer.Deserialize(fs);
    150.                 personalBest = pbGhost.PBGhost;
    151.             }
    152.         }
    153.         else if (PlayerPrefs.GetString("ghost") == "personal")
    154.         {
    155.             var serializer = new XmlSerializer(typeof(PersonalBestGhost));
    156.             using (FileStream fs = File.OpenRead(Application.persistentDataPath + "/" + PlayerPrefs.GetString("nickname") + "@" + trackName + "Ghost.xml"))
    157.             {
    158.                 PersonalBestGhost pbGhost = (PersonalBestGhost)serializer.Deserialize(fs);
    159.                 personalBest = pbGhost.PBGhost;
    160.                 checkPoint.fastesttime = pbGhost.Time;
    161.                 checkPoint.SetFastTime();
    162.             }
    163.         }
    164.     }
    165.  
    166.     public void ClearGhostRecord()
    167.     {
    168.         ghostRecords.Clear();
    169.     }
    170.  
    171.     public void PlayGhost()
    172.     {
    173.         if (PlayerPrefs.GetString("ghost") != "disabled")
    174.         {
    175.             if (!spawned) { Instantiate(ghostCar[PlayerPrefs.GetInt("selected_car") - 1]); spawned = true; Debug.Log("ghost spawned"); }
    176.             ghostCarInHierachy = GameObject.FindGameObjectsWithTag("ghost");
    177.             p = 0;
    178.         }
    179.     }
    180. }
    181.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    I'm guessing it's something to do with file IO, but you can prove it with tons of Debug.Log() statements (see below).

    First off, I would try and replace this mishmash spaghetti with proper use of System.IO.Path.Join(). Each operating system is more or less tolerant of misformed filespecs.

    Whatever it is, you must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
  3. adiseagle

    adiseagle

    Joined:
    May 15, 2019
    Posts:
    5
    actually i don't have any problems with the xml serializer nor the derializer. i apology for the unclearity but what the problem I'm having is that the missing movement data
    doesn't have anything to do with the xml functions. loading and saving an xml is costing quite a lot of processing power so i don't execute that at the gameplay but only when the player start the game or closes it.

    this part of the code should record the movement.
    Code (CSharp):
    1.     private void FixedUpdate()
    2.     {
    3.         ghostRecords.Add(new GhostRecord { position = car.transform.position, rotation = car.transform.rotation });
    this part of the code should temporarily save it to an array so that the list could be cleared and record a new one. (it's so that i won't be storing much data at runtime thinking that I'm doing some sort of optimization thing)
    Code (CSharp):
    1. public void SaveFastestGhost()
    2.     {
    3.         fastestGhost = ghostRecords.ToArray();
    4.     }
    this part clears the list of recorded movement ever since the fastest one would ever be used
    Code (CSharp):
    1. public void ClearGhostRecord()
    2.     {
    3.         ghostRecords.Clear();
    4.     }
    what baffles me is that it only work on pc but not on android, i did try to not clear the recorded movement list thinking it might've cleared it before the data moves into an array but there's still no movement data.
     
  4. adiseagle

    adiseagle

    Joined:
    May 15, 2019
    Posts:
    5
    update: i have debug many things to the UI and i conclude that the necessary data is there but it won't move for some reason. i'm so confused not to mention it works fine on pc
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    As my first post suggested, did you study the
    adb logcat
    ? It's extremely likely there is an exception being thrown.