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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Resolved How "return" madness works?

Discussion in 'Scripting' started by Frostysh, Aug 11, 2022.

  1. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    I have a code in the script program from the in-build Unity tutorial, which should prevent the main character from being damaged with a too high rate over damage zone.

    Code (CSharp):
    1. public void ChangeHealth (int amount)
    2.     {
    3.         // Animation increasing health.
    4.         if (amount > 0)
    5.         {
    6.             Instantiate(Consume_Health_Potion, rigidbody2d.position, Quaternion.identity);
    7.         }
    8.        
    9.         if (is_invincible)
    10.             return;
    11.            
    12.         if (amount < 0)
    13.         {
    14.             animator.SetTrigger("Hit");
    15.             Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity);
    16.            
    17.             //if (is_invincible)
    18.                 //return;
    19.  
    20.             is_invincible = true;
    21.             invincible_timer = time_invincible;
    22.         }
    23.         currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
    24.  
    25.         //Making changes into UI-Healthbar.
    26.         UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth);
    27.            
    28.         //Showing health due to debug console.
    29.         //Debug.Log(currentHealth + "/" + maxHealth);
    30.     }
    There is disabled code inside the if (amount < 0) program, which contains return, I have disabled it, because despite it was placed there in tutorial. The problem, is that I thought return is a 'jump' to start function public void ChangeHealth (int amount), but it is not! It seems that return only 'jumping one step above' of the place where it has been executed. And those making my character play animation of being damaged with insane rate.

    How exactly this return is works?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,012
    Have you looked at the C# docs? https://docs.microsoft.com/en-us/do...atements/jump-statements#the-return-statement

    return
    exits the function that's running, either just by terminating the function in the case of methods with a return type of
    void
    or returning a value in the case of methods with an actual return value.

    For example, this method returns the multiplied value of two numbers:
    Code (CSharp):
    1. public int Multiply(int a, int b)
    2. {
    3.     return a * b;
    4. }
    Often methods can be 'guarded' to exit early if they don't need to run, such is the case with the
    if (is_invincible)
    .
     
  3. FootSteps

    FootSteps

    Joined:
    Aug 19, 2014
    Posts:
    12
    The keyword right before the method name is the return type of the method or function. So at some point during that method you need to return something. Return just exits the method, returning to whatever is calling that function and resuming.

    You can return alot of things from a method, but you have to specify what you are returning before the method name. See following 2 examples.

    void - You don't need to return anything, but you can still use the return keyword to exit the function at the location of the statement. Essentially if you don't write return, at the end of the function it will return automatically for you.

    bool - You are required to return true or false. You still can exit at any line in the function. See IsImmune() function below, it has a boolean return type.

    Code (CSharp):
    1.     bool m_isImmune = true;
    2.     int m_health = 10;
    3.     public void ChangeHealth(int amount)
    4.     {
    5.         if (IsImmune() == true)
    6.             return;
    7.         else
    8.             m_health += amount;
    9.     }
    10.     public bool IsImmune()
    11.     {
    12.         return m_isImmune;
    13.     }
    Hope this helps.
     
  4. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    After your post, Mr. Spiney199, I have looked into that information. Me still don't understand. Do you trying to say that if (is_invicible) a function program same as public void ChangeHealth (int amount)?
    And why I need to use special program return if a function returns the results of operation with information inside the function automatically?

    P. S. Somehow in-line code not working, so I just changing the font.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,012
    Sorry, but that is 100% not at all what I said. I have no idea how after two posts explaining how this works you reached the same incorrect conclusion as you already had.

    Take this example:
    Code (CSharp):
    1. pubic class ReturnExample : Monobehaviour
    2. {
    3.     public bool skipBool = true;
    4.  
    5.     private void Start()
    6.     {
    7.         SkipMethod(skipBool);
    8.     }
    9.  
    10.     public void SkipMethod(bool skip)
    11.     {
    12.         if (skip == true)
    13.         {
    14.             //exits the method early
    15.             return;
    16.         }
    17.      
    18.         Debug.Log("We have not left the method early!");
    19.     }
    20. }
    If you put this on a game object and hit play, the Debug.Log will not run. That's because it returned early.

    It can't put it any more clearly than that.
     
    Bunny83 likes this.
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,571
    Based on Spiney's example code I want to make one thing clear. When you call a method you actually enter a sub routine. The return statement actually leaves that sub routine immediately and "returns" to the caller. In the example it means when the
    return;
    statement in line 15 is reached, the method is left immediately and the control goes back to line 8. Line 8 is simply the next line after the call of the method.

    The return keyword in C# has actually a direct relationship to the "ret" (return) opcode that a CPU can execute. This opcode literally does nothing else than popping the return address from the call stack and returning to the point where the method was called.

    In C# / C / C++ and most high level languages the "return" key world is also use to specify the return value if there is any. Though this is completely irrelevant here. The method in question does not have a return value since "void" as return type means "nothing".

    As I was mentioned before, the usage of the return statement in the OP is called a "guard clause" or "early exit". The point is to leave the method based on certain conditions early so the full method does not complete.
     
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    First of all, it does not 'return' the change. It simply calculates and applies it. It returns nothing, ie void, by definition.
    The Multiply function created by spiney above actually returns a value. Effectively this means that you can treat the function call itself like a value of its return type. Which can be used as such:
    Code (CSharp):
    1. int c = Multiply(5,3);
    As for your main question: the function has 3 parts. There is one thing the programmer always wants to check and possibly do first (amount > 0). Afterwards they check if the player is_invincible, and if so they return, meaning they quit the function early. If the player is not invincible the rest of the function will be executed. In this case, the return there is the same as if we encapsulated the rest of the function code in if(!is_invincible).
     
    Last edited: Aug 11, 2022
  8. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    But me have different situation, if use use the above mentioned code, it will be something like that...

    Code (CSharp):
    1. pubic class ReturnExample : Monobehaviour
    2. {
    3.     public bool skipBool = true;
    4.  
    5.     private void Start()
    6.     {
    7.         SkipMethod(skipBool);
    8.     }
    9.  
    10.     public void SkipMethod(bool skip)
    11.     {
    12.         if (skip != true)
    13.         {
    14.             if (skip == true)
    15.             {
    16.                 //exits the method early
    17.                 return;
    18.             }
    19.  
    20.         Debug.Log("We have not left the method early!");
    21.         }
    22.     }
    23. }

    And somehow my character still recieve a proper damage on the damage zone, but animation (which is on the same place as you Debug.Log() Mr. Spiney199), this is means that return working crazy, and stopping if (skip == true), but not stopping public void SkipMethod (bool skip).
    Why it is not return to line number 12 then? And when I use if () {if;}, its actually return only to first if.
    That is the problem of mineself, I don't understand what this crazy blackbox (electronic computation machina, A. K. A. computer) doing, I thought when I decided to make a video-game to read something about electronix first, but unfortunately in my case the process will take an eternity, and me need financial resource.
    This is screenshot from the in-build Unity tutorial, official one.



    World Interactions - Damage Zones and Enemies - Unity Learn

    And if we left return program on its place — character will start to 'jamming' on the damage zone in the next tutorial. Because it is a wrong place for such program! Is this a kind of idiotic joke? Or two part of tutorial has been made by different humans without pedagogical connection between them?
    This is next part of tutorial, which in combination in previous one, breaking the gameplay over damage zones.



    Sprite Animation - Unity Learn

    The animator.SetTrigger("Hit") cannot be disabled by return, and Debug.Log() working too.
     
    Last edited: Aug 11, 2022
  9. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,353
    You have some fundamental misunderstandings of how C# works. You are following tutorials without understanding what you are writing. A good exercise i recommend is to use comments for every line and explain what is going on.

    For example, if you understood what you typed here, you would know it is not good:

    Code (CSharp):
    1. public void SkipMethod(bool skip)
    2.     {
    3.         if (skip != true)
    4.         {
    5.             if (skip == true)
    6.             {
    7.                 //exits the method early
    8.                 return;
    9.             }
    10.         Debug.Log("We have not left the method early!");
    11.         }
    12.     }
    you're saying, if Skip is not true, then you are checking if skip is true...which will never reach the Return because of the first if block. The first if block is stopping you from reaching the second, thus return will not be called and the Debug.Log will call if skip is not true.

    Maybe you just need to start watching some different tutorials as well. Not all youtube tutorials are created equal.
     
    Bunny83 likes this.
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,571
    Because the return statement is only relevant for methods. When you use the return statement you are leaving the method you're currently in. An if statement is not a method. A method is a seperate subroutine. In your case you created a method named "SkipMethod". You call this method inside the Start method. When you call a method the execution jumps to the start of the method and executest one instruction at a time, one by one towards the end. There are no loops inside your code, so it could never possibly jump back up. An if statement is just a conditional statement. so the code inside the curly braces is only executed when the condition in the brackets of the if statement is true. If the condition if false, the body of the if statement (the code inside the curly braces) is skipped and the method continues after the closing curly brace.

    Like others have said you really need to learn the absolute basics first. A computer language is another language like english, spanish, chinese or klingon. Languages are used to express "ideas" and they have certain syntax rules and vocabulary you have to learn in order to use and understand this language. Unlike human languages, programming languages are directed towards computers. So the purpose of these languages are very specialized and limited. They have way less vocabulary but usually more syntax rules. You can't expect to write russian poetry if you can't speak russian and you're not a poet either. The fact that you have literally zero knowledge about how computers work means you have to learn two things at once: programming in general (which includes formal logic and general programming concepts) as well as the language C#. With zero background this is going to be a very difficult to pull that off on your own. We can't teach you everything from ground up here. The fundamental concept of a method / function is pretty much the same in all programming languages. If you have a background in maths, the concept of a function in programming is pretty similar to the concept of a function in math.
     
    Kurt-Dekker likes this.
  11. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    It is not relevant, what is important is that return not working properly in some construction, or maybe I something lost in the process of understanding. Lets start from the code (proposed in tutorial).

    Code (CSharp):
    1.     public void ChangeHealth (int amount)
    2.     {
    3.         // Animation increasing health.
    4.         if (amount > 0)
    5.         {
    6.             Instantiate(Consume_Health_Potion, rigidbody2d.position, Quaternion.identity);
    7.         }
    8.    
    9.         //if (is_invincible)
    10.             //return;
    11.        
    12.         if (amount < 0)
    13.         {
    14.             animator.SetTrigger("Hit");
    15.             Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity);
    16.        
    17.             if (is_invincible)
    18.                 return;
    19.  
    20.             is_invincible = true;
    21.             invincible_timer = time_invincible;
    22.         }
    23.         currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
    24.  
    25.         //Making changes into UI-Healthbar.
    26.         UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth);
    27.        
    28.         //Showing health due to debug console.
    29.         //Debug.Log(currentHealth + "/" + maxHealth);
    30.     }

    The results...



    The non-stop running of next code, due to return program failing to do its work.

    Code (CSharp):
    1.             animator.SetTrigger("Hit");
    2.             Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity);
    It is creating insane amount of animations Get_Hit cycle-spawning, but the health is properly decreasing, because the next code is under return program take of control.

    Code (CSharp):
    1.             is_invincible = true;
    2.             invincible_timer = time_invincible;
    3.         }
    4.         currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
    5.  
    6.         //Making changes into UI-Healthbar.
    7.         UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth);

    The code (with my edit)...

    Code (CSharp):
    1. public void ChangeHealth (int amount)
    2.     {
    3.         // Animation increasing health.
    4.         if (amount > 0)
    5.         {
    6.             Instantiate(Consume_Health_Potion, rigidbody2d.position, Quaternion.identity);
    7.         }
    8.    
    9.         if (is_invincible)
    10.             return;
    11.        
    12.         if (amount < 0)
    13.         {
    14.             animator.SetTrigger("Hit");
    15.             Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity);
    16.        
    17.             //if (is_invincible)
    18.                 //return;
    19.  
    20.             is_invincible = true;
    21.             invincible_timer = time_invincible;
    22.         }
    23.         currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
    24.  
    25.         //Making changes into UI-Healthbar.
    26.         UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth);
    27.        
    28.         //Showing health due to debug console.
    29.         //Debug.Log(currentHealth + "/" + maxHealth);
    30.     }

    All work as it planned.



    It was technically not a Youtube-tutorial, but official, Unity in-build tutorial, what I have mentioned in the beginning.
    Then construction if () {if return;} is method too, or me totally misunderstanding because I have no idea why program above in the post, has such habits and make spawn insane amount of cycle-animation things.
    Obviously learning some foolish program language is very good thing! And me thought to do this, but unfortuanutely me now learning: drawing, Unity. To create a video-game, and to learn in addition a program language I have no time, no power, no temptation. Me living in the village, so almost full day me outside the house.
    It is probably a total nonsense statement.
    It is rather a mechanism, than a language, but okay.
    I know, I know...
    Me have a poor background in mathematics (I think it is what you mean under 'math', Mr. Bunny83), but I think function in computer program language is not like function in mathematics. Of course I can be wrong.
     
    Last edited: Aug 11, 2022
  12. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,353
    Stop using Unity's built in tutorials and use good ones from the rest of the internet. They have been pretty broken for a long time now and usually only work in a specific version. Also, the return is not "failing to do its work", you just arent writing the code properly, it is a lack of understanding. I am happy to provide some YT channels with a type of game you are looking to make. I highly recommend avoiding the Unity created ones.
     
  13. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    Well, the in-build Unity tutorials obviously is made by humans without any pedagogical education, but they trying to make not like lecture, but more interactive, in-build tutorial has exercises, has reward points... It was a very good idea, and me follow it.
    I don't think I made a mistake, more likely construction function () {if {if return;} } is something that I don't understand to which point return must execute the jump in this case. The crucial point, return program in this case is inside of if () {} cycle.

    The type of game that your humble servant want to create to obtain financial resources is an interactive eroge visual novel with RPG elements. But don't think me is low morale, actually, I have a very strict morale standards which is close to religious zealot kind of standards, despite me an atheist. For an example, I am not watching real-video pornography, with thought that such things making me closer to the 'swamp' of pornography industry.
    Why eroge? Because I think humans in capitalistic world will buy it, at least I hope that my prediction will be truth.
     
  14. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    This was the funniest paragraph I have ever read on this forum; thank you for that wildly unnecessary amount of information! The genre of game doesn't have anything at all to do with understanding how a return statement works, but I'm glad you're living your best life.

    As far as tutorials, Brackeys is the tutorial creator I hear most for beginner tutorials (can't vouch personally as I learned long before Brackeys was around), and they have a C# playlist - that will probably be your best bet to make sure you have an understanding of all the basics.
     
  15. digiholic

    digiholic

    Joined:
    Nov 23, 2013
    Posts:
    14
    The code is running fine. The difference is, in the tutorial, there isn't an Instantiate before the return. In yours, there is. Code runs top to bottom, one singular line at a time. When it hits a return, it exits the function. That is all. Everything before the return is utterly unaffected.

    The second one. This is not a method, not even slightly. Return does not exit an if statement. It exits a method.
     
    Frostysh likes this.
  16. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    I think plenty of people already stated that there is nothing wrong with how return works.

    At the topic of recommending beginner video tutorials, i usually recommend Sebastian Lagues Unity + C# Gamedev series. You said you liked the way the Unity tutorials have little exercises for you: he does it the same way. From what i can tell from his other videos (he has a lot of interresting videos on more advanced topics aswell) he is pretty darn good at explaining stuff. The first few episodes i looked into seemed very well made as a general software development and Unity beginner intro.
    Just dont get lazy: type the code yourself and do the exercises, and you'll be fine.
     
  17. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,127
    If I may, I'll give you a tool that will help you, if properly wielded, to resolve any similar problems in the future.

    It's this: "Listen as if you are wrong".

    Now listen to what people are saying to you:

    The return statement is not some magical weird thing. It's working just fine for billions (yes billions) of times every second in millions of programs around the world. The likelihood of you having found the one odd case where it misbehaves is miniscule.

    Now what do you think is more likely:

    A) You having not enough knowledge or understanding of how it works and thus it looks "weird" to you but it's totally logical for everyone else.

    or

    B) The return statement implementation is so very faulty that even the simplest program causes weird errors and the world will most likely end tomorrow.

    Btw.: You are not alone with this problem in these forums. Quite often people come in here and claim that a Unity function XYZ does not work. Their primary assumption is "it's not MY fault". Usually the reason is either a lack of understanding or (sadly) some not-so-great documentation from unity. Yes, bugs happen too but almost never with something as fundamental as a return statement.
     
    Last edited: Aug 12, 2022
    Kurt-Dekker likes this.
  18. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    I knew that answer to "what type of the game you making" will be off-topic, so me reduced an answer to few sentences which me considered as important sentences.
    Actually, it is a purpose of Unity made by a lot of humans, a large corporation made it to make those curve 'from return to game develop' shorter for newbie game developers, or your humble servant is wrong? I have noted those tutorial, me will try to watch few videos.
    It is a reasonable answer. And probably the cause of such misunderstanding is me didn't know that code launching from top to bottom (an idiotic, but nevermind, probably its making programming easier and understandable for programmers).
    Anyway, I still can't understand why animator.SetTrigger("Hit") is unaffected by is_invincible = true, and currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth) is affected by those parameter? It seems like in "if" cycle if (amount < 0) {code_1 if () return; code_2}, anything before return has separately launching with anything after, not like a single construction, but like two different, not connected functions.
    One things is a theory, and more important, it is hard to me check if advisers understand the case, the other things is actually how this theory is connected to my problem... I will try to watch proposed by you, Mr. Yoreki, video, I think it will not make my situation worse in terms of understanding how to make a video-game.
    I have not called it as an error, I have asked how return program is works in my particular case.
    And what a purpose of this forum then, on your opinion Mr. Geo? I think one of answers is to explain for above mention humans truth.
     
  19. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,012
    It has been explained ad nauseum. And every step of the way you seem to have either ignored this advice or argued with it.

    Some of the people you're arguing here are industry professionals too (not me, mind you). Not only should you be listening and absorbing it, you should be goddam bloody grateful you're getting it for free.

    Instead you're just rambling on and making a complete ass of yourself, frankly.
     
  20. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    In general and, only one things that has a clear connection in explanation in my particular case, is that code launching from top to bottom, and those can make some interesting results with using of return program.
    I am very grateful, Mr. Spiney1999, as you may see, me is humble and mannered person.
    Nonsense.

    P. S. I have watch some videos from 'Brackays' — no thank you. The videos from Sebastian Lagues is little bit better, but he has it scattered and not organized, hard to find somethings. Anyway, now I have minimal understanding with what idea in mind the classes and functions has been created in programming languages.
     
    Last edited: Aug 12, 2022
  21. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,127
    I understand that from the perspective of someone not familiar with coding it might look like "return" does something different based on the context. However that's not the case.

    I think (and I don't mean this in a condescending way) that probably two things are blocking you from understanding what people are trying to explain to you.

    A) Maybe it's the language barrier. I really think that getting your hands on "learn to program" book in your native tongue might be the best way to resolve your problem of understanding what your script does.

    B) You simply lack the programming knowledge to understand what people are saying.

    Again, I mean well but you are getting ahead of yourself. Make a step back and learn the basics.

    The purpose of this forum is subjective as there is no definition. For me it's to facilitate learning. And I guess that's the goal of many here. We are not your "guide me through my project from zero to 100" crowd. It is generally expected that you put in some effort yourself first and then, if you are stuck, come back. The effort required from you now is to actually sit down and learn the basics.

    If you don't want to learn to program then that's fine too. There are plenty of visual scripting tools available.

    Good Luck !
     
  22. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    I have asked and why this construction function () {code_1 if () {if () return;} code_2} starting to execute code_1 totally separate from code_2 if condition of return-cycle is achieved (see above in code-quotes), I have put an effort to make screenshots and spent time to change and check options, and only reasonable answer that I saw — "The code executing from top of the line-script to the bottom!" — indeed, the reason seems right there, but more detailed explanation was expected. o_O
    Is this looks that I want to somebody study me programming on C# from newbie to professional? Is this a kind of joke, Mr. Geo?
     
  23. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,012
    We're telling you to go learn code proper as you keep objecting to our explanations or coming back with the complete wrong understanding.

    I honestly don't know how this post escalated to this point from my initial response. The first two responses answered your question in its entirety.

    Sorry but you don't even seem to grasp the basics of how code executes. How the hell else would code execute if not top to bottom?

    We're not telling you to learn to become a C# professional; that was never insinuated in the slightest. We're telling you to learn the absolute bare minimum of how C# operates.

    If that's too much then you're either stubborn, stupid, or both.
     
    Last edited: Aug 12, 2022
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,620
    This thread is going around in circles, possibly made worse by a small language barrier (no pun intended). Another problem I'm seeing is trying to understand how to make games and understand logic without first fundamentally understanding programming basics that apply to most languages. Not professional anything, simply the basics. Stuff to learn, away from a forum.

    What you're asking about is called "control flow" (use this to search online) and is common to most computer languages. It's not exclusive to Unity nor C#, it's lots and lots of languages. You should try to understand this concept, it'll serve you well and questions like the above will click into place. :) Maybe watch some YouTube stuff on it to better understand: https://www.youtube.com/results?search_query=control+flow

    You want a simple answer to a specific question but you don't seem to have the core knowledge to understand the answer and this is the problem or at least this is how you're coming across. Sorry if this isn't actually the case.
     
    Ryiah, Bunny83 and Yoreki like this.
  25. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    Well, okay, I will change 'tag' to "Resolved", my example is in detail explained in the post №11 of this thread, and only answer, that on my humble opinion somehow connected to the very example has been done by Mr. Digiholic in post №15 because indeed, again on my opinion, such weird habit of return because so-called compiler is move from top to the bottom of the script, but still, the more detail explanation of that 'glitch' is still enigma to myself. I will note this example somehow.
    Anyway, I have successfully finished this tutorial: Ruby's Adventure: 2D Beginner - Unity Learn, and now me will continue other tutorials from that series, and I hope your humble servant will be able to finish that too.

    My gratitude for anyone who answered in the topic!
     
    MelvMay, Yoreki and Cornysam like this.
  26. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    I just saw you resolved the thread, but as i was already writing this ill still post it.

    "Code executed top to bottom" is really all that's relevant here. But "top to bottom" might be a bit irritating. "Sequentially" is a better word, since the compiler can jump through the code. For any jump-free code segment "top to bottom" is accurate however. If-statements, function calls, return statements and some other language elements are simply jumping to a different location in the code.

    Code (CSharp):
    1. # .. possibly more code..
    2. int i = 0;
    3. CheckSomething(true);
    4. float pi = 3.1415f;
    5. # .. possibly more code..
    6.  
    7. public void CheckSomething(bool condition){
    8.     # (A) some code
    9.     if (condition){
    10.         return;
    11.     }
    12.     # (B) some more code
    13. }
    In the above example, the compiler would start executing the code at line 1 and will sequentially work its way through it. Meaning it will declare and assign a value to the variable i in line 2. Afterwards it reads the function call in line 3. The compiler remembers this line as the return address. He continues execution at line 7 and executes some code (A) in line 8. Now the compiler encounters a condition. If this condition was not met, it would skip the scope of the if-statement and continue at line 11 to execute the (B) code part of the function. In the above example the condition is true however, meaning the compiler continues through the scope of the if-statement, which specifically makes it execute line 10. Line 10 is the return statement. The compiler thus now returns to the remembered return address of 3 and continues executing code at line 4. Note how the code execution will never make it to the part of the function below the return statement, unless we skipped it by passing condition=false. This seems to have confused you in previous posts, but part (A) will always be executed when the function is called, but part (B) relies on the return statement not being hit early.

    Above i tried to keep it simple by working with line numbers. In reality we would be talking about memory addresses, but for the sake of this explanation it's pretty much the same. Also note how if we passed condition=false it would naturally reach the end of the function. Non-void functions must return a value on all possible paths, but for void functions you can imagine a hidden return statement at the bottom of the function. So if the compiler reached the end of code section (B) it would also jump back to line 3 and continue at 4.

    Maybe this helps clear up some misunderstandings you might have about how code is executed. Inside Unity you usually work with the Start() and Update() methods, which are handled by Unity. However, Units itself is also a program that is executed sequentially, and these functions just serve to give you nice entry points to insert your own code into the lifecycle of Unity objects. I only added this part since it might be confusing that Unity appears to start code execution at these "arbitrary" points, if we so far claimed it's all "top to bottom" or "sequentially" - however that still holds true, and Unity itself simply calls these functions to execute your own code in a larger sequential program.
     
    Frostysh and MelvMay like this.
  27. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    Yes it was! I was confused and thought about 'glitch' that launching code (A) and code (B) simultaneously, but it is false, me mistaken. Very good Mr. Yoreki! If your post is a truth, then I think I can see the mechanism that created insane infinite loop through the mist of which surrounds it! Now we can, based on your post, explain what happens in detail...

    First lets look on the so-called if-condition cycle of return program (the full script in the first post).

    Code (CSharp):
    1.          if (is_invincible)
    2.                 return;
    Code (CSharp):
    1.  void Update()
    2.     {
    3.         if (is_invincible)
    4.         {
    5.             invincible_timer -= Time.deltaTime;
    6.             if (invincible_timer < 0)
    7.                 is_invincible = false;
    8.         }

    This condition is only true when invicible_timer > 0 or equal to zero. The Time.deltaTime is a constant too (I think), and -= is means to decrease on particular amount. The void Update () function is called every frame.
    So the code (A) is executing until timer is equal or larger than zero (and smaller of some constant).

    Code (CSharp):
    1.  
    2.     public void ChangeHealth (int amount)
    3.     {
    4.         // Animation increasing health.
    5.         if (amount > 0)
    6.         {
    7.             Instantiate(Consume_Health_Potion, rigidbody2d.position, Quaternion.identity);
    8.         }
    9.    
    10.         //if (is_invincible)
    11.             //return;
    12.        
    13.         if (amount < 0)
    14.         {
    15.             animator.SetTrigger("Hit"); //Code (A).
    16.             Instantiate(Get_Hit, rigidbody2d.position + Vector2.up*1.0f, Quaternion.identity); //Code (A).
    17.             PlaySound (Get_Hit_Audio); //Code (A).
    18.        
    19.             if (is_invincible)
    20.                 return;
    21.  
    22.             is_invincible = true; //Code (B).
    23.             invincible_timer = time_invincible; //Code (B).
    24.         }
    25.         currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth); //Code (B).
    26.  
    27.         //Making changes into UI-Healthbar.
    28.         UI_Health_Bar.instance.SetValue(currentHealth / (float)maxHealth); //Code (B).
    29.        
    30.         //Showing health due to debug console.
    31.         //Debug.Log(currentHealth + "/" + maxHealth);
    32.     }

    Then, one single moment, when invincible_timer is smaller than zero, then is_invincible is false and so code (B) is executed, and those it make looks like hitpoints (currentHealth) is decreasing properly! This was moment, until I have read a post of Mr. Yoreki, this was moment of my confusion.
    And this is mechanism of insane loop that will be started if we follow the above mentioned tutorial, eureka! This return program is demanding of some understanding how C# machine works. Good that I have placed limit on how many Get_Hit can be created, because in the opposite case my electronic calculation machine (A. K. A. American computer lol), can freeze instantly...
     
    Last edited: Aug 12, 2022
  28. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    Update() is called by Unity once per frame, yes.
    Time.deltaTime is not a constant. It is, as the name implies, the time difference (a delta) to the last frame. This is a very important value. If you, for example, want to move an object with 100 meters a second, you need to know how much time passed since the last time you moved it. If you moved it at a constant amount per frame, the gameplay would not be framerate independant, as can oftentimes be seen in older games.
    This is a simplification, but just as an example: if you had a constant 60 FPS, Time.deltaTime = 1/60 = ~ 0.0166. So we would multiply our value of 100 with the deltaTime to move, over the duration of one second, exactly 100 units.
    You will encounter this type of calculation very often in the future.

    Your summary of the code is basically correct tho, as is_invincible is true when invincible_timer >= 0.

    Since im not sure if this is a language barrier thing, let me make sure we are on the same page. You wrote "executed until", which would apply it not being executed afterwards. Part A however is always getting executed (assuming we enter the amount < 0 if statement), part B is then only executed if the player is not currently invincible - yes.
    Basically when you get hit, you always want to play the corresponding animation and play the sound. But you only want to subtract HP if you are not currently invincible. It is worth noting that in this particular example, when we say invincible we are talking about the short term invincibility used by many games to prevent too many instances of damage hitting you in a very short amount of time, so one hit makes you invincible for usually a fraction of a second.

    So it's not exactly "one single moment when insincible_timer is smaller than zero". Remember that this function is only supposed to be called when your HP changes, which can happen at varying intervals. If you are invincible for 0.5s after every hit that hits you, then when an attack hits you once every 10 seconds, the invincibility mechanic plays no role whatsoever, and every hit will properly remove health and display the change. But if you get attacked more often than 2x per second, it would start to ignore some of those hits because they arrive during your invincibility - and if the player is invincible you do not want to remove health (or display that).

    Anyways, im glad if my last posted helped you understand the return statement better! I can only recommend following along with some of the tutorial series recommened here to build a knowledge foundation for yourself :)
     
    Frostysh likes this.
  29. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Perhaps the man is making an eroge game, but you can't deny he has a good taste!
    Mr. Yaroslav, thanks for a good laugh. I understand it's hard to learn all of this over night, and yes there is a lot to take in before you can do whatever you want. Even after a decade (plus) of constant work with Unity I am still sometimes struggling with some of its aspects. It is both powerful and immensely frustrating. Anyway, just wanted to say keep it up, maybe you're making the best eroge game in the (American) market!
     
    Nad_B likes this.
  30. Frostysh

    Frostysh

    Joined:
    Jul 11, 2022
    Posts:
    66
    Interesting, too complicated, but interesting.
    As we can see, this 'deltaTime' is not constant, because FPS is not constant? Obviously, if we multiply the time of single frame as a fraction of one second (normalized I think it is called) to draw to how many meters some object will go for this second, we defacto will divide speed of object [m]/[sec] over speed of framerate [f]/[sec], and obviously, after this operation we will obtain [m]/[f] coefficient. This coefficient is a speed over a single frame which object must hold to, as you right said, Mr. Yoreki, to make 100 m / sec frame independent over 60 FPS.
    Yes it is. Ate least I understand it in this way, but initial tutorial was wrong about where to place if (is_invincible) return; program.
    Yes, in this way me understand a situation, the reason of this is a sequence to launch code is mostly top to bottom, and return making jump and returning control to start of function ChangeHealth() obviously, avoiding executing part B when condition accomplished.
    Initial plan was not to play animation of get hit when invincible main character is. Because its creating an insane loop over damage zones with every frame making amount < 0 as we can see.
    I understood it in this way, because is_invincible = true and invincible_timer = time_invincible is located in the part (B) of the code, after getting hit, the timer preventing from get hit again for main character for some time. Indeed!
    But I am not, and it is obviously, at least for now — because me is currently trying to finish interactive, in-build Unity tutorials to make mineself more familiar with the above mentioned computer program abilities and settings.
    The laugh is not worst emotion in the world, am I right?
    Unfortunately me have not such a large period of time in my disposition to use.
    I hope my future eroge-video-game will be popular not only in americanoes market but all around capitalistic world. Me actually no need to create something 'super-profit', as Americans saying, few thousands financial dollars per year is actually enough to mineself.