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

Question Confusion with float and string

Discussion in 'Scripting' started by es7509, Oct 25, 2022.

  1. es7509

    es7509

    Joined:
    Aug 25, 2022
    Posts:
    2
    Hi, I am a beginner programmer which means I don't really know what I'm doing.
    I have created a script to change scenes when something happens. (i.e. a button)
    I tried adding a public variable to specify how much you want the scenes to change by.
    When I save the code and unity reloads, it gives me this error;

    Assets\MainMenu.cs(11,36): error CS1503: Argument 1: cannot convert from 'float' to 'string'

    I've tried changing the variable type, adding a cast, and both, but nothing has worked so far.
    This is the script;

    public class MainMenu : MonoBehaviour
    {
    public float sceneIncrement = 1f;
    public void PlayGame()
    {
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + sceneIncrement);
    }

    }
    Can anyone tell me what I am doing wrong?
    Thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    Best to break this into separate lines, one step at a time:

    - get the index
    - increment it
    - load it

    If you have more than one or two dots (.) in a single statement, you're just being mean to yourself.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    "Programming is hard enough without making it harder for ourselves." - angrypenguin on Unity3D forums

    "Combining a bunch of stuff into one line always feels satisfying, but it's always a PITA to debug." - StarManta on the Unity3D forums

    Once you do that, you must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    When in doubt, print it out!(tm)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.
     
    Bunny83 likes this.
  3. es7509

    es7509

    Joined:
    Aug 25, 2022
    Posts:
    2
    This helped a lot! Thanks for the help!
     
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,571
    Since Kurt went overboard again, let me give you the usual approach how to solve such problems. The compiler complains that you try to pass a float to a method where the compiler expected a string. Such issues gets more complicated when you use a method that has "overloads". A method is called "overloaded" if there are more than one method with the exact same name, but different arguments. So the compiler has to figure out which method it should call based on the arguments you, the programmer, passed to the method.

    So we start at the documentation.
    As you can see, there are two overloads of the LoadScene method. The first one takes an integer that should specify the scene build index of the scene you want to load, the other expects a string indicating the name of the scene you want to load. Those are the only two options.

    Now the error of the compiler already tells you that you try to pass a float in a place where the compiler expects a string. A float value is neither an integer nor a string. So the compiler simply picked one of the overloads (the string version) and couldn't find an implicit way of converting a float to a string or an int value. This is your problem.

    The scene index is an integer value.
    SceneManager.GetActiveScene().buildIndex
    is also an integer. However you declared your "sceneIncrement" variable as a float which is your main problem and should be changed. When you add a float value to an integer value, the result would be a float. It doesn't make much sense to declare sceneIncrement as a float since you never want and never can increment the current scene index by a fractional number like 0.2f. Indices always have to be whole numbers.

    So just declare your sceneIncrement as an "int" and the issue should be gone. Of course the field initializer can't be
    = 1f
    and has to be changed as well:

    Code (CSharp):
    1. public int sceneIncrement = 1;
     
    Madgvox likes this.
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Yes, well you're neglecting the pieces of the puzzle which are very essential to the system as a whole.

    Basically, when you're programming in C#, there are lots of little tiny parts that are sometimes annoyingly precise and all of them have to fit together. There is no mind-reading and the system is never smart, unless it's some mechanical duty that makes the actual job of programming easier.

    In this case, yes you've passed the syntax check, but you've neglected to pay attention to the types of your variables, as well as different flavors of that particular method, as explained by Bunny. Both type strictness and method overloading are critically important features of the language and you should read up more on that.
     
    Bunny83 likes this.