Search Unity

Why TryParse would fail and how to Convert.ToInt

Discussion in 'Scripting' started by binbash3r, Oct 6, 2018.

  1. binbash3r

    binbash3r

    Joined:
    Nov 5, 2016
    Posts:
    13
    Hello everyone,

    I'm currently working on a new project that works through Twitch.tv. The Script I'll be posting grabs commands with int values. Since the text we're parsing is always a type of "String", in order to parse these values correctly into variables, I need to replace the command text with nothing, set up a variable to parse to and output just the integer value that the player has specified in chat.

    Example: Player types "!aim 50" in chat .
    The command "!aim" would get removed from the string, and "50" of type String would be left. I then attempt to convert that string value into an integer value that I can pass into the player's instantiated prefab.

    Code (CSharp):
    1.                 //First we check if we're in the attack round.
    2.                 if (rm.phase == "Attack")
    3.                 {
    4.                     GameObject playerGO = GameObject.Find(name);
    5.                     string aimAngle = e.Command.ChatMessage.Message;
    6.                     aimAngle = aimAngle.Replace("!aim ", "");
    7.                     int aimAngleInt;
    8.                     int.TryParse(aimAngle, out aimAngleInt);
    9.  
    10.                     //Do a check to see if the angle is within physics boundaries. If not, break.
    11.                     if (aimAngleInt >= 0 && aimAngleInt <= 360)
    12.                     {
    13.                         //If the angle is acceptable, set the aim angle for the player.
    14.                         //Get the player's instantiated prefab, and set angle on the attached aim script.
    15.                         playerGO.GetComponent<Aim>().SetAimToAngle(aimAngleInt);
    16.                         Debug.Log(aimAngleInt);
    17.                     }
    18.                     else
    19.                     {
    20.                         //The value specified was either too low or too high. Ignore the command.
    21.                     }
    22.                 }
    23.                 else
    24.                 {
    25.                     //Do nothing, because we're in the attack round.
    26.                 }
    27.                 break;
    28.  
    29.             case "fire":
    30.                 _client.SendMessage(e.Command.ChatMessage.Channel, $"Firing!");
    31.                 if (rm.phase == "Attack")
    32.                 {
    33.                     string forceValue = e.Command.ChatMessage.Message;
    34.                     forceValue = forceValue.Replace("!attack ", "");
    35.                     int forceValueInt;
    36.                     int.TryParse(forceValue, out forceValueInt);
    37.  
    With every case, except for fire, TryParse works perfectly - the string value is converted to an integer value and the int variable is assigned the int value. As mentioned, on line 36, TryParse returns a value of "0", which if I understand correctly, means that TryParse failed to parse the string as an integer.

    My questions are:

    Why would every case but this one work? The code is exactly the same in terms of context, and nearly literally.
    What could have changed to cause TryParse to fail in the first place?

    It is absolutely necessary that the string value is converted to an integer value to pass into the player prefab's attached Fire script.

    What are some examples of other ways I could convert/parse the string as an integer knowing the answers to the above questions in mind?
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,440
    so if you print out the forceValue, there is no special characters or anything there, just numbers?
    int.TryParse will also return bool, so can check when it failed,
    if (int.TryParse(..)==false) ...
     
  3. binbash3r

    binbash3r

    Joined:
    Nov 5, 2016
    Posts:
    13
    If I print the value of forceValue, it's the entire string of the player's chat command. IE: "!fire 50"
    If I print the value of forceValueInt, the value is "0", which is the boolean return of TryParse as False.

    I have put a conditional in the block of code to test:
    Code (CSharp):
    1.             case "fire":
    2.                 _client.SendMessage(e.Command.ChatMessage.Channel, $"Firing!");
    3.                 if (rm.phase == "Attack")
    4.                 {
    5.                     string forceValue = e.Command.ChatMessage.Message;
    6.                     forceValue = forceValue.Replace("!attack ", "");
    7.                     int forceValueInt;
    8.                     if (int.TryParse(forceValue, out forceValueInt) == false)
    9.                     {
    10.                         Debug.Log("TryParse failed.");
    11.                     }
    I ran it, typed "!fire 50", and got:
    TryParse failed.

     
    Last edited: Oct 6, 2018
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,440
    ok, then need to remove the "!fire "-part, like you do for replace "!attack "
     
    binbash3r likes this.
  5. binbash3r

    binbash3r

    Joined:
    Nov 5, 2016
    Posts:
    13
    After hours of looking at this.. it's been a typo all along.
    Face, meet palm. Palm, meet face.

    You're right, I do need to remove the !fire part, except the string to replace in that is "!attack".

    ... it should be "!fire ".
    I am so sorry I have missed this for two days.
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,440
    debug.log() is always your best friend when things don't work : )

    you could also split using the space character, then parse the second part if split was successful,
    so then no need to keep track of your replace commands if they change.
     
  7. binbash3r

    binbash3r

    Joined:
    Nov 5, 2016
    Posts:
    13
    Could you give me a small snippet as an example in the context of my project? I was under the assumption that split was used to access an array, and I chose not to use this for simplicity's sake. Is there another way?
     
  8. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,440
    im thinking something like,
    Code (CSharp):
    1. string forceValue = e.Command.ChatMessage.Message;
    2.                     var s = forceValue.split(' ');
    3.                     if (s!=null && s.length>1)
    4.                     {
    5.                         int forceValueInt;
    6.                         if (int.TryParse(s[1], out forceValueInt) == false)
    7.                         {
    8.                             Debug.Log("TryParse failed.");
    9.                        }
    10.                    }
    actually could just take index of space, and parse substring something like
    Code (CSharp):
    1. string forceValue = e.Command.ChatMessage.Message;
    2.                     var space = forceValue.indexOf(' ')+1; // find where space is
    3.                     if (space>0)
    4.                     {
    5.                         int forceValueInt;
    6.                         if (int.TryParse(forceValue.subString(space,forceValue.length-space), out forceValueInt) == false)
    7.                         {
    8.                             Debug.Log("TryParse failed.");
    9.                        }
    10.                    }
     
  9. binbash3r

    binbash3r

    Joined:
    Nov 5, 2016
    Posts:
    13
    Got it! Thanks so much for your help here. That's making sense to me!