How to make scene instances unable to overlap each other?
Asked Answered
T

18

0

Hi! I'm trying to create my own Dialogue manager to help me with my game, and it's going great. But I can't find an solution to the issue of my dialogue boxes overlapping each other.

I want to be able to create multiple instances of dialogue boxes that I can edit in real time. For this I would like to make it so the boxes can't touch nor overlap each other. But I can't find how. I tried making them StaticBody2D with really weird results since they seem to follow each other when touching.

I would appreciate any advice about a better way to do it!

Here is a screenshot of two boxes overlapping. I want to make it so it's impossible for that to happen.

Troche answered 19/9, 2023 at 16:29 Comment(0)
G
0

Troche Could you make a screenshot and show us what you have or trying to do? Because if you talk about dialogue then my first thought would be more along the lines of Control and not StaticBody2D.

Grapery answered 19/9, 2023 at 16:55 Comment(0)
T
0

Grapery I just updated the post with a screenshot of the dialog boxes overlapping each other. They are control nodes, I'm trying to make it so it's impossible for them to touch or overlap another box!

Troche answered 19/9, 2023 at 17:17 Comment(0)
G
0

Troche Could you add a container control that for example sits at the center of the screen per default and that automatically layouts your dialogs? Maybe arrange them next to each other in at most two columns and then if you add a third dialog it adds a new row and shows the new dialog below the other two.

Edit: Or maybe just a tab container. Add a tab for every new dialog. After all, do you really need to show more than one or two on the screen at once?

Grapery answered 19/9, 2023 at 17:36 Comment(0)
T
0

Grapery It's not what I wanted but i might be enough. I will try it, thank you!

Troche answered 19/9, 2023 at 18:30 Comment(0)
W
0

I'm vomiting ideas here:

  • draw() signal fires everytime a control node is redrawn, for example, when appearing, moving or resizing.
  • a rect's position should be located at its top left corner by default, so:
    anywhere between rect.position and rect.position + rect.size would be occupied by rect.

you could use that draw() signal with the vector2 math above to convince your control nodes to behave how I think you're wanting them to behave.
if you're clever.
i am a lot more familiar with gdscript than most of godot's builtin functions, so please someone speak up if what i'm suggesting is unnecessarily hacky.

Wooley answered 19/9, 2023 at 20:9 Comment(0)
T
0

Grapery I tried it with containers and it kind of works but It's not really what I was looking for. This way I can't move them around and connect them as I had planned.

If someone knows a better way, I would appreciate it!

Troche answered 19/9, 2023 at 21:7 Comment(0)
G
0

Oh, you wanted to connect them? I thought they were more like dialog boxes.

Grapery answered 19/9, 2023 at 21:30 Comment(0)
T
0

Wooley Those are great ideas too! I will test them and get back to you!

Troche answered 19/9, 2023 at 22:3 Comment(0)
T
0

Grapery Oh no this is more like my dialog manager so this is where I will be making the narrative in the back end. At the end I should be able to export the whole tree of conversation to a json file that I will use with my actual dialogue box. That's why I want to be able to move them around and connect them but without them overlapping/touching

Troche answered 19/9, 2023 at 22:4 Comment(0)
W
0

Troche It's not worth the effort if this is just for backend. Let them overlap. Almost every node editor in existence overlaps its nodes.

Wallachia answered 19/9, 2023 at 22:9 Comment(0)
B
0

I agree it isn't necessary or worth it, but why not do it anyway for fun? πŸ˜›

Coercion Do you already have figured out how you're doing click & drag? You should implement that first, then at the point in code where you release after dragging you can worry about making the boxes not overlap.

Bagel answered 20/9, 2023 at 4:56 Comment(0)
T
0

Wallachia True but it's a good opportunity to challenge myself so I can learn more about the engine (and do more things in the actual game). So my goal is that they can't won't touch.

Troche answered 20/9, 2023 at 10:24 Comment(0)
T
0

Bagel Yeah, it's more like a challenge to improve. In fact I could use GraphNodes and GraphEdit to have them directly but I'm traying to make them myself so I can learn and play with the logic.

I haven't figured out the connection yet, but I guess I will use curve2D and a simple drag and drop code that checks if can_drag and can_drop. The hard part would be making interactions between them when linked, I think.

Troche answered 20/9, 2023 at 10:27 Comment(0)
W
0

Troche True but it's a good opportunity to challenge myself

Well if you want to challenge yourself, then you should figure it out on your own. By asking "how to", you're challenging the people on the forum instead πŸ˜‰

This can be done in several ways. Start by precisely describing the behavior. Can you drag one or multiple boxes at a time? Should they rearrange as you drag or only when you drop? Should they be pushed in the direction of drag or only moved out of the way... etc.

Wallachia answered 20/9, 2023 at 10:35 Comment(0)
T
0

Wallachia I tried myself for a long time. If I'm asking is because I got stuck and you gotta know your limits. Now Madigan gave me a great idea that a can try to implement and learn more.

I thought it would be possible to give them some kind of "collide" property just like bodies, but I guess I will need to code the whole interaction.

Troche answered 20/9, 2023 at 12:17 Comment(0)
W
0

Troche thanks for the validation. i use knowledge from vain/pointless projects all the time.
i do appreciate custom UI behaviour. altering how the player interacts with a menu can make your game subconsciously memorable. i didn't love Metroid Prime 2, but the main menu in that game still sticks in my head, simply because it was weird.
do be careful with that, it can also cause your game to suck..

Wooley answered 20/9, 2023 at 13:53 Comment(0)
W
0

Troche A quick and dirty custom implementation of rectangular Separating Axis Theorem should do the trick. It's been a while since I implemented one of those, so challenge accepted πŸ˜ƒ

main.gd:

extends Node2D

func separate(window1, window2, bias = .5):
	var r1 = window1.get_rect()
	var r2 = window2.get_rect()

	var ri = r1.intersection(r2)	
	if not ri.has_area():
		return

	var displace = Vector2.ZERO
	var o1 = r1.end - r2.position
	var o2 = r2.end - r1.position

	if(ri.size.x < ri.size.y):
		if abs(o1.x) < abs(o2.x):
			displace.x += o1.x
		else:
			displace.x -= o2.x	
	else:
		if abs(o1.y) < abs(o2.y):
			displace.y += o1.y
		else:
			displace.y -= o2.y	
	
	window2.position += displace * bias
	window1.position -= displace * (1-bias)

func _process(delta):
	for w1 in get_children():
		for w2 in get_children():
			if w1 != w2:
				var bias = .5
				if w1.dragging: 
					bias = 1
				elif w2.dragging:
					bias = 0
				separate(w1, w2, bias)

window.gd:

extends ColorRect

var dragging = false

func _gui_input(event):
	if event is InputEventMouseButton:
		if event.is_pressed():
			dragging = true
			modulate = Color(1.0, 0.0, 0.0, 1.0)

	if event is InputEventMouseMotion and dragging:
		position += event.relative

func _input(event):
	if event is InputEventMouseButton and not event.is_pressed():
		dragging = false
		modulate = Color(1.0, 1.0, 1.0, 1.0)

Note that running it once cannot guarantee cascaded separation in very crowded situations. However we run it every frame and it eventually sorts itself out throughout several frames, which is mostly unnoticeable.

You homework is to adapt it for multiple dragging windows, and optimize for performance πŸ˜‰

Wallachia answered 20/9, 2023 at 15:3 Comment(0)
T
0

Wallachia Wow that actually looks amazing, great work! I understand part of what you did there, but another part of the code is a mystery to me. I will spend the day studying it, thank you so much!

Troche answered 20/9, 2023 at 18:37 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.