Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Transform.Translate speeding up on Max screen size?

Discussion in 'Scripting' started by Vildez, Oct 9, 2014.

  1. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Hello,
    I am making a game that scrolls an object across the screen. I have finally managed to get them spawning and destroying the way that I want them to. However, I have noticed that if I change my resolution the speed of the objects seems to get faster as the res gets higher. For example if I'm looking at my game scene view in just a small window they are moving just exactly how I want them to. If I select the option to maximize on play then they go so fast that it breaks what I want the game to do. here is the code that I use to move the objects across the screen.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq.Expressions;
    5.  
    6. public class scriptDuckControler : MonoBehaviour {
    7.    
    8.     // Update is called once per frame
    9.     void Update ()
    10.     {
    11.         if (transform.tag == "duck_left")
    12.         {
    13.             if (this.transform.position.x <= -4.2)
    14.             {
    15.                 GameObject.Destroy(this.gameObject);
    16.             }
    17.             else
    18.             {
    19.                 this.transform.Translate(-.025f, 0, 0);
    20.             }
    21.         }
    22.  
    23.         else if (transform.tag == "duck_right")
    24.         {
    25.             if (this.transform.position.x >= 4.0f)
    26.             {
    27.                 GameObject.Destroy(this.gameObject);
    28.             }
    29.             else
    30.             {
    31.                 this.transform.Translate(.025f, 0, 0);
    32.             }
    33.         }
    34.     }  
    35. }
     
  2. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Your movement code does not seem to be frame rate independent. Look up Time.deltaTime in the documentation. Short story; multiply speeds with it.
     
    Joe-Censored likes this.
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    That's a good point, but how could that cause the particular issue the OP is having? It seems to me, if anything, having a bigger screen = lower framerate = his movement would be slower, not faster, if not having Time.deltaTime was the cause of his problem.
     
    ThermalFusion likes this.
  4. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    So this being said and both of your points being valid could someone please give me an example how they would move the ducks across the screen. I'm not sure I understand what you guys are saying but I do get the code and that would be very helpful. Thank you very much for taking the time to do this.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    His suggestion is to basically do this:
    Code (csharp):
    1.  
    2. this.transform.Translate(-1f * Time.deltaTime, 0, 0);
    3.  
    The main thing that this concept does is to make it frame-rate independent. No matter how fast or slow the game is running, with the above, your guy will constantly move 1 unit per second.

    ....and while you should definitely always be doing this, I would be surprised and confused if this actually solves the problem you came here with.
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    As for the actual problem.... I'm having a tough time imagining what could be going on here. Would it be possible for you to record a screencast demonstrating the problem, as well as showing a quick overview of the setup of this scene? Weird as it sounds, in a case like this, little details like, for example, the exact proportion of just how much faster the ducks are moving at different screen sizes, can really help point to certain things as the source of the problem. Plus, little details in the way the scene is setup, which are certain to escape the notice of a novice Unity user, but might stick out like a sore thumb to someone who's experienced.
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    And finally, one other thing - and again, this is almost certainly not your core problem - is, you should learn how to use public variables. Tags are probably the most inconvenient way you could possibly be controlling which ducks go which direction. You can replicate your current functionality in a much cleaner, more versatile way by using instead a bool "isMovingRight":
    Code (csharp):
    1.  
    2.  
    3. public bool isMovingRight = true;
    4. void Update() {
    5. if (isMovingRight) {
    6. if (transform.position.x >= 4f) Destroy(gameObject);
    7. else transform.Translate(1f * Time.deltaTime, 0f, 0f);
    8. }
    9. else {
    10. if (transform.position.x <= -4f) Destroy(gameObject);
    11. else transform.Translate(-1f * Time.deltaTime, 0f, 0f);
    12. }
    13. }
    14.  
    and now you have a little checkbox in your script that controls whether your duck is moving left or right.

    But wait! there's more. Why not make the speed customizable in your duck as well? Throw in a public float, and use that number in place of "1f" in your translate command. Why restrict them to left and right? Make it a public Vector3 instead, and use transform.Translate(yourMovementVector * Time.deltaTime)! The possibilities are endless here. There's very little reason not to have public variables controlling nearly everything in your game, and in my experience, there's also very little reason ever to use GameObject.tag for....well, anything....
     
  9. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    Massive necro here, and as a newbie to contributing I apologise if this is against the rules, but this is my exact problem at the moment.

    I have an AI chasing a "bunny" along a waypoint path around a track. When testing without Maximise on Play it's fine.
    There's limits on acceleration and deceleration - if AI too close to Bunny then slow down, and there's also a max speed.

    However, now it's all working nicely, testing in Maximise on Play seems to strip all these variables, the AI goes as fast as it pleases, passes through the cube and then has a fit trying to get back to it, none of the constraints outlined above are in play.

    Purely through playing with Maximise On Play. Dragging the window to make it bigger works fine, scene view is fine, the code throws no errors.

    Did anything ever come of this?
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    It means your code is not framerate-independent, which was the same thing the OP did.

    --Eric
     
  11. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    Duh, I was using LateUpdate and not Fixed. My bad.

    Thank you.

    Is there an equivalent to Late Fixed?
    I read that LateUpdate should be used when taking into account player input, and that physics should be done with Fixed. What if you're doing both?
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    FixedUpdate is only for physics. It's unlikely you want to use that. The issue is not LateUpdate, or Update, but the fact that your code is not framerate-independent. You should probably read the first several posts in this topic again.

    --Eric
     
  13. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    I only use Time.deltaTime in any calculations, and moving my code to FixedUpdate fixed it so I'm not sure what else could have gone wrong.

    Thanks
     
  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Moving it to FixedUpdate proves that it wasn't framerate-independent. Either you used Time.deltaTime wrong, or you shouldn't have used it (e.g. when tracking mouse input, which is already framerate-independent to start with).

    --Eric
     
  15. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    Hi Eric,

    Thanks for the replies. This error in particular was regarding an AI object following another AI object, no user input, so Fixed Update was indubitably the saviour

    My question regarding user input was a blazé comment as for some reason I'd used LateUpdate which I've never done before, not sure how my code ended up in there. Sorry for the confusion! In retrospect I think my question could be better worded as: (unrelated to original issue)

    If LateUpdate is best for user input, but the user input applies a force, then should it be in LateUpdate or Fixed?

    Bit of a tangent from the original post and not something I need for my project I'm just picking your brains :)

    Thanks
     
  16. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,738
    LateUpdate isn't the best place for user input, Update is. LateUpdate is most often used for code on which no other code would depend, usually visual stuff like trail renderers, making UI elements hover over ingame objects, etc. But the important thing you need to learn from this thread, right now, is that FixedUpdate should almost always only be used for physics. The reason is that if you get in the habit of putting your code in FixedUpdate, your game will be subject to exponential slowdown - that is, it'll perform fine until you add enough stuff to slow it down, and then performance will absolutely crater. But if you use Update for most of your logic, your performance will slow down proportionally instead. See this link for a longer writeup.

    (User Input also gets royally mangled if you use it in FixedUpdate.)

    So when we tell you that moving the code to FixedUpdate is not a good solution, we're saving you big headaches later on.

    All of this would be much easier to explain in the specific rather than the abstract, so if you could post your code (or what your code used to be before it was "fixed"), we would be able to give you a more detailed answer of why it was wrong.
     
  17. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    I refunded the course this was said in for other reasons but now I feel this is more justified. Thanks for this clarification.

    Ok, below is a snippet of my movement function, it's called in FixedUpdate and utilises Left Stick and both Trigger inputs of a Gamepad.

    Code (CSharp):
    1. void Movement()
    2.     {
    3.         //Input
    4.         Vector3 m = new Vector3(-leftStickDir.x, 0, -leftStickDir.y) * Time.deltaTime;
    5.  
    6.         float accelInput = rightTrig * Time.deltaTime;
    7.         float brakeInput = leftTrig * Time.deltaTime * 50;
    8.         //ForwardSpeed
    9.         Vector3 localVelocity = transform.InverseTransformDirection(playerRB.velocity);
    10.         forwardSpeed = localVelocity.z;
    11.  
    12.         float maxRotate = 15;
    13.         float rotateSpeed = maxRotate / forwardSpeed;
    14.    
    15.         //manipulation
    16.         //Remove console error
    17.         if (m != Vector3.zero)
    18.         {
    19.             targRot = Quaternion.LookRotation(m);
    20.         }
    21.    
    22.         if (brakeInput >= 0.1f)
    23.         {
    24.             playerRB.drag = brakeInput;
    25.         } else if (brakeInput >= 0.5f)
    26.         {
    27.             playerRB.drag = brakeInput * 3;
    28.         }
    29.         else
    30.         {
    31.             playerRB.drag = 0.1f;
    32.         }
    33.  
    34.         //Removes sideways movement
    35.         localVelocity.x = 0;
    36.         playerRB.velocity = transform.TransformDirection(localVelocity);
    37.  
    38.    
    39.         if (isGrounded && !isRagdolled)
    40.         {
    41.             //Forward
    42.             playerRB.AddForce(transform.forward * accelInput * moveSpeed, ForceMode.VelocityChange);        
    43.             //Rot
    44.             transform.rotation = Quaternion.Lerp(transform.rotation, targRot, Time.deltaTime * rotateSpeed);
    45.         }
    46.         else if (!isGrounded && !isRagdolled)
    47.         {
    48.             //Air Forward
    49.             playerRB.AddForce(transform.forward * accelInput * moveSpeed / 2, ForceMode.VelocityChange);
    50.             //AirRot
    51.             transform.rotation = Quaternion.Lerp(transform.rotation, targRot, Time.deltaTime * rotateSpeed / 4);
    52.  
    53.         }
    54.         if (forwardSpeed >= fullSpeed - 1)
    55.         {
    56.             playerRB.velocity = Vector3.ClampMagnitude(playerRB.velocity, fullSpeed);
    57.         }
    As you can see there's a lot of physics manipulation - should be in fixed? - from user input.- should be in Update.

    I also have these in FixedUpdate:
    Jump(); - input > AddForce
    ShootWeapon(); Input > raycasts > instantiations > explosion forces
    PlayerFX(); if(# speed) > enable particles
    PlayerAudio(); - Audio strings // I'm guessing this one's for update for sure.




    Thanks for your time!
     
    Last edited: Mar 17, 2020
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Put input code in Update, and physics code in FixedUpdate. It can work to do input in FixedUpdate, but if you get sloppy and start putting *Down or *Up events in there, they will randomly fail, so to be safe it's better to separate them.

    --Eric
     
  19. Deridealized

    Deridealized

    Joined:
    Jan 17, 2017
    Posts:
    46
    Apologies if I'm annoying with my replies, this is new (and valuable!) information to me.

    Should I split my function out then, and have the variables affected by input in their own function inside Update, and access those variables in Movement which should be in FixedUpdate?

    Thank you.
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Yep.

    --Eric
     
    Deridealized likes this.