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

C# noob needs help limiting how far an object travels

Discussion in 'Scripting' started by jpine, Feb 20, 2017.

  1. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    This is my first attempt at writing C#...ever. The last time I tried writing code was in college when Ronald Regan was a first-term POTUS. So here is my question. After hours of trial an error, I got an object to behave pretty much the way I want. What I can't seem to get my head around is how to limit how far the object travels using the up and down keys to move the object on its Y axis. I tried a workaround by using a rigid body and collider combo, but I'm working with a scene purchased from the Asset Store and there is all kinds of parenting and other things making that approach beyond my skill level. I basically want the object to travel anywhere up the Y axis until it hits 15 meters. I want it to be limited to zero meters going down. Like I said, I have the basic code for the movement, and it works just as I want it to. I just want it to stop at a high point and/or down point. I'll paste below. I used Monodevelopment to write the code. Visual Studio was giving me fits.

    Thanks!!!
    JP
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class UpandDown : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

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

    transform.Translate (0f,Input.GetAxis("Vertical")*Time.deltaTime, 0f);

    }
    }
     

    Attached Files:

  2. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    First, please use code tags! https://forum.unity3d.com/threads/using-code-tags-properly.143875/

    Short answer: 1981 ;)

    It's simple:

    Code (CSharp):
    1.  
    2. void Update()
    3. {
    4.     if (transform.position.y <= 15 && transform.position.y >=0)
    5.     {
    6.         transform.Translate(0, Input.GetAxis("Vertical")*Time.deltaTime, 0);
    7.     }
    8.  
    9. }
    Really? For me, it's the complete opposite. I can't even get Monodevelop to start sometimes.
     
    TaleOf4Gamers and jpine like this.
  3. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Thank You!!!! I'll try this in the morning. And thanks for the code tags thing too. ;-)

    Yeah, VS was giving me all kinds of grief. Multiple red warning and yellow cautions popped up randomly in the console. I did a Google search for an alternative and found that Monodevelopment was built in and I could select it in my Preferences. I did so, and the caution and warnings stopped immediately.

    Thanks again for your time in answering what was, for most, a very simple question.
     
  4. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    The Red and yellow cautions are there to show scripting errors and warnings. The grey ones are information, such as Debug.Log. The console you see in VS is pretty much the same as the one in Unity, and you can keep it closed (like I do).

    If you have more questions, ask away :D
     
    jpine likes this.
  5. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Get used to the red and green squiggles, they are actually a very valuable resource. Also as you get experience and knowledge you will learn how to interpret what intellisense is trying to tell you and how to use it complete statements and such.
    And I just started about 3 months ago and I was a junior in high school in 1981.
     
    DroidifyDevs likes this.
  6. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Oh, it wasn't VS that showed the red and yellow warnings. It was the red and yellow error warnings and cautions in Unity's console. The VS was fine. The red and yellow in Unity went away when I used Monodevelopment. Weird, but what do I know? ;)

    I was a 23 year old Freshman, fresh out of the Army, in 1982. I congratulate you on picking up coding in the past few months! I always thought coding was a young person's game. Maybe there's hope for me yet.
     
    Ryeath likes this.
  7. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Well, I'm doing something wrong. No surprises there, sadly. There are no warnings/squiggly lines in Mono, but Unity says "error CS1525: Unexpected symbol 'end-of-file' I've attached the actual C# file.
     

    Attached Files:

  8. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    It's not Visual Studio's fault, its actually helping you by telling you that you have an error in your code. If you write it in monodevelop and go to Unity, Unity will show the error in the console.

    That's because you're missing a bracket at the end. This works:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class UpandDown : MonoBehaviour
    6. {
    7.  
    8.     // Use this for initialization
    9.     void Start()
    10.     {
    11.  
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         if (transform.position.y <= 15 && transform.position.y >= 0)
    18.         {
    19.             transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);
    20.         }
    21.  
    22.     }
    23. } //added this bracket
    It's like saying "My car's engine light was on, so I took out the light bulb and the problem was fixed" :D
     
    jpine likes this.
  9. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Being a gear head since I was old enough to turn a wrench, I love the car warning light analogy! To further the analogy, car warning lights are called "idiot lights" for a reason.

    While the error was noted in Unity, there was no missing bracket error indicated in Mono. Maybe I'll give VS another try after all. In my case "user error" in using VS is more of a probability that it is possibility.

    Thanks again for taking time out of your day to help me on this. It may be simple thing for you, but it's a big deal to me. :)
     
  10. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Ok, the script no longer shows errors, but the line, "if (transform.position.y <= 15 && transform.position.y >= 0)" makes the line " transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);" no longer work. If I comment out the former, the latter works, i.e., the object moves up and down. This is just FYI. I don't want to burden you any further with this problem. I suspect it has to do with the build of the scene and/or model itself. I'll contact the guy I got the scene from on the Asset Store and ask him what, if anything, may be interfering with the addition of the code you've shared with me.

    Thanks again!
     
  11. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Debug.Log is your friend ;)

    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (transform.position.y <= 15 && transform.position.y >= 0)
    4.         {
    5.             transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);
    6.         }
    7.  
    8.         else
    9.         {
    10.             Debug.Log("Object wasn't moved because its Y position " + transform.position.y + " was not between 0 and 15");
    11.         }
    12.  
    13.     }
     
  12. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Well, here is the debug message. It popped up in Unity's console the second I hit the up key. I don't know what to do about it. :)

    object wasn't moved because of its Y position-0.0008266683was not between 0 and 15
    UnityEngine.Debug:Log(Object)
    UpandDown:Update() (at Assets/ArchVizPRO Interior Vol.4/UpandDown.cs:24)
     
  13. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Because you're using >=, you're letting it move for 1 frame after it's 0. Also, it's best to add a reset system:

    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (transform.position.y < 15 && transform.position.y > 0)
    4.         {
    5.             transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);
    6.             return;
    7.         }
    8.  
    9.         else
    10.         {
    11.             if (transform.position.y >= 15)
    12.             {
    13.                 //if it's too high, we need to move it back into the acceptable range
    14.                 transform.position = new Vector3(transform.position.x, 14.9f, transform.position.z);
    15.                 return;
    16.             }
    17.  
    18.             if (transform.position.y <= 0)
    19.             {
    20.                 //if it's too low, we need to move it back into the acceptable range
    21.                 transform.position = new Vector3(transform.position.x, 0.1f, transform.position.z);
    22.                 return;
    23.             }
    24.         }
    25.     }

    CODE EDITED . The previous reset was wrong as it would reset outside of the range.
     
    Last edited: Feb 22, 2017
    jpine and Ryeath like this.
  14. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    I made a Christmas Game (finished in February, but oh well) that uses a similar script. I can post it when I get home later and you can see how it works. Does exactly what DroidyDevs is saying. It is possible for the object to move past your limit before the next if statement so you need to reset it back to the limit.
     
    DroidifyDevs likes this.
  15. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Code (CSharp):
    1. if (sledGo)
    2.         {
    3.             sledTarget = transform.position + new Vector3(0.0f, 0.0f, 5.0f);
    4.             resetSled = transform.position.z;
    5.  
    6.             if (Input.GetKey("right"))
    7.             {
    8.                 rightCheck = sledTarget.x;
    9.                 if (rightCheck < 1.95f)
    10.                 {
    11.                     sledTarget = sledTarget + new Vector3(0.5f, 0.0f, 0.0f);
    12.                 }
    13.             }
    14.  
    15.             if (Input.GetKey("left"))
    16.             {
    17.                 leftCheck = sledTarget.x;
    18.                 if (leftCheck > -1.95f)
    19.                 {
    20.                     sledTarget = sledTarget - new Vector3(0.5f, 0.0f, 0.0f);
    21.                 }
    22.             }
    23.  
    24.             if (Input.GetKeyDown("up"))
    25.             {
    26.                 sledSpeed = sledSpeed + 0.2f;
    27.                 if (sledSpeed > 8.0f)
    28.                 {
    29.                     sledSpeed = 8.0f;
    30.                 }
    31.                 SetSpeed();
    32.             }
    33.             if (Input.GetKeyDown("down"))
    34.             {
    35.                 sledSpeed = sledSpeed - 0.2f;
    36.                 if (sledSpeed < 4.0f)
    37.                 {
    38.                     sledSpeed = 4.0f;
    39.                 }
    40.                 SetSpeed();
    41.             }
    42.  
    43.             if (resetSled >= 48f)
    44.             {
    45.                 transform.position = new Vector3(transform.position.x, 0.15f, -48.5f);
    46.             }
    47.             else
    48.             {
    49.                 transform.position = Vector3.MoveTowards(transform.position, sledTarget, step);
    50.             }
    51.         }
    This works by setting a target (sledTarget) ahead of the sled and using the moveTowards command. Just like a carrot in front of a horse, the target will always be just in front of the sled. The furthest position I want the sled to go is between -2 to 2 on the x axis. When if the right key is pressed it gets the x location. If the x location is less than the limit the script adds .5 to the target x. On left key same thing but minus. If the target is outside of the range it just skips the x axis adjustment and the sled moves straight line even if the key is pressed. Note I don't check if a target is equal to the limit, just if it is out of the range.

    Note on the math, the limit is 2.0, but the check is 1.95. That allows for the one time movement after the last positive check that DroidifyDevs is talking about.
     
    DroidifyDevs likes this.
  16. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Well apparently, when it comes to coding, I'm incapable of copying and pasting without having an error. Line 37 is the problem. Even though there is an "}" in the line, the editor says, "} expected". I tried copying and pasting in VS and Mono with the same results. Please tell me that learning to code is always this frustrating when you're starting out. :mad:
     

    Attached Files:

  17. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Again, you forgot a bracket at the end. Remember, if you type "{", you'll need a "}" after it.

    This is a handy tip:
    VSCodeSnip1.PNG
    In the screenshot, you see that your last bracket is for the Update function. Note how VS kindly highlights both brackets, so you instantly know what that last bracket is for. Now look above. After MonoBehaviour, you see a lonely "{", who hasn't found his soulmate "}" yet because of you :(

    So add another bracket in the end. It's not frustrating, you just need to learn the basics. Have you done the Unity tutorials yet? Once you know basic c#, you'll be able to write most code in Unity fine.
     
  18. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Oh good grief. I was so focused on the red squiggly on line 37, and confused that editor want a } when there was already on there, that I did not even notice line 5's {.

    Question: Do put the } at the end of the bracket that comes after MonoBehaviour or do you mean add a bracket at the end of EVERYTHING by putting it on a newly created line 38? There are 37 lines at the moment.

    -----------------------------------------------------

    I am truly astounded that you picked this stuff up in just 3 months. It must have involved a lot of Red Bull. :p But I have to tell you, after this project, I'm done. I bought Playmaker. There is a reason that the only "C" I got in college was in that Basic language class back in '82.

    I hit your profile's "Follow" button in case I need to get someone to help (for pay) with a future project that exceeds Playmaker's capabilities. IM me if you want to share your contact info with me.

    I'll make the corrections tomorrow after I hear from you as to exactly where to put the }. I want to thank you again for your time, patience, and understanding. :)

    JP
     
    Last edited: Feb 22, 2017
  19. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    At the very end of the script, put a "}". This is so that the class (that's derived from Monobehavior) has all the code inside it. So that would make it line 38.

    Where did I say that? It's actually been more than a bit longer than that, no Red Bull involved. Just an 8 hour playlist of mostly terrible Spotify music to keep me going. German heavy metal makes the debugger work 26% faster :D

    I've been on the forum for almost 2 years and still don't know what the follow button does. It must be important though.

    I've really been into Unity as something just on the side, not professionally (yet). I'm currently working on an interesting project, just too busy IRL. If you need more help, post on the forums. If you want to reach out to me directly for something else, you can send a direct message :)

    Really, you just need to get the hang of the basics. Knowing where to put open/close brackets is just the beginning. Also, C# is used in many applications, not just Unity games. With C# you can make Windows Console programs, Windows Forms, WPF programs, UWP (Universal Windows Platform - Windows 8-10 apps), and even the Windows 10 IOT core for the Raspberry Pi (which I have but don't have the time to play with). And I've listed just some of C#'s applications I'm familiar with. Then there's Java, which is really close to C#, and I've used it a bit in Android Studio. So I'd say do the Roll a Ball tutorial to get a hang of scripting, because it's something really useful once you get your head around the basics.

    I was looking into visual scripting (Unreal has something similar to Playmker built-in called Blueprints), but I thought that I'd spend just as much time learning Unreal's Blueprint system as I could spend learning Unreal's C++, so I've stuck with C# in Unity for now.
     
  20. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Ok, I managed to figure out where the } went. VS was more helpful in that regard than Mono. There are no errors in Unity or VS. The only problem is that it won't move. There are no errors in Unity's console. It just does not move when I hit the up or down key.
     

    Attached Files:

    Last edited: Feb 22, 2017
  21. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Saw your reply after I posted my last response. Have a look at my code and let me know if you see anything obvious that won't allow it to work. If nothing immediately stands out, don't worry about it. You've spent far too long hand-holding me as it is. I'll give it go in Playmaker as well as send the last C# file to the asset creator and see if he sees anything obvious. Maybe something he did is making thing not work. It's a really big asset.

    Thanks again!!!
     
  22. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    My bad. That was Ryeath.
     
  23. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (transform.position.y < 15 && transform.position.y > 0)
    4.         {
    5.             transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);
    6.             return;
    7.         }
    8.  
    9.         else
    10.         {
    11.             if (transform.position.y >= 15)
    12.             {
    13.                 //if it's too high, we need to move it to 15
    14.                 transform.position = new Vector3(transform.position.x, 15, transform.position.z);
    15.                 return;
    16.             }
    17.  
    18.             if (transform.position.y <= 0)
    19.             {
    20.                 //if it's too low, we need to set it to 0
    21.                 transform.position = new Vector3(transform.position.x, 0, transform.position.z);
    22.                 return;
    23.             }
    24.         }
    25.     }
    26. }
    What is your starting transform? If I assume you are starting at (0, 0 , 0) your object will not move because to activate the translation you need to be greater than 0.
    Also if you object does move, once it goes outside of the range it will never move again because your reset is outside of the range.
    Try reading the line out loud to yourself.
    If y is less than or equal to 0, it is too low so set it to 0. tells you that you are setting it too low. I personally wouldn't bother with the equals in the testing portion.
    Don't give up though.
     
    DroidifyDevs likes this.
  24. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Ouch, that was a glaring mistake on my part to reset it to something outside of the range. The 15 should be 14.9 and 0 should be 0.1. Good catch!
     
  25. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Ok, for clarification, do all three lines of code (lines 3, 11, and 18) need to be changed to 14.9 and 0.1? Or, given the context of Wreath's comment, do I only change lines 11 and 18? I'm afraid to experiment on my own in this regard for fear of accidentally creating a new problem. ;-)
     
  26. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    I edited my previous answer.

    Code (CSharp):
    1. void Update()
    2.     {
    3.         if (transform.position.y < 15 && transform.position.y > 0)
    4.         {
    5.             transform.Translate(0, Input.GetAxis("Vertical") * Time.deltaTime, 0);
    6.             return;
    7.         }
    8.  
    9.         else
    10.         {
    11.             if (transform.position.y >= 15)
    12.             {
    13.                 //if it's too high, we need to move it back into the acceptable range
    14.                 transform.position = new Vector3(transform.position.x, 14.9f, transform.position.z);
    15.                 return;
    16.             }
    17.  
    18.             if (transform.position.y <= 0)
    19.             {
    20.                 //if it's too low, we need to move it back into the acceptable range
    21.                 transform.position = new Vector3(transform.position.x, 0.1f, transform.position.z);
    22.                 return;
    23.             }
    24.         }
    25.     }
    I'm afraid you aren't understanding the logic here. Here's what's going on:

    If the Y position is LESS THAN 15 AND GREATER THAN 0, move it. return; means that the function will not be executed past that word, so we save some performance by not having to check things after that line.

    If it is NOT in the range, check if its Y position is GREATER THAN OR EQUAL TO 15. If it is, move it to slightly less than 15 so it fits in the range of the first function (between 0 and 15). return; means that the function will not be executed past that word, so we save some performance by not having to check things after that line.

    Check if its Y position is LESS THAN OR EQUAL TO 0. If it is, move it to slightly more than 0 so it fits in the range of the first function (between 0 and 15). return; means that the function will not be executed past that word, so we save some performance by not having to check things after that line.

    That's the logic of the code, sometimes speaking it out in human language is easier to understand for beginners.
     
    Ryeath likes this.
  27. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    jpine,

    The lines that need to be edited are 14 & 21 so the reset is within the range.

    DroidifyDevs,

    I was wondering about the Return; statement. I was thinking there was no use of putting it in there, but you saying using will save performance. It makes sense as long as there are no other statements past the IF / Elses.

    Pure genius. I have so much to learn.
     
    Last edited: Feb 22, 2017
    jpine likes this.
  28. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    That goes without saying. :confused: Thanks for the save!
     
  29. jpine

    jpine

    Joined:
    Feb 8, 2015
    Posts:
    26
    Like I said before, coding is so much more of a natural endeavor for some than it is for others. After this project, I'm putting my time into learning Playmaker which, at least in the first few tutorials I've gone through, makes infinitely more sense to me. If I get into a position where something is beyond Playmaker's capability, I'll hire the solution out rather than putting people like you and Droidify through days of hand-holding some like me over what is probably a simple problem. I don't think I have the ability to profit from the experience, thus it is not fair to the people trying to help me.
     
  30. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Actually, there's a lot I have to learn in C# too :D

    It's really micro-optimization, and the return on line 22 is redundant. Basically, in theory it is faster to do if (transform.position.y >= 15) and then use return, since without return it would also check if it's Y position is <= 0, which is unnecessary since we already know it's >= 15. In real life, the performance gain is negligible, but since it's in the Update function I added it in there anyways.

    Don't give up! It's easier than you think, there's just some basic concepts you need to learn. Like trigonometry you have to do in high school, it's hard, but learnable since you learn gradually from the beginning.
     
  31. Ryeath

    Ryeath

    Joined:
    Dec 4, 2016
    Posts:
    265
    Not to lend anymore confusion to jpine, and getting a bit off topic, but I find this kind of stuff interesting. Technically we wouldn't even need the third if statement. There are only three states, in range, above range, under range and only one can be true at any given time. Once the first two have been proven false the third must be true by default. so to paraphrase.

    If (in range)
    Move object
    return
    else if (above range)
    Reset at upper range limit
    return
    else reset at lower range limit
     
    DroidifyDevs likes this.