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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Void Functions and Parameters

Discussion in 'Scripting' started by Shadowsurge, Jan 26, 2016.

  1. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    Typically I'd create a function type to return something, such as an int function to return an int etc but I was wondering, since I've never actually looked into it or done it, is it a good/decent idea to just pass a variable into a void function and have it manipulated from there?

    I know it's probably a basic thing, but I feel like the basic things are the things I forget quickest

    Let's say I have this in my controller

    Code (csharp):
    1.  
    2. if (Input.GetKeyDown(KeyCode.UpArrow))
    3.         {
    4.             model.min = model.guess;
    5.             model.guess = (model.max + model.min) / 2;
    6.  
    7.             view.setNewText("Higher or lower than " + model.guess);
    8.         }
    9.  
    and this in my view

    Code (csharp):
    1.  
    2.  
    3.   public void setNewText(string text)
    4.     {
    5.         print (text);
    6.     }
    7.  
    8.  
    Is there a better way I should be passing data like this, or is it acceptable?
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    ... using parameters is ok, even if the function doesn't return anything...

    think I'm missing the question though :confused:
     
  3. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    Nah you're not, that's perfect.

    I was just making sure there wasn't any awkward ways I should be doing it. After programming in C++ I've gotten into the mindset that if something is too simple, and works that way, it's probably wrong xD Thanks though
     
  4. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Yeah that works well enough. Though from our talk before I am wondering why the model and the view are being accessed in the same class :p.

    Really the setNewText is a bit of a confusing one. Because you need to ask yourself whether that is something the view should automatically display, or whether this is an event that needs to be passed to the controller to be handled. In this instance I'd probably pass this to the controller, like so:

    Code (CSharp):
    1.     private Model model = new Model();
    2.     private View view = new View();
    3.  
    4.     public class Controller : MonoBehaviour
    5.     {
    6.         public void SetNewTextAction(string text)
    7.         {
    8.             print("Higher or lower than " + text);
    9.         }
    10.     }
    11.  
    12.     public class Model : MonoBehaviour
    13.     {
    14.         float min = 0, max = 10;
    15.  
    16.         public float GetModelGuess()
    17.         {
    18.             return ((min + max) / 2);
    19.         }
    20.     }
    21.  
    22.     public class View : MonoBehaviour
    23.     {
    24.         private Model model;
    25.         private Controller controller;
    26.  
    27.         void Start()
    28.         {
    29.             controller = GetComponent<Controller>();
    30.             model = GetComponent<Model>();
    31.         }
    32.  
    33.         void Update()
    34.         {
    35.             if (Input.GetKeyDown(KeyCode.UpArrow))
    36.             {
    37.                 controller.SetNewTextAction(model.GetModelGuess().ToString());
    38.             }
    39.         }
    40.     }
    Remember the model only holds the data, and makes it ready to be modified by the controller, and accessed by the view. The view is only able to grab information from the model to display it, or pass any events called by the outside, to the controller (like a key press). I hope that makes sense.
     
  5. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    are model and controller meant to be monobehaviours in that snippet?
     
  6. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Either really. It's just an example of an MVC..
     
  7. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    @Nigey

    I had my controller handling the key presses that's why :p This is just a really basic number guessing game I'm working through to get the idea of what we spoke about yesterday. Starting small and working my way up.

    Here's the way I had done it until now, first attempt and it seems to work well enough so I'm not too far off the general idea I think.

    Model
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class NumberWizardModel : MonoBehaviour
    7. {
    8.     public int max = 1000;
    9.     public int min = 1;
    10.     public int guess = 500;
    11. }
    12.  
    13.  
    View
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class NumberWizardView : MonoBehaviour
    6. {
    7.     public NumberWizardModel model;
    8.  
    9.     // Use this for initialization
    10.     void Start ()
    11.     {
    12.  
    13.     }
    14.  
    15.     public void StartGame()
    16.     {
    17.         model = FindObjectOfType<NumberWizardModel>();
    18.  
    19.         print("========================================================");
    20.         print("Welcome to Number Wizard");
    21.         print("Pick a number in your head, but don't tell me!");
    22.  
    23.         print("The highest number you can pick is " + model.max);
    24.         print("The lowest number you can pick is " + model.min);
    25.  
    26.         print("Is the number higher or lower than " + model.guess + "?");
    27.         print("Up = higher, DOWN = lower, RETURN = equal");
    28.     }
    29.  
    30.     public void setNewText(string text)
    31.     {
    32.         print (text);
    33.     }
    34.  
    35.     // Update is called once per frame
    36.     void Update ()
    37.     {
    38.  
    39.     }
    40. }
    41.  
    Controller
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class NumberWizardController : MonoBehaviour
    7. {
    8.     public NumberWizardModel model;
    9.     public NumberWizardView view;
    10.  
    11.     // Use this for initialization
    12.     void Start ()
    13.     {
    14.         view = FindObjectOfType<NumberWizardView>();
    15.         model = FindObjectOfType<NumberWizardModel>();
    16.  
    17.         view.StartGame();
    18.         model.max = model.max + 1;
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update ()
    23.     {
    24.         if (Input.GetKeyDown(KeyCode.UpArrow))
    25.         {
    26.             model.min = model.guess;
    27.             NextGuess();
    28.         }
    29.         else if (Input.GetKeyDown(KeyCode.DownArrow))
    30.         {
    31.             model.max = model.guess;
    32.             NextGuess();
    33.         }
    34.         else if (Input.GetKeyDown(KeyCode.Return))
    35.         {
    36.             view.setNewText("I won!");
    37.             ResetGame();
    38.             view.StartGame();
    39.         }
    40.  
    41.     }
    42.  
    43.     void NextGuess()
    44.     {
    45.         model.guess = (model.max + model.min) / 2;
    46.  
    47.         view.setNewText("Higher or lower than " + model.guess +
    48.                         "\nUp = higher, DOWN = lower, RETURN = equal");
    49.     }
    50.  
    51.     void ResetGame()
    52.     {
    53.         model.max = 1000;
    54.         model.min = 1;
    55.         model.guess = 500;
    56.     }
    57. }
    58.  
    EDIT:

    Just realized I have my instances set to public when I don't think they have to be, aside from that I thought it went well. Although you have

    private Model model = new Model();

    whereas I have

    public NumberWizardModel model;

    Any real difference, aside from the public and private thing I just mentioned
     
  8. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
    Remember that some values are passed by reference, others by value. Thus there are differences on how to handle these values.

    Have a look at MSDN:
    https://msdn.microsoft.com/en-us/library/9t0za5es.aspx

    Not the best example but should give you an idea of what's happening.
     
  9. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    shouldn't be using "new" and monos was the point :p :)
     
    Nigey likes this.
  10. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Touche Lefty, touche lol :p.

    Lol I see, I see. As you're making an example of the MVC pattern. I'd consider making a method in the Model class that has something along the lines of EditMax(int amt){ max += amt; }. Simply so the controller isn't actually changing the values itself, but is passing requests for the data to be changed on the model. Otherwise what's the point in it, you know? It's a simple example now, but when you get to larger examples, you'll notice the difference :).
     
  11. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    Didn't you say the Controller should handle changing the Model data?

    You said before the controller should update the models data, which is what I have my controller doing. It's taking in the key presses, setting the models data to new values, which are then being read again and sent to the view.
     
  12. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Aaah I see. There was a little confusion there then, my bad!

    Yes the controller does request data to be changed on the model, but normally the model handles it's own changes. If ever needed, the model can let the controller know when that done (though that would be mainly for more complex tasks like saving data). So the controller would request a change in data on the model, the model would then make that change on it's own data. To encapsulate the three classes cleanly. Does that make sense?

    It's almost exactly what I was saying. The only minor difference is that the controller is calling a method on the model to change it's data, rather than accessing it's data directly. It's a very subtle difference, but one that becomes more noticeable as the application grows :).
     
  13. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    Yeah I understand you now, sorry to confuse you with all the stuff I asked yesterday!

    Okay, so I updated the code and I think this represents what you're saying slightly better. I have kept the key presses inside the controller, since there isn't any representation of those on the UI (other than the text), I felt like they were a better fit in the controller for now. When I move onto bigger practice projects later today, I'll most likely do it the way you said letting the view handle the button presses on the UI etc and passing events to the controller.

    Model
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class NumberWizardModel : MonoBehaviour
    7. {
    8.     public int max = 1000;
    9.     public int min = 1;
    10.     public int guess = 500;
    11.  
    12.     public void ResetGame()
    13.     {
    14.         max = 1000;
    15.         min = 1;
    16.         guess = 500;
    17.     }
    18.  
    19.     public void UpdateMin()
    20.     {
    21.         min = guess;
    22.     }
    23.  
    24.     public void UpdateMax()
    25.     {
    26.         max = guess;
    27.     }
    28.  
    29.     public void UpdateGuess()
    30.     {
    31.         guess = (max + min) / 2;
    32.     }
    33. }
    34.  
    35.  
    Controller
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class NumberWizardController : MonoBehaviour
    7. {
    8.     private NumberWizardModel model;
    9.     private NumberWizardView view;
    10.  
    11.     // Use this for initialization
    12.     void Start ()
    13.     {
    14.         view = FindObjectOfType<NumberWizardView>();
    15.         model = FindObjectOfType<NumberWizardModel>();
    16.  
    17.         view.StartGame();
    18.     }
    19.    
    20.     // Update is called once per frame
    21.     void Update ()
    22.     {
    23.         if (Input.GetKeyDown(KeyCode.UpArrow))
    24.         {
    25.             model.UpdateMin();
    26.             NextGuess();
    27.         }
    28.         else if (Input.GetKeyDown(KeyCode.DownArrow))
    29.         {
    30.             model.UpdateMax();
    31.             NextGuess();
    32.         }
    33.         else if (Input.GetKeyDown(KeyCode.Return))
    34.         {
    35.             view.setNewText("I won!");
    36.             model.ResetGame();
    37.             view.StartGame();
    38.         }
    39.     }
    40.  
    41.     void NextGuess()
    42.     {
    43.         model.UpdateGuess();
    44.  
    45.         view.setNewText("Higher or lower than " + model.guess +
    46.                         "\nUp = higher, DOWN = lower, RETURN = equal");
    47.     }
    48. }
    49.  
    50.  
    View
    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5.  
    6. public class NumberWizardView : MonoBehaviour
    7. {
    8.     private NumberWizardModel model;
    9.  
    10.     // Use this for initialization
    11.     void Start ()
    12.     {
    13.      
    14.     }
    15.  
    16.     public void StartGame()
    17.     {
    18.         model = FindObjectOfType<NumberWizardModel>();
    19.  
    20.         print("========================================================");
    21.         print("Welcome to Number Wizard");
    22.         print("Pick a number in your head, but don't tell me!");
    23.  
    24.         print("The highest number you can pick is " + model.max);
    25.         print("The lowest number you can pick is " + model.min);
    26.  
    27.         print("Is the number higher or lower than " + model.guess + "?");
    28.         print("Up = higher, DOWN = lower, RETURN = equal");
    29.     }
    30.  
    31.     public void setNewText(string text)
    32.     {
    33.         print (text);
    34.     }
    35.    
    36.     // Update is called once per frame
    37.     void Update ()
    38.     {
    39.    
    40.     }
    41. }
    42.  
    43.  
    It doesn't have to be 100% perfect, it is only for a uni assignment and it's my first time using MVC, but for practice, I think it's laid out fairly well. At least if I know it's on the right tracks, I can continue doing it like this.

    So basically, just to be sure after all the confusion, here's how it should work?

    Model - Blueprint for any objects being created, holds all the variables and maintains/updates those variables when requested to do so by the Controller. Has no knowledge that the View exists.

    Controller - Accepts data from the view, which is passed through via collision detection, triggers etc. Transmits the data to the Model, and handles the general logic flow of the process. This is basically just a 'errand class' for the Model & Controller right? (As in, it's there mainly to pass data from the view to the model, but without them ever coming into contact)

    View - Can read only from the model, and update it's own UI data. Passes any data related to the model directly to the controller instead.
     
  14. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Yeah I think you've got it pretty much on, from what I understand of it anyways. It fits the design pattern as shown here http://www.tutorialspoint.com/design_pattern/mvc_pattern.htm.

    When you say an errand class. There's actually a much simpler way to think about it. The view is literally the view. When you look at someone, you interact with the view you see of that person. The view is the physical representation of the overall entity. Literally, the view. So anything that interacts with the entity in a physical sense WILL be interacting with the view. Represented by the view class. This is then passed to the controller. In keeping with the analogy that the view is the physical representation of someone, the controller would be that someone's brain. The brain changes info on the model. Another way of thinking of this, would be the person's memory. So in short on this metaphorical example:

    The view is the physical representation of a person. You can shake their hand or talk to them.
    The controller is the brain. When the view passes events to the controller. It's the bodies nerve system sending messages to the brain, that something's happened to the body's 'view'. With that, there's reactions, and the memory of that person changes. Either temporarily or permanently. The memory being that person's 'model'.

    The aim of the metaphor is to clean up things a little lol, instead of confuse you more. Either way I think you've pretty much got the gist of it now. Good job!
     
  15. Shadowsurge

    Shadowsurge

    Joined:
    Nov 26, 2015
    Posts:
    34
    Haha nah that makes sense.

    One thing though, what about multiple entities with their own MVC's?

    I was gonna have each entity with it's own set of MVC scripts. What should interact with what?

    For simplicitys sake, say I have an enemy with 3 MVC scripts. A player with 3 MVC scripts and the player shoots the enemy (I'm assuming the weapon/projectile also needs MVC scripts so there's another 3)
     
  16. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    If that was me I'd probably simply create a 'character' MVC. That would have the basic functionality of any generic 'person'. When a person interacts with another person, it'll be through their 'view', or physical representation. So giving two examples: Shaking another person's hand. That could equate to colliders connecting. In which case the view would hold the trigger for the collision event, and then pass that data to the controller, to take actions, and pass any data needed to update the model. The other example would be giving someone else a command. In that example there would be some form of audible receiver. Or some fake that you'd pretend exists. Again, you'd set that up in the view, to pass the event onto the controller..

    Anyways I don't wan't to be your sole access for MVC, as I said, I'm not the master of it lol, but I hope that helps :).