Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Simple game is extremely lagging

Discussion in 'Scripting' started by Rotzak, Aug 13, 2018.

  1. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Hello,

    I'm working on a car game. A few days ago I noticed the objects that I'm spawning aren't very clear but I didn't bother about it anymore. Today I added alot of UI elements and animations and my game is lagging so hard now, it unplayable really... So I've spent the last few hours with disabling all these objects and animations and removing alot of stuff of the update function but still the game is lagging extremely.

    Here is a little video of the lagg, look at the car with number 87 you can barely read it:


    Here are the stats. Isn't it alot of fps for such a small game?


    And here is a picture of the profiler. To be honest I don't understand most of these parameters.


    peak:




    PS:
    - I'm using instantiate to spawn, but there are max 4-5 clones at a time.
    - Game is lagging on phone as an apk build BUT plays fine (still a bit laggy) on the computer!

    EDIT 20 AUGUST:
    Because I'm never going to find the solution on my own I'm sharing my test project here. It's a simple scene with one car. When you tap anywhere on your phone a car will be spawning. Build and run this to your phone and U'll see that the car is vibrating. The car has a number on it which u can barely read.

    This is a WeTransfer link which contains the unity project (Zipped). I'm using the last version of Unity (2018.2.3f1)
    https://we.tl/t-2jF2Hgvb51

    Help is much much much appreciated.
     
    Last edited: Aug 20, 2018
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Gfx.WaitForPresent means that Unity has done all of its processing and is sitting around waiting for the GPU draw the current game's frame, which is basically an ideal state to be in.

    1.3ms CPU time is extremely good.

    Your game doesn't seem laggy so much as you're relying on physics without interpolation, and is thus only moving the objects as often as your fixed timestep. Try turning Interpolation on, in the Rigidbody components for your cars, and the visuals should feel smoother.
     
    Content1of_akind and Rotzak like this.
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Looking closely, it actually looks like a camera problem. Is your camera moving? That's where I would look first.

    If not I would take a close look at the code that is moving the road.
     
    Rotzak likes this.
  4. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,589
    Do not profile your game running in the editor, it yields incorrect results, profile a build running on the target hardware instead.

    The following video goes into details why profiling in the editor isn't a great idea.
     
    Rotzak likes this.
  5. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks for the answer. I've turned on interpolation for all the cars but unfortunately it didn't change anything. Here is a picture of my rigidbody 2D settings now:
     
  6. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks for the answer. Idd it looks like the camera is making small movements. I've checked it and the camera has no script attached so can't move probably. Here is a picture of the camera settings, nothing wrong with them I think:


    Can't see something wrong in the script of the track move. Also I turned the background off and builded on my phone but it's still lagging.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class trackMove : MonoBehaviour {
    6.  
    7.     public float speed;
    8.     Vector2 offset;
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.  
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update () {
    17.             offset = new Vector2(0, Time.time * speed);
    18.  
    19.             GetComponent<Renderer>().material.mainTextureOffset = offset;
    20.     }
    21. }
    22.  
     
  7. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Also I want to notice the lagg starts from the beginning so even when the game is paused. I don't know if you can see it in this video but in my opinion the ghost that moves up after countdown is really stuttering (animation). Here is a video:



    When the game became this slow there also happened something in the menu. In the menu you can choose out of 8 players. 6 out of the 8 player sprites where you can choose from were heavily blurred. Notice that these are just sprites! I fixed this by changing the max size of the sprites from 2048 to 1024pixels .
     
    Last edited: Aug 13, 2018
  8. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    I've disabled all objects, audio and other stuff and here is the result on my phone (apk build):



    Doesn't look smooth at all to me lol. Any ideas really don't know what to do now :eek:
     
  9. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    What version of Unity are you using?

    Maybe use renderer.sharedmaterial instead of material since the material property of renderer is creating a new instance everytime you call it. Since you’re doing it every frame you’re creating a material every frame.

    Read the note & code, you should call it once and store it. Then use that instanced reference.
    https://docs.unity3d.com/ScriptReference/Renderer-material.html

    What is the target frame rate set to? Is it 30 or 60? (debug it on the device, not in unity editor)
    Debug.Log(Application.targetFrameRate);

    if 30 try setting it to 60 (note that this does use more battery)
    Application.targetFrameRate = 60;


    Have you tried a development build on the phone and profile that, instead of the Editor?

    Is the spike also occuring if you lower the speed variable? Is it less frequent when you lower it?
     
    Last edited: Aug 13, 2018
    Rotzak and FernandoHC like this.
  10. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks for the answer will try this out tommorow. I was using 2018.1 and I've updated to 2018.2 just now, so many TextMesh errors...
     
  11. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    Listen man, i have the SAME problem as yours!!!
    I've opened a thread few days ago and no one could help me.
    I consider remove my project now because this stupid thing...
    It's just not smooth and there is no excuse!
    Profiler says nothing, script is optimized i guess and the sprites are low compressed.
    If you find an answer pleaseee send me a message.
     
  12. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Sure will do what kind of game was it? Were you also spawning objects top down?
     
  13. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Update:
    I've made a new scene in my current project with only a moving track. I disabled all the other scenes in the build settings and builded it to my phone. Here is the result:




    After I made a new project with exact the same objects:



    Result: It's sad I cant share what I see but the new project isn't stuttering at all. The scene made in the current project is stuttering heavily. It's not really stuttering but you can see that the lines are vibrating.

    Conclusion: I really don't have an idea but this is really weird isn't it exact the same becuase I disabled all the other scenes in the current project??? I mean in both cases there is just one script running if I'm correct.
     
    Last edited: Aug 14, 2018
  14. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    So first I added
    Debug.Log(Application.targetFrameRate);
    in the Update function of a random script. The console was constantly debugging "-1". After I added in the start function of the same script:
    Application.targetFrameRate = 30;
    . Builded in to my phone and the vibrating was even worse. After I did another build but now I wrote this in the start function:
    Application.targetFrameRate = 60;
    .

    Result: It's much better now but it's still not OK. It looks like the vibrations are in the car itself now and not around it anymore.

    What can I conclude out of this? And what can I do to remove these vibrations totally?
    Also I have the feeling the vibrations are getting worse the longer I play. Not sure of this it could be also eye deception.
     
    Last edited: Aug 14, 2018
  15. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    -1 just means there's no limit and it'll go fast as it can.

    You should post some code.
     
  16. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
  17. Shayke

    Shayke

    Joined:
    Dec 8, 2017
    Posts:
    352
    Endless runner, I used object pooling.
     
  18. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
  19. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    It could be the code, i'm an beginner. I've started c# and Unity on 17 June and I never did anything with programming in my life. But what code would be relevant? I Have around 20-30 scripts and I'm calling probably way too much in the update functions.

    Here is my enemy car mover script. The enemy cars are really unclear and vibrating. So that's actually the biggest problem atm. The player car on the other hand is clear because it isn't moving.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class EnemyCarMove : MonoBehaviour {
    6.  
    7.     public float speed = 8.0f;
    8.  
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.    
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update () {
    17.  
    18.         transform.Translate(new Vector3(0, 1, 0) * speed * Time.deltaTime);
    19.  
    20.     }
    21. }
    22.  
    Here is my enemycarspawner script this is probably a bit vague and not optimized. The script is attached to an empty gameobject:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System.Linq;
    5.  
    6.  
    7. public class CarSpawner : MonoBehaviour {
    8.  
    9.     public GameObject[] cars; //Change to array to add more different cars (datatype = gameObject ,en [] verwijst naar een array, en cars is de naam van de array)
    10.     //int[] numbers = { 0, 1, 2, 3, 4, 5, 6, 7 };
    11.  
    12.     int carNo;
    13.     int carNoTwo;
    14.     int randomSpawnNo;
    15.  
    16.     public float maxPos = 1.60f;
    17.  
    18.     bool SpawnTwoCars;
    19.     float dist;
    20.  
    21.     public float delayCarTimer;
    22.     float carTimer;
    23.     //public float truckTimer = 5.0f;
    24.  
    25.     public List<int> xPositions = new List<int>();
    26.  
    27.     float notSpawnPositionMin;
    28.     float notSpawnPositionMax;
    29.  
    30.     float newMinPosition;
    31.     float newMaxPosition;
    32.  
    33.     bool spawnOnLeftSide;
    34.     bool spawnOnRightSide;
    35.  
    36.     //bool oneTime = true;
    37.  
    38.     // Use this for initialization
    39.     void Start() {
    40.  
    41.         carTimer = delayCarTimer; //Timer is bij start gelijk aan één
    42.                                   //truckTimer = delayTruckTimer;
    43.  
    44.         Vector3 StartCarPos = new Vector3(0, transform.position.y, transform.position.z); //Positie van het spawnen
    45.  
    46.         carNo = Random.Range(0, 77);
    47.  
    48.         Instantiate(cars[carNo], StartCarPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)
    49.  
    50.     }
    51.  
    52.     // Update is called once per frame
    53.     void Update()
    54.     {
    55.         if (UImanager.score <= 5)
    56.         {
    57.             delayCarTimer = Random.Range(0.60f, 0.90f);
    58.         }
    59.         if (UImanager.score > 5)
    60.         {
    61.             delayCarTimer = Random.Range(0.60f, 0.85f);
    62.         }
    63.         if (UImanager.score > 10)
    64.         {
    65.             delayCarTimer = Random.Range(0.60f, 0.80f);
    66.         }
    67.  
    68.         if (UImanager.score > 15)
    69.         {
    70.             delayCarTimer = Random.Range(0.55f, 0.70f);
    71.         }
    72.  
    73.         /*
    74.         if (UImanager.score > 40)
    75.         {
    76.             delayCarTimer = 0.60f;
    77.         }
    78.         if (UImanager.score > 50)
    79.         {
    80.             delayCarTimer = 0.60f;
    81.         }
    82.         if (UImanager.score > 100)
    83.         {
    84.             delayCarTimer = 0.60f;
    85.         }
    86.         if (UImanager.score > 200)
    87.         {
    88.             delayCarTimer = 0.65f;
    89.         }
    90.         if (UImanager.score > 500)
    91.         {
    92.             delayCarTimer = 0.60f;
    93.         }
    94.         if (UImanager.score > 700)
    95.         {
    96.             delayCarTimer = 0.60f;
    97.         }
    98.         if (UImanager.score > 800)
    99.         {
    100.             delayCarTimer = 0.60f;
    101.         }
    102.         if (UImanager.score > 900)
    103.         {
    104.             delayCarTimer = 0.55f;
    105.         }
    106.         if (UImanager.score > 950)
    107.         {
    108.             delayCarTimer = 0.50f;
    109.         }
    110.         */
    111.  
    112.         carTimer -= Time.deltaTime; //De echte tijd wordt afgetrokken van de timervalue die bij start één is, en wordt daaraan gelijkgesteld
    113.                                     //truckTimer -= Time.deltaTime;
    114.  
    115.         SpawnOneCar();
    116.  
    117.         SpawnTwoCarsAtSameTime();
    118.  
    119.         /*if (truckTimer <= 0)
    120.         {
    121.             SpawnTruck();
    122.         }*/
    123.     }
    124.  
    125.     public void SpawnOneCar()
    126.     {
    127.         if (carTimer <= 0 && SpawnTwoCars == false) //Zodra het spel één seconde bezig is zal er aan deze voorwaarde voldaan zijn
    128.         {
    129.                 //Get last position of the list
    130.                 int number = xPositions.Count;
    131.                 int lastItem = xPositions[number - 1];
    132.  
    133.                 if (lastItem <= 0)
    134.                 {
    135.                     spawnOnRightSide = true;
    136.                 }
    137.  
    138.                 if (lastItem > 0)
    139.                 {
    140.                     spawnOnLeftSide = true;
    141.                 }
    142.  
    143.                 //Not spawning between a range of +-1 of the last car position
    144.                 notSpawnPositionMin = (lastItem) - 1f;
    145.                 notSpawnPositionMax = (lastItem) + 1f;
    146.  
    147.                 //Spawn positions for the next car
    148.                 newMinPosition = Random.Range(-maxPos, notSpawnPositionMin);
    149.                 newMaxPosition = Random.Range(notSpawnPositionMax, maxPos);
    150.  
    151.                 //Round to int so we can add the new car position to the list
    152.                 int checkXAgainRight = Mathf.RoundToInt(newMaxPosition);
    153.                 int checkXAgainLeft = Mathf.RoundToInt(newMinPosition);
    154.  
    155.                 if (spawnOnRightSide == true)
    156.                 {
    157.                     xPositions.Add(checkXAgainRight);
    158.                 }
    159.  
    160.                 if (spawnOnLeftSide == true)
    161.                 {
    162.                     xPositions.Add(checkXAgainLeft);
    163.                 }
    164.  
    165.             SpawnOneCarLeftOrRight();
    166.         }
    167.     }
    168.  
    169.     public void SpawnOneCarLeftOrRight()
    170.     {
    171.             if (spawnOnLeftSide == true)
    172.             {
    173.                 Vector3 NewCarPos = new Vector3(newMinPosition, transform.position.y, transform.position.z); //Positie van het spawnen
    174.  
    175.                 carNo = Random.Range(0, 77);
    176.  
    177.                 Instantiate(cars[carNo], NewCarPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)
    178.  
    179.                 carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is
    180.  
    181.             randomSpawnNo = Random.Range(0, 8);
    182.  
    183.                 spawnOnLeftSide = false;
    184.  
    185.                 if (randomSpawnNo == 5)
    186.                 {
    187.                     SpawnTwoCars = true;
    188.                 }
    189.             }
    190.  
    191.             if (spawnOnRightSide == true)
    192.             {
    193.                 Vector3 NewCarPos = new Vector3(newMaxPosition, transform.position.y, transform.position.z); //Positie van het spawnen
    194.  
    195.                 carNo = Random.Range(0, 77);
    196.  
    197.                 Instantiate(cars[carNo], NewCarPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)
    198.  
    199.                 carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is
    200.  
    201.             randomSpawnNo = Random.Range(0, 8);
    202.  
    203.                 spawnOnRightSide = false;
    204.  
    205.                 if (randomSpawnNo == 5)
    206.                 {
    207.                     SpawnTwoCars = true;
    208.                 }
    209.             }
    210.     }
    211.  
    212.     public void SpawnTwoCarsAtSameTime()
    213.     {
    214.             Vector3 carPosOne = new Vector3(Random.Range(0.70f, maxPos), transform.position.y, transform.position.z);
    215.  
    216.             float secondMin = -maxPos;
    217.             float secondMax = maxPos;
    218.             float halfway = 0;
    219.  
    220.             if (carPosOne.x >= halfway)
    221.             {
    222.                 secondMax = carPosOne.x - 2.30f;
    223.             }
    224.  
    225.             else
    226.             {
    227.                 secondMin = carPosOne.x + 2.30f;
    228.             }
    229.  
    230.             Vector3 carPosTwo = new Vector3(Random.Range(secondMin, secondMax), transform.position.y, transform.position.z);
    231.  
    232.             //dist = Vector3.Distance(carPosOne, carPosTwo);
    233.  
    234.             carNo = Random.Range(0, 77);
    235.             carNoTwo = Random.Range(0, 7);
    236.  
    237.             if (SpawnTwoCars == true && carTimer <= 0)
    238.             {
    239.                 Instantiate(cars[carNo], carPosOne, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)
    240.  
    241.                 Instantiate(cars[carNoTwo], carPosTwo, transform.rotation);
    242.  
    243.                 carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is
    244.  
    245.                 SpawnTwoCars = false;
    246.             }
    247.     }
    248.  
    249.     /*public void SpawnTruck()
    250.     {
    251.         if (oneTime == true)
    252.         {
    253.         Vector3 TruckPos = new Vector3(Random.Range(-maxPos, maxPos), transform.position.y, transform.position.z); //Positie van het spawnen
    254.  
    255.         Instantiate(truck, TruckPos, transform.rotation); //We use the position and rotation of the CarSpawnPosition (empty gameobject)
    256.  
    257.         carTimer = delayCarTimer; //We zetten de timer terug naar zijn startvalue, welke een is
    258.  
    259.         truckTimer = 5.0f;
    260.  
    261.         oneTime = false;
    262.  
    263.         }
    264.    
    265.     }*/
    266.  
    267. }
    268.  
    269.  
    270.  
    And here is my enemycar import settings. I've tried a few different settings but maybe you spot something wrong:

     
    Last edited: Aug 14, 2018
  20. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
  21. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Unity remote is just casting the screen onto your device and use the device input to hand it back to the editor.
    Personally I never use the Unity Remote because it just buggy and sucks. It isn't the same experience as building the APK for the target device.

    As Shayke said in an endless runner it is highly advisable to use object pooling.
    You don't want to constantly keep instantiating prefabs again and again.
    Rather on start, instantiate a few to fill the pool a bit by an initial amount.
    While running -> get a car from the pool (set active) -> track its life cycle (position) -> if end of life cycle (out of screen bounds) -> return to the pool (set inactive)
    if there is no car available from the pool instantiate one.
    Something along those lines.

    You're currently moving the texture using a textureoffset, not sure how precise that is and whether it has an effect when you increase the texture offset by such a high amount (since it builds up every frame).

    If I were making an endless runner like that I'd move 2 or 3 road pieces. If it reaches a certain Y point, reset it back to the top.
     
    Last edited: Aug 15, 2018
  22. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Its great for working out input schemes that can't be reproduced on the computer. Things like cameras or gyro data. But otherwise I agree with you.
     
    Joe-Censored likes this.
  23. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Ok thanks I'll try to do something like this
     
  24. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Made a new project with only the moving track and the spawning cars. The cars are still vibrating and when I lower the speed they don't. So the vibrations are caused by the high speed of the spawning cars. Question is how can I avoid this? I really need the higher speed.
     
  25. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    Avoid using Instantiate and similars. Instantiating is a heavy operation.
    Do all your initializations/Instantiations in the loading of your level and then pool/recycle objects by activating(true/false). This should increase performance considerably if caused by Instantiate.
     
    Content1of_akind and Rotzak like this.
  26. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    I'm currently spawning objects with the pool method in my test scene. Uploaded to my phone and the issue still occurs. The cars are still vibrating. I'm wondering if it's even possible in Unity to move objects fast without vibrations.

    Also I tried these 5 methods for movement with no succes:

    Code (CSharp):
    1.    void Update()
    2.     {
    3.         //transform.Translate(new Vector3(0, -1, 0) * speed * Time.deltaTime);
    4.         //rb.AddForce(-transform.forward * 500);
    5.         //transform.position += -transform.up * speed * Time.deltaTime;
    6.         //rb.MovePosition(transform.position + (-transform.up * speed * Time.deltaTime));
    7.         //rb.velocity = -transform.up * Time.deltaTime * speed;
    8.     }
     
  27. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Because I'm never going to find the solution on my own I'm sharing my test project here. It's a simple scene with one car. When you tap anywhere on your phone a car will be spawning. Build and run this to your phone and U'll see that the car is vibrating. The car has a number on it which u can barely read.

    This is a WeTransfer link which contains the unity project (Zipped). I'm using the last version of Unity (2018.2.3f1)
    https://we.tl/t-2jF2Hgvb51

    Help is much much much appreciated.
     
  28. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    Try moving your camera logic from Update() to LateUpdate(), and then look into various camera techniques for smoothing. This feels like a camera issue if you've already turned a lot of things off already.
     
    Content1of_akind likes this.
  29. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks for the input, but there isn't a script attached to the camera. It idd looks like it.
     
  30. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    What kind of phone you have?
     
  31. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    Hmm. If you need your physics to update lock-step, in a stable manner, try converting your movement logic to use fixed timestep intervals (you'll need to set your fixed time step to your target framerate in the editor or via a startup script) and migrate your logic to FixedUpdate() using Time.fixedDeltaTime instead of Time.deltaTime.

    Only other thing I can think of to do without diving into your project (I'm at work) is to look at creating a build with deep profiling enabled or use the Profiler.Begin/EndSample() functions for slices of code you think may be the culprit.

    This article goes into where micro-stuttering can occur, even in a seemingly "optimized" deltaTime update loop, even on beefy PC hardware:
    https://medium.com/@alen.ladavac/the-elusive-frame-timing-168f899aec92

    My recommendation continues to be that if you have important gameplay movement, even if it uses kinematic or custom physics, it should still use the FixedUpdate() loop timing. Secondary animations, non-essential things like UI tween effects can run at update speeds and stutter is acceptable, even if not preferred.

    You may also want to consider using a manager-type updater class that will apply your car movement to all car scripts at once, instead of relying on the normal Update() / FixedUpdate() script calls. See this blog post for more details: https://blogs.unity3d.com/2015/12/23/1k-update-calls/
     
  32. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Samsung J5 2017 I believe.
     
  33. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Already tried to put the movement code in fixedUpdate but unfortunately it doesn't fix anything :(. Also in the project you can find here https://we.tl/t-2jF2Hgvb51 there is actually only one line of code that defines the movement which is:

    Code (CSharp):
    1. private void FixedUpdate()
    2.     {
    3.         transform.Translate(-Vector3.up * Time.fixedDeltaTime * 5);
    4.     }
    .

    I also eliminated almost everything else from the project so nothing else can affect this stuttering. Thanks for the links will look into these soon. I invite you to look at my project if you have some spare time, thanks ;)
     
  34. diegoossal

    diegoossal

    Unity Technologies

    Joined:
    May 10, 2018
    Posts:
    4
    Hi @Rotzak,

    You only have to use
    Application.targetFrameRate = 60;
    once in your code. For example in the Awake of your Manager.
    In the case of the car movement, if your object has a RigidBody, you can also use Velocity. In that way, you are not using the Update method.

    Like this:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class MoveObjectForce : MonoBehaviour
    4. {
    5.     private Rigidbody2D rb;
    6.    
    7.     private void Start()
    8.     {
    9.         rb = GetComponent<Rigidbody2D>();
    10.         rb.velocity = -Vector3.up * 10;
    11.     }
    12. }
    I think your game is running very well, try to keep going since you are starting, we are here to help you.
     
    FernandoHC likes this.
  35. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I'll try to take a look this weekend. I've been prepping something for launch with my day job, but it goes into final RC testing next week and so I've got more energy to look at things like this.

    One thing I haven't seen while re-skimming the thread is to take a look at your VSync settings for your platform. Try doing what @diegoossal above suggested, and also look at enabling/disabling Vsync for your platform and see what that does.

    Another thing I remembered is that some mobile platforms may throttle due to battery / power settings:
    https://answers.unity.com/questions/1464484/android-vsync-auto-enabling.html
     
  36. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Vsync can't be disabled on iOS / Android, it is forced on.
    https://support.unity3d.com/hc/en-u...game-flips-between-running-at-30FPS-and-60FPS
    So either setting it to 30 or 60 would do. The default TargetFramerate (-1) sets the framerate to 30 fps on the mobile platforms. You can set it to 60 fps with
    Application.targetFrameRate = 60;
     
    Rotzak likes this.
  37. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks for the help. But I can clearly see a difference between stationary objects and moving objects in my game. I have the feeling everything I'm trying to move (backgrounds, objects etc...) in Unity vibrates. Or is this just normal and caused by the fps?
     
  38. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thanks. I've already disabled Vsync in the past. Battery settings are fine on my phone (didn't know it affected the fps).
     
  39. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I have a light day now (these last few weeks we've been shipping something) but your link doesn't work anymore. Do you still need some eyes on it?
     
  40. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Yes would really appreciate it, here is a new link: https://we.tl/t-iTPU14XDK4.
     
  41. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    Just another comment, make sure you aren't doing a lot of Debug/print statements in your code in something like an update or coroutine as this can slow things down.

    Might not be your issue, just adding it on as another thing to watch for.
     
    Last edited: Sep 6, 2018
    Rotzak likes this.
  42. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    Having a look at this and running the deep profiler, it looks like it's partially that you're stuck with VSync and there's some hiccuping with that in the editor. That being said here's what I can see:

    * Your code is extremely light. Obviously you've stripped it down for this sample but there's not much going on that your code is doing. Even with the deep profiler most of your code runs in less than 3ms because there's not much going on.
    * In the editor, almost all of the performance issue hiccups at all is entirely VSync + editor overhead for the majority of frames. I have a GTX 970 and an i7 4770k with 16 GB. I still noticed some hiccuping, which tells me this is some kind of sync issue and less a raw perf issue. Like most frames in the editor are WaitForTargetFPS, which is normally pretty good, as that means editor overhead and VSync are your biggest framepace constraints.
    * I wasn't able to test against my galaxy S7 tonight, since I had to replace a failing hard drive a few months ago and forgot to reinstall the android dev tools. I'll see if I can get to that tomorrow, but I doubt a mobile performance gap would still explain the issue.
    * I noticed your TestObject script has the FPS override, you should probably move that into TestManager. This won't affect much right now, but your gameplay objects shouldn't be adjusting application settings, and on top of that if you can avoid your instanced objects doing any logic, you should do so.
    * I also noticed that you're both using a non-Kinematic rigidbody, and also translating manually via update, that can cause transform sync issues. Setting the rigidbody to Kinematic seems to have smoothed out the issue, as the rigidbody transform sync no longer interferes with the manual transform update. If you're writing extremely custom motion, you may want to skip using Dynamic/Static rigidbodies and set them to kinematic if you want them to interact with physics objects. Right now you're not moving the rigidbodies with the rigidbody physics, so if you can avoid that extra sync, it may work out better as the issue may not be performance, but the physics system fighting with your movement code, despite no forces acting on the rigidbody. "Manual" physics is used a lot for platformers and other games where tight control is more important the semi-random/complex physics that PhysX/Bullet/Box2d Might provide (or the results from those are massaged/constrained to get the intended effect).
    * See what happens if you run on your phone with "full release" settings, no development build, no unity remote, minimal logging. Then test against the normal profiler and the deep profiler and see where any spikes or drops are comping from.
     
  43. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Thank you very much for your effort! Will look into this soon! Currently I've uploaded my game on the google play store because I want to know if it's any good before I put more time into it.

    https://forum.unity.com/threads/google-play-store-spooky-driver.551524/
     
    recursive likes this.
  44. TheSaviour

    TheSaviour

    Joined:
    Apr 20, 2015
    Posts:
    68
    Hi,

    I'm actually facing a similar problem with my game. I described the issue in this thread. Did you manage to find what's causing the problem?
     
  45. Rotzak

    Rotzak

    Joined:
    Jul 11, 2018
    Posts:
    92
    Hello, no I never managed to solve the problem and did put alot time in it. Let me know if you find a solution.
     
  46. PerfectSkies

    PerfectSkies

    Joined:
    Jan 2, 2019
    Posts:
    3
    https://drive.google.com/open?id=1unnDQpAkBn2EHAA50sZmgDKrQEl-f24i
    I've spend 4 hours of my Sunday building this... I've been here before!! This project might give you some insight as to a stable frame rate background scroller. (58-60 fps on a toaster). I hope it helps!:)
     
    Last edited: Sep 29, 2019
  47. LuyaGames

    LuyaGames

    Joined:
    Jan 22, 2019
    Posts:
    19
    Hi! One of my future games looks like yours. I chose another approch to address the infinite scrolling background. I use RigidBody velocity and I think it may be smoother than a Translate. Here's how, give it a try :

    In Editor, I created two 2D sprites called background and background_repeat. I added a Rigidbody2D on both backgrounds. Both are set as Kinematic, Simulated, Discrete and Start awake.

    Then I added 3 scripts to both of them :
    - FullwidthSprite so the background adapts to device width. The main Camera must be othographic for it to work.
    - ScrollingObject so the background moves down giving impression that the car is at high speed.
    - RepeatingBackground so the backgrounds change position to give illusion it is infinite.

    The ScrollingObject exposes 2 public fields, Xvel and Yvel, so you can make an Object move in all directions. To make the background move toward the bottom, just let Xvel = 0 and Yvel < 0 (for example, Yvel = -6) from the Editor.

    The RepeatingBackground exposes the public field isRepeater to make one background place itself adequatly on top of the other one. Check it on background_repeat from the Editor.

    The ScrollingObject and RepeatingBackground were originaly from here : https://unity3d.com/fr/learn/tutorials/topics/2d-game-creation/scrolling-repeating-backgrounds

    Also, I made the RepeatingBackground wait for FullwidthSprite effect before it starts. It's mandatory because the FullwidthSprite may change the scale of the sprite and thus it's size and thus it's position when repeating. Otherwise they may overlap or there may be a gap between them.

    Here are the 3 classes :

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class FullwidthSprite : MonoBehaviour
    4. {
    5.     public bool fullwidthed;
    6.     private static readonly object syncobj = new object();
    7.     void Start()
    8.     {
    9.         lock (syncobj)
    10.         {
    11.             if (!fullwidthed)
    12.             {
    13.                 SetFullwidth();
    14.             }
    15.         }
    16.     }
    17.  
    18.     private void Update()
    19.     {
    20.         lock (syncobj)
    21.         {
    22.             if (!fullwidthed)
    23.             {
    24.                 SetFullwidth();
    25.             }
    26.         }
    27.     }
    28.  
    29.     public void SetFullwidth()
    30.     {
    31.         SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
    32.         if (spriteRenderer != null && spriteRenderer.sprite != null)
    33.         {
    34.             Vector2 spriteSize = spriteRenderer.sprite.bounds.size;
    35.  
    36.             var height = 2 * Camera.main.orthographicSize;
    37.             var width = height * Camera.main.aspect;
    38.  
    39.             var widthRatio = width / spriteSize.x;
    40.  
    41.             transform.localScale *= widthRatio;
    42.  
    43.             fullwidthed = true;
    44.         }
    45.     }
    46. }
    47.  
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class ScrollingObject : MonoBehaviour
    5. {
    6.     private Rigidbody2D rigidbody;
    7.     public float xvel;
    8.     public float yvel;
    9.  
    10.     private FullwidthSprite fssprite;
    11.  
    12.     private IEnumerator Start()
    13.     {
    14.         fssprite = gameObject.GetComponent<FullwidthSprite>();
    15.  
    16.         yield return new WaitUntil(() => fssprite.fullwidthed);
    17.  
    18.         rigidbody = gameObject.GetComponent<Rigidbody2D>();
    19.         if (rigidbody != null)
    20.         {
    21.             rigidbody.velocity = new Vector2(xvel, yvel);
    22.         }
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.  
    29.     }
    30. }
    31.  
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class RepeatingBackground : MonoBehaviour
    5. {
    6.     private float backgroundVerticalLength;       //A float to store the x-axis length of the collider2D attached to the Ground GameObject.
    7.  
    8.     private FullwidthSprite fssprite;
    9.  
    10.     public bool isRepeater;
    11.  
    12.     private IEnumerator Start()
    13.     {
    14.         fssprite = gameObject.GetComponent<FullwidthSprite>();
    15.         yield return new WaitUntil(() => fssprite.fullwidthed);
    16.  
    17.         //Store the size of the collider along the x axis (its length in units).
    18.         var spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
    19.         if (spriteRenderer != null && spriteRenderer.sprite != null)
    20.         {
    21.             backgroundVerticalLength = spriteRenderer.sprite.bounds.size.y * transform.localScale.y;
    22.         }
    23.  
    24.         if (isRepeater)
    25.         {
    26.             transform.position = new Vector3(0, backgroundVerticalLength, 0);
    27.         }
    28.         else
    29.         {
    30.             transform.position = Vector3.zero;
    31.         }
    32.     }
    33.  
    34.     //Update runs once per frame
    35.     private void Update()
    36.     {
    37.         //Check if the difference along the y axis between the main Camera and the position of the object this is attached to is greater than groundVerticalLength.
    38.         if (transform.position.y < -backgroundVerticalLength)
    39.         {
    40.             //If true, this means this object is no longer visible and we can safely move it forward to be re-used.
    41.             RepositionBackground();
    42.         }
    43.     }
    44.  
    45.     //Moves the object this script is attached to top in order to create our looping background effect.
    46.     public void RepositionBackground()
    47.     {
    48.         //This is how far to the top we will move our background object, in this case, twice its length. This will position it directly to the top of the currently visible background object.
    49.         Vector3 groundOffSet = new Vector3(0, backgroundVerticalLength * 2f, 0);
    50.  
    51.         //Move this object from it's position offscreen, behind the player, to the new position off-camera in front of the player.
    52.         transform.position = transform.position + groundOffSet;
    53.     }
    54. }
    55.  
    I hope it helps!
     
  48. Ko8e

    Ko8e

    Joined:
    Jan 10, 2020
    Posts:
    14
    Do not use "GetComponent<>" inside update. Always do it in Start() or Awake() and then assign to a reference variable. use that reference variable in the script.
     
  49. jayjona

    jayjona

    Joined:
    Oct 4, 2016
    Posts:
    2
    I was having a close problem with the lagging. I went into : Edit - Project Settings - Quality - and then unticked the high quality settings and ultra quality settings. Since then it has been testing fine during test run in game play. Hope that helps.
     
  50. unity_x_qe4ZQcRm_jUg

    unity_x_qe4ZQcRm_jUg

    Joined:
    Sep 6, 2020
    Posts:
    2
    Have you considered using "FixedUpdate" instead of "Update" method? Maybe it would prevent lagging...