godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Make collision layer a class / resource #329

Closed fossegutten closed 2 years ago

fossegutten commented 4 years ago

I would suggest to make the collision layers / masks into a resource. The code for layers is now repeated in physics_body, physicsbody2d, area, area3d, csgshape, softbody, gridmap and tilemap. Including methods to edit the collision layer. setting bit value, getting bit value etc.

Describe the project you are working on: Working on several projects that uses inner classes or custom nodes, that needs a collision mask / layer.

Describe the problem or limitation you are having in your project: The problem is to get a collision_layer to communicate with the regular physics system. Now i need to first make an area2d node or similar, then check all collision bits i need, then print out the value of collision_layer. The printed out value can now be used for collision_layer, which i use as a value in my bullet class, to be used as a parameter in Physics2DShapeQueryParameters.

Describe how this feature / enhancement will help you overcome this problem or limitation: This way I could just add a collision_layer resource to my classes / nodes, and use this through exposed methods.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work: Here is an example, with the CollisionLayer inner class representing the custom resource that i suggest:

extends Node

var player_bullets : Array = []

func _ready():
    for i in 10:
        var p : Projectile = Projectile.new()
        p.pos = Vector2(10, 20 * i)
        p.dir = Vector2.RIGHT
        p.speed = 10.0
        p.damage = 1
        player_bullets.append( p )

func _process(delta):
    for b in player_bullets:
        # process logic, included collisions with Physics2DDirectSpaceState
        pass

class Projectile:

    var pos : Vector2
    var dir : Vector2
    var speed : float
    var damage : int
    var collision_layer : CollisionLayer

    func set_collision_layer(new_layer : CollisionLayer):
        collision_layer = new_layer

class CollisionLayer:

    var _layer

    func get_layer():
        return _layer

Describe implementation detail for your proposal (in code), if possible: Move the code from all the above mentioned classes into a resource that they can all use, with exposed methods for setting bit values, getting values, and getting the collision layer value (int).

If this enhancement will not be used often, can it be worked around with a few lines of script?: It could be made in GDscript with functions like this, but it will require several lines:

func set_collision_layer_bit(layer : int, bit : int, value : bool) -> int:
    if value:
        layer |= 1 << bit
    else:
        layer &= ~(1 << bit)
    return layer

Is there a reason why this should be core and not an add-on in the asset library?: It would also reduce the repeating of code in the Godot code base.

YuriSizov commented 2 years ago

There doesn't seem to be a lot of traction for this idea, but something similar has been proposed recently. So I'll close this one in favor of a more actual discussion: https://github.com/godotengine/godot-proposals/issues/4200