Fields assigned values aren't being referenced by other files in the same namespace (Error CS0103)

Hi again,

So I’m trying to reference fields that are declared in other files with the same namespace, except they’re not and I’m getting error CS0103 instead. I’m also getting warnings on the pages of the actual fields themselves saying that they’re assigned but never used, which I guess is technically true since when I try to actually use them they don’t work. Here’s some example!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System.Linq;

namespace ScissorsPaperRock
{
    public class WhoWins
    {
        public static void Start()
        {
            if (thePlayerChosenOption = UNIT.SCISSORS) // Error The name 'thePlayerChosenOption' does not exist in the current context
            {
                if (theAIChosenOption = UNIT.SCISSORS) // error CS0103: The name 'theAIChosenOption' does not exist in the current context
                {
                    Debug.Log("The game is a tie!");
                }
                else if (theAIChosenOption = UNIT.PAPER) // error CS0103: The name 'theAIChosenOption' does not exist in the current context
                {
                    Debug.Log("You win!");
                }
                else
                {
                    Debug.Log("You lose!");
                }
            }

This obviously isn’t the full code, but it should hopefully be enough to give you guys an understanding of what’s going on.

Here’s one of the files where thePlayerChosenOption is declared.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System.Linq;
using ScissorsPaperRock;

namespace ScissorsPaperRock
{
    public class SelectScissors : MonoBehaviour, IPointerClickHandler
    {
        UNIT thePlayerChosenOption; // warning CS0414: The field 'SelectScissors.thePlayerChosenOption' is assigned but its value is never used
        public void OnPointerClick(PointerEventData pointerEventData)
        {
            Debug.Log("You selected scissors!");
            thePlayerChosenOption = UNIT.SCISSORS; // I don't think the enums are being referenced either.
        }
    }
}

Even though in theory, my field is declared and used. In practice, it’s sure assigned a value. But the main isn’t picking up on it.

It’s weird because I’m not getting warning CS0414 on this file’s field:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace ScissorsPaperRock
{
    public class AIOption
    {
        public UNIT theAIChosenOption;
        public void start()
        {
            System.Random rnd = new System.Random(); // Makes the random class.
            int AISelect = rnd.Next(0, 3);
            {
                if (AISelect == 0)
                    theAIChosenOption = UNIT.SCISSORS; // I don't think enums from UnitData.cs AREN'T BEING REFERENCED!
                else if (AISelect == 1)
                    theAIChosenOption = UNIT.PAPER; //If true, this essentially means that this is doing nothing.
                else
                    theAIChosenOption = UNIT.ROCK;
                // In theory, this code SHOULD select one of the three enums in UnitData.cs and keep the selected option on hand.
            }
        }
    }
}

Even though any attempts to reference it in other code files are also met with error CS0103.

Here’s were the enum UNIT is declared.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

namespace ScissorsPaperRock
{
    public enum UNIT
    {
        SCISSORS,
        PAPER,
        ROCK
    }
}

I personally don’t believe that the enums are being referenced.

I’m entirely confused, and it’s clearly something to do with Unity. Because when I recreated most of the code in a native C# app in Visual Studio, none of these errors or warnings showed up.

What is different about Unity that makes it so this doesn’t work, and how can I fix it? I’m entirely stumped.

Cheers.

EDIT: So I also asked this on Reddit and was told that if I made theAIChosenOption a public static variable, and in turn replace every instance of theAIChosenOption in my WhoWins.cs with AIChoice.theAIChosenOption that it should fix all of those errors. It didn’t. But when I went 1 step further and changed public class AIOption to public static class AIOption, this fixed every single error and removed every single warning. In its place is a single solitary error saying: “AIChoice.cs(11,21): error CS0708: ‘start’: cannot declare instance members in a static class”. So when I did the Reddit fix of changing public void start() to public static void start(), all of the errors came back.

Now, old me would have said “Welp, that means his fix was broken.” But I encountered this before, and am pretty sure it actually means the errors were never fixed in the first place.

In short, still looking for a solution. But I’ve learned more from it.

Starting off with ‘thePlayerChosenOption’ (problem is the same across the board), it is in the class WhoWins and referenced just by itself so it expects the value to be in the class WhoWins. However, you declared it in the class SelectScissors. While they are in the same namespace, they are different classes and thus can’t reference each other’s properties like this. Further thePlayerChosenOption is declared without a modifier for private/public so it is by default private, so even if you had a reference to SelectScissors you still couldn’t get the value.

I think you’re fundamentally misunderstanding what a namespace does. A namespace is a division of visibility on classes/structs. It does not confer any added visibility, and in fact only restricts visibility of properties and such. You usually use namespaces in complex projects to keep them better organized, especially when you start using similar names for classes but with totally different implementations for those classes, but they aren’t really necessary.

1 Like

I don’t quite understand why this is the case, since I don’t need to do this in a native C# app. I’m not trying to argue, I’m just confused.

I didn’t actually know this. I thought that a namespace did confer added visibility.

Thank you very much for your help, you’ve given me a far better understanding of something I was seriously misinterpreting.

Just as way of an example, maybe not appropriate for you, but I’ll give you some example code that should work (I haven’t compiled it, but should be about right):

public class WhoWins
{
        public static void Start()
        {
            if (SelectScissors.thePlayerChosenOption = UNIT.SCISSORS)
            {
                if (AIOption.theAIChosenOption = UNIT.SCISSORS)
                {
                    Debug.Log("The game is a tie!");
                }
                else if (AIOption.theAIChosenOption = UNIT.PAPER)
                {
                    Debug.Log("You win!");
                }
                else
                {
                    Debug.Log("You lose!");
                }
            }
        }

}

public class SelectScissors : MonoBehaviour, IPointerClickHandler
    {
        public static UNIT thePlayerChosenOption;
        public void OnPointerClick(PointerEventData pointerEventData)
        {
            Debug.Log("You selected scissors!");
            thePlayerChosenOption = UNIT.SCISSORS;
        }
    }

public class AIOption
    {
        public static UNIT theAIChosenOption;
        public void start()
        {
            System.Random rnd = new System.Random(); // Makes the random class.
            int AISelect = rnd.Next(0, 3);
            {
                if (AISelect == 0)
                    theAIChosenOption = UNIT.SCISSORS;
                else if (AISelect == 1)
                    theAIChosenOption = UNIT.PAPER;
                else
                    theAIChosenOption = UNIT.ROCK;
               
            }
        }
    }

public enum UNIT
    {
        SCISSORS,
        PAPER,
        ROCK
    }

Now it is important to note here this only allows 1 independent instance of AIOption and SelectScissors, so if for some reason you need more, this definitely wouldn’t work as it is using the static method. To have more you’d have to make them just publics then pass references to the instances to WhoWins so it can properly reference the particular instance.