Why can I not change the enum value?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By gcivico
:warning: Old Version Published before Godot 3 was released.

On stage editor I have an Area2D with this code:

extends Area2D

const PlayerController = preload("res://player/script/2017-07-25/PlayerController.gd")

func _ready():
    connect("body_enter", self, "_on_player_body_enter")
    pass

func _on_player_body_enter( body ):
    if body.get_name() == "Player":
        print(PlayerController.CollisionState.has("Bottom"))
        print(PlayerController.CollisionState)
        print(get_tree().get_root().get_node("Game").get_node("Player").CollisionState)
        if PlayerController.CollisionState.has("Bottom"):
            PlayerController.CollisionState.Bottom = true
#           get_tree().get_root().get_node("Game").get_node("Player").CollisionState.Bottom = true

If the Player enter in to the Area2D, the value of CollisionState.Bottom have to be true, where CollisionState is an enum on PlayerController:

extends KinematicBody2D

enum CollisionState {
    None,
    Top,
    Right,
    Bottom,
    Left,
    Wall,
    Slope,
    RSlope,
    LSlope
}
var groundRayCasts = []
var onAir = false

func _ready():
    CollisionState.None = true
    CollisionState.Top = false
    CollisionState.Right = false
    CollisionState.Bottom = false
    CollisionState.Left = false
    CollisionState.Slope = false
    CollisionState.RSlope = false
    CollisionState.LSlope = false
    CollisionState.Wall = false
...
... More code here ...

But the Debugger show this error:

Invalid set index 'CollisionState' (on base: 'GDScript').

But the prints show this:

True
(Bottom:True), (LSlope:False), (Left:False), (None:True), (RSlope:False), (Right:False), (Slope:False), (Top:False), (Wall:False), (lSlope:False)
(Bottom:True), (LSlope:False), (Left:False), (None:True), (RSlope:False), (Right:False), (Slope:False), (Top:False), (Wall:False), (lSlope:False)

What I’m doing wrong?

:bust_in_silhouette: Reply From: aozasori

enum elements are read only. You aren’t supposed to change them.
They are meant to represent a set of related things with integer values.

Each element in the enum has an integer value counting up from 0.

For what you are trying to do, you should use a dictionary instead.

var CollisionState = {
    None=true,
    Top=false,
    Right=false,
    Bottom=false,
    Left=false,
    Wall=false,
    Slope=false,
    RSlope=false,
    LSlope=false
}

And to set a value:

CollisionState["Bottom"] = true

Thanks aozasori

I changed to a Dictionary and the code worked like this:

extends Area2D

func _ready():
	connect("body_enter", self, "_on_player_body_enter")
	pass

func _on_player_body_enter( body ):
	if body.get_name() == "Player":
		var PC = get_tree().get_root().get_node("Game").get_node("Player")
		PC.CollisionState["Bottom"] = true

gcivico | 2017-07-28 04:28

If you are into optimization, you could also use a single integer as a bitfield :wink:

Zylann | 2017-07-28 16:34