custom data layers characterbody2d

Godot Version

4.x

Question

I was wondering how you could access custom data layers on characterbody2d as a root node, I’ve already looked at multiple videos and forums but they didn’t help

I want to use custom data layers for many things from adjusting speed on different blocks and making exit blocks to possibly adding wall bouncing in the future.

I’m basically asking if I can see what block I collided with so I can do stuff like change character speed etc.

thanks in advance!

If you’re talking about the physics layer names, this is what it looks like:

Snipaste_2024-07-26_19-35-56

After this, use the names configured in the collision settings, such as a CharacterBody2D:

I don’t believe that is what I was looking for unless this somehow solves my issue, I am looking for custom data layers, like from the tile map, I don’t know how to get the custom data into my code

Maybe you need to use metadata?

  • Metadata can be access by get_meta(StringName) -> Variant and set_meta(StringName, Variant) -> void
  • Metadata is binded to the instance, not the type.

Or use interface?

  • Interface means a type, but there’s nothing like that in gdscript.
  • If a object has all properties and methods defined by a interface, that’s means the object implemented the interface.
  • With interface, you can define some type like SpeedInfluceObject by defining what this type has.
  • You can use has_method(StringName) -> bool with a unique name to check if a object implemented a interface. Metadata can do this too.
  • A simple example:
    class A extends RefCounted:
      func implemented_IA() -> void: return
      var IA_factor: int = 2
    class B extends RefCounted:
      func implemented_IA() -> void: return
      var IA_factor: int = 3
    class C extends RefCounted:
      pass
    
    func _ready() -> void:
      process(A.new()) # factor is 2
      process(B.new()) # factor is 3
      process(C.new()) # nothing
    
    func process(obj) -> void:
      if obj.has_method("implemented_IA"):
        print("factor is " + str(obj.IA_factor))
    
1 Like

sorry, but is this in gdscript? I’m sorry to be a pain but my small mind can’t understand, I’m a beginner.

It’s gdscript.

At the first, there’s a agreement:
Defined method implemented_IA means:

  • It implemented interface IA
  • It has a variable named IA_factor with type int

class A extends RefCounted means define a class that extends RefCounted(like Object, but don’t need to care about memory manage).
func implemented_IA() -> void: return defined a method for class A.
var IA_factor: int = 2 defined a variable IA_factor and assigned with 2
It’s same to B and C

obj.has_method("implemented_IA") will check if obj has a method named implemented_IA. In this case, instances of class A and B will pass.
Then follow the agreement, defined implemented_IA means it has a variable IA_factor. So it’s safe to access directly unless something doesn’t follow the agreement.
In this case, instances of A and B passed the if statement. So it will print the factor of instances of A and B. Instance of C doesn’t passed the if statement, it will do nothing. That’s why you saw that output.

Method implemented_IA doesn’t have any effect, it just a sign tells "I implemented interface IA` other methods. So you will never call that method.
But not only can use method as a sign, but also can use signal, metadata, class name, and many ways as a sign.

But gdscript haven’t really interface system, you can try C#:

using Godot;

interface IA
{
  public int IA_factor{get; set; }
}

class A implements IA
{
  public int IA_factor{get; set; } = 2;
}

public partial class Test: Node
{
  public override void _Ready()
  {
    IA a = new A();
    Godot.Print(a is IA);
    Godot.Print(a.IA_factor);
  }
}

Maybe you need to fix it to running in C#.