Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Why does not this keep the loop?

Discussion in 'Scripting' started by michellynitecki, May 18, 2019.

  1. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    Why does not this keep the loop? the two pieces of information are being called at the same time. when moving to index 1

    Code (CSharp):
    1.     public ScriptName Script;
    2.     public int index = 0;
    3.     public Button _Previousobj, _Nextobj;
    4.  
    5.     private void Start()
    6.     {
    7.         pad();
    8.     }
    9.  
    10.     public void previous()
    11.     {
    12.         index--;
    13.         pad();
    14.     }
    15.  
    16.  
    17.         public void next()
    18.     {
    19.         index++;
    20.         pad();
    21.     }
    22.  
    23.  
    24.         void pad()
    25.     {
    26.         if (index <= 0)
    27.         {
    28.             index = 0;
    29.         }
    30.  
    31.         if (index >= 1)
    32.         {
    33.             index = 1;
    34.         }
    35.  
    36.         if (index == 0)
    37.         {
    38.             //
    39.             _Previousobj.onClick.AddListener(() => Player1());
    40.             _Nextobj.onClick.AddListener(() => _Player1());
    41.             //
    42.             _Previousobj.onClick.RemoveListener(() => Player2());
    43.             _Nextobj.onClick.RemoveListener(() => _Player2());
    44.         }
    45.         else if (index == 1)
    46.         {
    47.             //
    48.             _Previousobj.onClick.RemoveListener(() => Player1());
    49.             _Nextobj.onClick.RemoveListener(() => _Player1());
    50.             //
    51.             _Previousobj.onClick.AddListener(() => Player2());
    52.             _Nextobj.onClick.AddListener(() => _Player2());
    53.         }
    54.     }
    55.  
    56.     void Player1() {
    57.         Script.obj1previous();
    58.     }
    59.  
    60.     void _Player1() {
    61.         Script.obj1next();
    62.     }
    63.  
    64.     void Player2() {
    65.         Script.obj2previous();
    66.     }
    67.  
    68.     void _Player2() {
    69.         Script.obj2next();
    70.     }
    71.    
    72.    
    73. ///Script weapon
    74. public class ScriptName : MonoBehaviour {
    75.     public GameObject[] weaponPlayer1, weaponPlayer2;
    76.  
    77.     int Selecao, Selecao1;
    78.     public void obj1next()
    79.     {
    80.         weaponPlayer1 [Selecao].SetActive (false);
    81.         Selecao++;
    82.         if (Selecao > weaponPlayer1.Length - 1)
    83.         {
    84.             Selecao = weaponPlayer1.Length -1;
    85.         }
    86.  
    87.         weaponPlayer1 [Selecao].SetActive (true);
    88.         Debug.Log("hi");
    89.     }
    90.  
    91.     public void obj1previous()
    92.     {
    93.         weaponPlayer1 [Selecao].SetActive (false);
    94.         Selecao--;
    95.         if (Selecao < 0)
    96.         {
    97.             Selecao = 0;
    98.         }
    99.  
    100.         weaponPlayer1 [Selecao].SetActive (true);
    101.         Debug.Log("hi");
    102.     }
    103.  
    104.     public void obj2next()
    105.     {
    106.         weaponPlayer2 [Selecao1].SetActive (false);
    107.         Selecao1++;
    108.         if (Selecao1 > weaponPlayer2.Length - 1)
    109.         {
    110.             Selecao1 = weaponPlayer2.Length -1;
    111.         }
    112.  
    113.         weaponPlayer2 [Selecao1].SetActive (true);
    114.         Debug.Log("hi2");
    115.     }
    116.  
    117.     public void obj2previous()
    118.     {
    119.         weaponPlayer2 [Selecao1].SetActive (false);
    120.         Selecao1--;
    121.         if (Selecao1 < 0)
    122.         {
    123.             Selecao1 = 0;
    124.         }
    125.  
    126.         weaponPlayer2 [Selecao1].SetActive (true);
    127.         Debug.Log("hi2");
    128.     }
    129. }

     
    Last edited: May 18, 2019
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,337
    There is no loop (with apologies to Neo).
     
    Ryiah likes this.
  3. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    is a type of index limiter, but it was supposed to work, could you tell me how to solve this problem?
     
  4. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    15,681
    We can't tell you anything if you only show us a very limited portion of the code. What you've shown us has no loops in it.
     
  5. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    sorry,I did not express myself well the idea I did was just a back-and-forth, that's why I called it loop, can you show me how it does, with something tutorial, api.
     
  6. ismaelflorit

    ismaelflorit

    Joined:
    Apr 16, 2019
    Posts:
    38
    In some functions you call
    Code (CSharp):
    1. index
    and in others
    Code (CSharp):
    1. Index
    . Would be good to see all the code :)
     
  7. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,595
    Maybe something like this? :
    Code (CSharp):
    1.     void previous()
    2.     {
    3.         Pad(true);
    4.     }
    5.  
    6.     void next()
    7.     {
    8.         Pad(false);
    9.     }
    10.  
    11.     void Pad(bool isPlayer1)
    12.     {
    13.         if (isPlayer1)
    14.         {
    15.             _Button.onClick.AddListener(() => Player1());
    16.             _Button.onClick.RemoveListener(() => Player2());
    17.         }
    18.         else
    19.         {
    20.             _Button.onClick.RemoveListener(() => Player1());
    21.             _Button.onClick.AddListener(() => Player2());
    22.         }
    23.     }
    24.  
    25.     void Player1()
    26.     {
    27.         // Player 1 stuff.
    28.     }
    29.  
    30.     void Player2()
    31.     {
    32.         // Player 2 stuff.
    33.     }
    34.  
    35.     [SerializeField] Button _Button;
     
    michellynitecki likes this.
  8. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    truth
    I did not realize it.

    I added the whole script and a video of what is going on
     
  9. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    The same thing happens in my script, I think the error is in logic
     
  10. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,595
    Ok, I made a mistake. The remove will not work the way I wrote it. You will need to create a variable for the event methods. For example :
    Code (CSharp):
    1.         // This will not remove the listener.
    2.         myButton.onClick.AddListener(() => MyHandler());
    3.         myButton.onClick.RemoveListener(() => MyHandler());
    4.  
    5.         // This will remove the listener.
    6.         UnityAction myMethod = () => MyHandler();
    7.         myButton.onClick.AddListener(myMethod);
    8.         myButton.onClick.RemoveListener(myMethod);
     
    ismaelflorit likes this.
  11. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    a puzzle, I completed his line to work, because he was not calling the onclick...when using UnityAction, the button is no longer shared, for example when you trigger the button in index 1 when passing to index2 it becomes inoperative

    Code (CSharp):
    1. private UnityAction myMethod, Main;
    2.     public Button _Previousobj, _Nextobj;
    3.  
    4.     private void Start()
    5.     {
    6.         pad();
    7.         myMethod += _Player1;
    8.         Main += _Player2;
    9.         _Nextobj.onClick.AddListener(myMethod);
    10.         _Nextobj.onClick.AddListener(Main);
    11.     }
    12.  
    13.  
    14.         if (index == 0)
    15.         {
    16.             UnityAction myMethod = () => _Player1();
    17.             _Nextobj.onClick.AddListener(myMethod);
    18.             _Nextobj.onClick.RemoveListener(Main);
    19.         }
    20.         else if (index == 1)
    21.         {
    22.             UnityAction Main = () => _Player2();
    23.             _Nextobj.onClick.AddListener(myMethod);
    24.             _Nextobj.onClick.RemoveListener(Main);;
    25.         }
    26.     }
     
  12. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,595
    I'm not sure how to read that code- are the all in the same class?

    Line 16 creates a
    myMethod
    event handler that will be obsolete after line 19. Also, lines 16 and 22 seem to possibly hide the variables on line 1 (depending on context).

    There seems to be two things to consider here:
    1. The exact same event handler variable instance that was given to
      AddListener
      needs also to be given to
      RemoveListener
      . So you likely want to use the variables on line 1 but definitely not the ones on lines 16 and 22.
    2. From the video above, it looks like with each click of
      Previous
      and
      Next
      , two listeners will be added (to
      ObjectPrevious
      and
      ObjectNext
      ) and two listeners will be removed (from
      ObjectPrevious
      and
      ObjectNext
      ).
     
  13. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    I did what you said, but I can not use the same variable. Action, nothing I keep trying
    Code (CSharp):
    1.         if (index == 0)
    2.         {
    3.             UnityAction myMethod = () => _Player1();
    4.             _Nextobj.onClick.AddListener(myMethod);
    5.             UnityAction myMethod2 = () => Player1();
    6.             _Previousobj.onClick.AddListener(myMethod2);
    7.  
    8.             UnityAction Main = () => _Player2();
    9.             _Nextobj.onClick.RemoveListener(Main);
    10.             UnityAction Main2 = () => Player2();
    11.             _Previousobj.onClick.RemoveListener(Main2);
    12.         }
    13.         else if (index == 1)
    14.         {
    15.             UnityAction myMethod = () => _Player1();
    16.             _Nextobj.onClick.RemoveListener(myMethod);
    17.             UnityAction myMethod2 = () => Player1();
    18.             _Previousobj.onClick.RemoveListener(myMethod2);
    19.  
    20.             UnityAction Main = () => _Player2();
    21.             _Nextobj.onClick.AddListener(Main);
    22.             UnityAction Main2 = () => Player2();
    23.             _Previousobj.onClick.AddListener(Main2);
     
  14. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,595
    Ok, let's take a step back here. Do this :
    1. Create a new scene.
    2. Into that scene add a Button.
    3. Add the script below to the MainCamera.
    4. Drag the button from the scene hierarchy and drop it into the "My Button" slot in the "Test" script on the MainCamera in the Inspector view. Do not run the code yet.
    5. Have a look at the script - what do you expect to see logged out in the console each time you click on the button?
    6. Run the scene. Does it log out as you expect when clicking the button?
    7. Now comment out line 21 and uncomment line 22. What do you expect to happen now- the same thing or something different?
    8. Run it again. Does it act as you expect now?
    Code (CSharp):
    1. public class Test : MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.         myHandler1 = () => Method1();
    6.         myHandler2 = () => Method2();
    7.         myButton.onClick.AddListener(myHandler1);
    8.     }
    9.  
    10.     void Method1()
    11.     {
    12.         Debug.Log("Marco");
    13.         myButton.onClick.RemoveListener(myHandler1);
    14.         myButton.onClick.AddListener(myHandler2);
    15.     }
    16.  
    17.     void Method2()
    18.     {
    19.         Debug.Log("Polo");
    20.         myButton.onClick.AddListener(myHandler1);
    21.         myButton.onClick.RemoveListener(myHandler2);
    22.         //myButton.onClick.RemoveListener(() => Method2());
    23.     }
    24.  
    25.     [SerializeField] Button myButton;
    26.     UnityAction myHandler1;
    27.     UnityAction myHandler2;
    28. }
     
    michellynitecki likes this.
  15. michellynitecki

    michellynitecki

    Joined:
    Apr 26, 2019
    Posts:
    34
    Thank
    Doug_B

    sorted out. I applied your concept and, instead of taking the functions into the void, I caught the function direct.
    stayed like this
    Code (CSharp):
    1.             //add
    2.             _Previousobj.onClick.AddListener(Script.obj1previous);
    3.             _Nextobj.onClick.AddListener(Script.obj1next);
    4.             //remove
    5.             _Previousobj.onClick.RemoveListener(Script.obj2previous);
    6.             _Nextobj.onClick.RemoveListener(Script.obj2next);
    7.         }
    8.         else if (index == 1)
    9.         {
    10.             //remove
    11.             _Previousobj.onClick.RemoveListener(Script.obj1previous);
    12.             _Nextobj.onClick.RemoveListener(Script.obj1next);
    13.             //add
    14.             _Previousobj.onClick.AddListener(Script.obj2previous);
    15.             _Nextobj.onClick.AddListener(Script.obj2next);
    16.         }
     
  16. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,595
    Glad you resolved it. :)
     
unityunity