#Let's add verticality to 2D top-down-scenes

6 messages · Page 1 of 1 (latest)

simple granite
#

https://www.youtube.com/watch?v=Z-iXfstZNgM
So I've seen this video, and I wanna create a system, that's similar to this. Thanks to CanvasGroups and TileMapLayers, the rendering part should be fairly easy, Even though i still have zto figure out how to maybe add a blur-effect to layers, that are out of focus for extra waowzers. What's bothering me, is the physics part. There aren't enough CollisionLayers to make is scalable, and i don't think that's what the layers are meant for. So far the cleanest way I've found to put the different layers into different PHYSICS SPACES, using PhysicsServer2D and body_set_space() or area_set_space() as well as a singleton, that keeps track of the RIDs of each space, that's in use. The neat thing is, that you can turn these physics spaces on and off on the fly, which may be useful for some more experimental games. Yet, I still have the issue, that it's a teensy bit convoluted overall, after all you have to loop through all nodes at the beginning, sort them into their respective spaces and do it again for each node that gets added to the tree and happens to be a collisionobject. There's also the problem of what to do, when an object needs to interact with objects of multiple layers.

I'd like some input on how to pull it off as easy and scalable as possible, maybe someone has seen a demo project?

Join my Discord:
https://discord.gg/rTmmPzEGK6

Download the latest early build of Goblin Menace:
https://bit.ly/goblin_menace_alpha

About me:
I'm making a sandbox action RPG with a focus on building your own AI-controlled mercenary army to fight hordes of goblins. I make games with a top-down 2.5D pixel art style.

▶ Play video
#

Here's what i got so far:

extends Node

var spaces : Array[RID]

func get_space(idx: int) -> RID:
    while spaces.size() < idx + 1:
        spaces.append(PhysicsServer2D.space_create())
    return spaces[idx]```

``` # PhysicsLayer.gd
extends CanvasGroup

@export var physics_space : int = 0 : set = set_physics_space
var space : RID
var colliders : Array[CollisionObject2D]

func _ready() -> void:
    set_physics_space(physics_space)

func find_colliders(node: Node) -> Array[CollisionObject2D]:
    var c : Array[CollisionObject2D]
    for N in node.get_children():
        
        if N is CollisionObject2D:
            c.append(N)
        
        c.append_array(find_colliders(N))
        
    
    return c

func set_physics_space(value : int) -> void:
    physics_space = value
    space = PhysicsLayerManager2d.get_space(physics_space)
    for i in find_colliders(self):
        add_to_space(i)
    PhysicsServer2D.space_set_active(space, true)

func add_to_space(collider: CollisionObject2D) -> void:
    if collider is Area2D:
        PhysicsServer2D.area_set_space(collider.get_rid(), space)
    elif collider is PhysicsBody2D:
        PhysicsServer2D.body_set_space(collider.get_rid(), space)
    else:
        printerr("FAIL")
extends Area2D

@export var target_space : int = 0


func _on_body_entered(body: Node2D) -> void:
    print("mlem :3")
    var space : RID = PhysicsLayerManager2d.get_space(target_space)
    PhysicsServer2D.body_set_space(body.get_rid(), space)

But idk, maybe i'm overengineering it. lemme know your thoughts

#

^This works, by the way, but it comes with a few issues itself. for instance, gravity is suddenly upside down and idk why. Feel free to make a test project and test it yourself. Simply add 2 CanvasGroups with the script to a 2D Scene, and add a few staticbodies and rigidbodies as a child to each one. Then set the idx of the physics space in the inspector. The two layers won't interact with each other.

opal thunder
#

Bookmarked.

simple granite
#

Currently working on implementing a system for this, i'll make it an editorplugin, probably.

balmy wraith