#Weird Getter behaviour?

1 messages · Page 1 of 1 (latest)

lofty vine
#

I am facing a weird issue where my Getter always returns 0. Here is my code:

Setting the spawn position works but getting the spawn position always returns 0. Why?


public class Tile : MonoBehaviour
{
    [SerializeField] string tileName;

    int spawnPosition;

    public string GetTileName()
    {
        return tileName;
    }

    public int GetSpawnPosition()
    {
        print("returned: " + spawnPosition);
        return spawnPosition;
    }

    public void SetSpawnPosition(int spawnPosition)
    {
        this.spawnPosition = spawnPosition;
        print("set to: " + this.spawnPosition);
    }

    private void Update()
    {
        print("DANIEL" + spawnPosition);
    }
}```

`print("DANIEL" + spawnPosition);` always prints DANIEL0 and `print("returned: " + spawnPosition);` always prints returned 0

The weird thing is that `print("set to: " + this.spawnPosition);` prints the correct value.

The EVEN WEIRDER thing is that when I make spawnPosition public it WORKS even though I never access it directly, only through the Getter method.

**Can anybody explain this to me?**
#

The code where I call the Getter:

if (tileRb2DList[i] == null) { continue; }

tileScript = tileRb2DList[i].gameObject.GetComponent<Tile>();

if (tileScript.GetSpawnPosition() < 4)
{
    tileRb2DList[i].velocity = moveLeftVelocity;
    print("Moving tile with spawnPos : " + tileScript.GetSpawnPosition());
}
else
{
    tileRb2DList[i].velocity = moveRightVelocity;
    print("Moving tile with spawnPos : " + tileScript.GetSpawnPosition());
}```
wicked dove
#

NB: "Getter" and "setter" methods are bad C# design, use a property

lofty vine
#

What's the difference? I thought public int spawnPosition { get; set; } was just another quicker way to write get / set methods

tough robin
#

it's quicker. and more elegant.

#

And less tedious to use, because you get rid of the parentheses during declaration & calls.

wicked dove
#

more elegant
This is the key thing of it. It is indeed quicker to write, but the most important thing is that it fits with .NET guidelines. Getter/setter methods are found in langs like Python, C++, Java.
But C# doesn't do it. They are ugly and considered horrendous practice, you should always use a property to publicly expose things like that

#

The only exemption to this is if you're accepting a parameter, like for example if you had a GetCellAtCoordinate - and you needed to pass a coordinate. GetCellAtCoordinate(Vector2.zero) - you can't make this a property

lofty vine
#

If I use public int spawnPosition { get; set; }, how would I get the value?
I tried GetSpawnPosition() but that doesn't work

#

I'm sorry, I've never used properties before and the documentation seems complicated

tough robin
tough robin
#

Also, public members should always be named in PascalCase, so it would be public int SpawnPosition { get; set; }

lofty vine
#

I did tileScript.GetSpawnPosition where tileScript is the script but it says that "Tile" doesn't contain a definition for SpawnPosition

wicked dove
#

Your code snippet and your error don't match

woeful wigeonBOT
#

It's hard to answer a programming question without code

Resolving a bug is almost impossible when the question doesn't include any of the buggy code. In order to help fix the problem, answerers are going to have to see what the code is.
Source: https://idownvotedbecau.se/nocode

Please isolate the problematic code and send it as a codeblock. If you don't know how to send a codeblock, type []cb

lofty vine
#

for (int i = 0; i < tileRb2DList.Count; i++)
        {
            if (tileRb2DList[i] == null) { continue; }

            tileScript = tileRb2DList[i].gameObject.GetComponent<Tile>();

            if (tileScript.GetSpawnPosition < 4)
            {
                tileRb2DList[i].velocity = moveLeftVelocity;
                print("Moving tile with spawnPos : " + tileScript.GetSpawnPosition);
            }
            else
            {
                tileRb2DList[i].velocity = moveRightVelocity;
                print("Moving tile with spawnPos : " + tileScript.GetSpawnPosition);
            }```
#

at tileScript.GetSpawnPosition my Visual Studio says "Tile" doesn't contain a definition for SpawnPosition

wicked dove
#

Well why are you still doing GetSpawnPosition?

#

I thought you renamed it to SpawnPosition like zenvin said

ocean sinew
#

Yeah I don't see a property anywhere in that code

lofty vine
#

You are right, I thought you still had to write get ._.

#

But it's still 0, I'll send the modified code

#

public class Tile : MonoBehaviour
{
    [SerializeField] string tileName;

    public int SpawnPosition { get; set; }

    private void Update()
    {
        print("DANIEL" + SpawnPosition);
    }
}```

It's always printing DANIEL0

   for (int i = 0; i < tileRb2DList.Count; i++)
    {
        if (tileRb2DList[i] == null) { continue; }

        tileScript = tileRb2DList[i].gameObject.GetComponent<Tile>();

        if (tileScript.SpawnPosition < 4)
        {
            tileRb2DList[i].velocity = moveLeftVelocity;
            print("Moving tile with spawnPos : " + tileScript.SpawnPosition);
        }
        else
        {
            tileRb2DList[i].velocity = moveRightVelocity;
            print("Moving tile with spawnPos : " + tileScript.SpawnPosition);
        }
    } ```

Same here

   {
       int spawned = 0;
       while(spawned != spawnPositions.Length - 1)
       {
           GameObject tile = tilesToGenerate.ElementAt(Random.Range(0, tilesToGenerate.Count)).Key;
           int value;
           if(tilesToGenerate.TryGetValue(tile, out value))
           {
               if(value != 3)
               {
                   tile.GetComponent<Tile>().SpawnPosition = spawned;
                   Instantiate(tile, spawnPositions[spawned + 1].position, Quaternion.identity);
                   spawned++;
                   tilesToGenerate[tile] += 1;
               }
           }
       }
   }
}```

Setting it here
#

If I print(spawned) inside the last script, it's the value is correct

ocean sinew
#

Have you actually set the tilescripts spawn position? I don't see any code anywhere that would do so, you just seem to be getting the value which defaults to 0, you could confirm this by setting SpawnPosition equal to -1 (after the brackets like this)

public int MyInt { get; set; } = -1
lofty vine
lofty vine
#

Anyone else? <@&823670198958948373>

pallid dagger
#

Umm, wait, imma read back

#

Umm, you should see before you get

#

Set*

lofty vine
#

When I make it visible in the editor, it's not 0

pallid dagger
#

Also I'm making a spawning system for my game, so maybe I can help you more when I start making it

lofty vine
#

Mine already works, it's 2D I just need to know which spawn something spawned from and I didn't think I would need that when making it D:

lofty vine
pallid dagger
lofty vine
#

Yes that is the case

pallid dagger
lofty vine
#

That's correct

pallid dagger
#

[]cb

woeful wigeonBOT
#

Use codeblocks to send code in a message!

To make a codeblock, surround your code with ```
To use C# syntax highlighting add cs after the three back ticks.

For example:
```cs
Console.WriteLine("Hello World");
```

Produces:

Console.WriteLine("Hello World");

To send lengthy code, paste it into https://paste.myst.rs/ and send the link of the paste into chat.

pallid dagger
#

Sorry, didn't mean to do thar

#

That*

lofty vine
#

at the top

#

"The EVEN WEIRDER thing is that when I make spawnPosition public it WORKS even though I never access it directly, only through the Getter method."

#

Can you explain that?

#

This makes no sense to me

tough robin
# pallid dagger All scripts run simultaneously in unity, so you have to make sure that the get h...

NB: This is technically not quite correct.
Every Update/LateUpdate method of every script instance runs every frame, but that's far from being "simultaneous". They will still be executed in a certain order.
You can only get stuff to run truly simultaneously, if you multithread (which Unity does not do by default). And if you have operations placed within the same method, they will always be executed in the order that they are written in.

pallid dagger
#

That's what I meant

pallid dagger
pallid dagger
lofty vine
#

I did this:

{
    [SerializeField] int test = 999;

    void Update()
    {
        test = (GetComponent<Tile>().SpawnPosition);
    }
}```
#

(This is when using properties because the other people told me to use properties)

pallid dagger
pallid dagger
lofty vine
#

Still showing 0

{
    [SerializeField] int test = 999;

    void Update()
    {
        test = this.GetComponent<Tile>().SpawnPosition;
    }
}```
pallid dagger
#

Assign the game object that has the spawnposition to the scriptParent variable

pallid dagger
lofty vine
#

But the property looks like this public int SpawnPosition { get; set; } = 0;

pallid dagger
lofty vine
pallid dagger
lofty vine
#

Like this?

public class tesdt : MonoBehaviour
{
    [SerializeField] int test = 999;
    [SerializeField] GameObject scriptParent;

    void Update()
    {
        test = scriptParent.GetComponent<Tile>().SpawnPosition;
    }
}```
pallid dagger
lofty vine
#

It's showing 0 @pallid dagger

pallid dagger
#

I'm getting confused

lofty vine
#

I'm already confused, don't worry

pallid dagger
lofty vine
#

What part of it?

pallid dagger
#

Problem is... I can't try it in my phone

pallid dagger
#

Wait

#

I have an idea

lofty vine
#

😮

pallid dagger
#

If it does work, then the problem really is in the order in which the methods run

lofty vine
#

If the problem is the order, can't I just run my test script in LateUpdate()?

#

to test

pallid dagger
lofty vine
#

How do I add GetSpawnPositionSetter() to the context menu

pallid dagger
lofty vine
#

I think we both have been dividing way too much time to this. I think I should stop and just go with making it public. We might figure it out after 1 hour but it wouldn't be worth it I think

#

I have been sitting in this thread for hours but I don't think it's worth it honestly

#

I hope that doesn't disappoint you. I must say you have been a great help when troubleshooting 🙂

pallid dagger
#

Anyways you can add a method to context menu by doing:

[ContextMenu("Name you want in inspector")]

Before the method declaration

pallid dagger
#

You're welcome

ocean sinew
#

Everything runs synchronously in Unity, one after another, some scripts are executed before others but all have a certain order that is followed and unless you explicitly add asynchronous code into your game it will always finish one method before moving to the next

#

As for the setting and getting your condition is that the variable value is not 3 before setting spawn position, but you're not checking if
A: the tile actually has a component called Tile
B: tilesToGenerate actually has a legitimate value of "tile" which is likely the problem
Also there's a lot of abuse of GetComponent and such which would be really taxing on the system with repeated calls
Also lots of accessing variables inside arrays without just caching them which arguably would be cleaner and faster

pallid dagger
pallid dagger
#

So it doesn't matter

ocean sinew
#

Half assed fixes aren't solutions, especially as this fix doesn't really address the root problem

pallid dagger
ocean sinew
#

I pointed the most likely issues out above