#preview texture behaving strangely

40 messages · Page 1 of 1 (latest)

turbid dune
#

Hello! I have an inventory and a hotbar. I have a working script to drag things between the two and add objects to the main inventory from the world. For some reason though the preview for the item being dragged doesn't follow the mouse properly. I followed a tutorial initally to learn how to make things draggable, so I went back and recreated that project exactly and it works perfectly. The preview follows the mouse normally. I can't see what went wrong with the version in my game. The tutorial has a TextureRect as the base and mine is a panel container, but I've checked and rechecked and it should still be fine. Here's a video of what's happening. https://1drv.ms/u/s!AhFDhdExpRP1hOxijqXB8DfItEsY0w?e=vpQ6T8

#

This is my script

||extends PanelContainer
class_name Slot

@onready var texture_rect = $TextureRect

var filled : bool = false

func _get_drag_data(at_position):
set_drag_preview(get_preview())
return texture_rect

func _can_drop_data(at_position, data):
return data is TextureRect

func _drop_data(at_position, data):
var temp = texture_rect.property
texture_rect.property = data.property
data.property = temp

func get_preview():
var preview_texture = TextureRect.new()

preview_texture.texture = texture_rect.texture

var preview = Control.new()
preview.add_child(preview_texture)

return preview

func set_property(data):
texture_rect.property = data

if data["TEXTURE"] == null:
    filled = false
else:
    filled = true||

This is the script that works properly, though it's not connected to the inventory.

||extends TextureRect

@export var slot_type: int = 0

@onready var property: Dictionary = {"TEXTURE": texture,
"SLOT_TYPE": slot_type}:
set(value):
property = value

    texture = property["TEXTURE"]
    slot_type = property["SLOT_TYPE"]

func _get_drag_data(at_position):

var preview_texture = TextureRect.new()

preview_texture.texture = texture
preview_texture.expand_mode = 1
preview_texture.size = Vector2(30,30)

var preview = Control.new()
preview.add_child(preview_texture)

set_drag_preview(preview)
texture = null

return preview_texture.texture

func _can_drop_data(at_position, data):
return data is Texture2D

func _drop_data(at_position, data):
texture = data||

echo kite
#

May I see the set_drag_preview() function?

#

I would like to know what node preview becomes child of.

#

And if you set its position at any point.

#

Probably has something to do with local vs global position, or children inheriting the position of their parent

#

@turbid dune

turbid dune
#

@echo kite This is what I have to determine what the preview is
`func get_preview():
var preview_texture = TextureRect.new()

preview_texture.texture = texture_rect.texture

var preview = Control.new()
preview.add_child(preview_texture)

return preview`
echo kite
#

preview_texture is added as child of preview, but what is preview added as child of?
This is done in the set_drag_preview() function, I assume. Which is not shown.

turbid dune
#

Ah. That's the entirety of the script. So perhaps that's what's happening. When the game is running the new Control node is a child of the Inventory Control node.

turbid dune
echo kite
#
func _get_drag_data(at_position):
    set_drag_preview(get_preview())
    return texture_rect

You can see set_drag_preview() is being called here. But that function is not shown which is confusing.

#

To lock the texture to the mouse, are you:

  • Changing its position
  • Adding it as child of a certain node and then changing the position of that node to follow the mouse
  • Both?
#

When the game is running the new Control node is a child of the Inventory Control node.
What causes it to become child of the Inventory Control node? It must happen in code somewhere.

turbid dune
#

Sorry. I'm trying to see where it's happening.

#

And yeah, I don't see the set_drag_preview function anywhere. How do I have no memory of doing this 🤦‍♀️

echo kite
#

I realized set_drag_preview() is a built-in function of PanelContainer - sorry for the confusion

turbid dune
#

ohhh okay

echo kite
#

But still, that new Control node named preview must be being added as child of something, somewhere

#

And that's where the problem lies I think

#

Mm I see

turbid dune
#

Okay, slight update. The preview only works right with the hot bar. If I try to drag something from the regular inventory is does the weird position thing. With both the original slot and the one I redid.

#

So, it's got to be something with the Inventory set up right? Both it and the hot bar have instances of the same slot scene

#

The hot bar Control nodes are appearing as children on the Hotbar Control node

echo kite
#

Reading into set_drag_preview() a bit more, it does some neat stuff I'm not familiar with. Doesn't add anything to the current scene's tree... the new node is on some upper level. (Child of Viewport?)

I'm not sure why set_drag_preview() would be giving you results like this, assuming it works with global_position...

#

Maybe it works with local position? Meaning you'd have to call it on a control node that is at global position (0, 0)...

turbid dune
#

I think it is though

echo kite
#

Not sure then gddeadinside Thanks for bearing with me anyway
You could try a different method if you'd like (not using set_drag_preview())
The idea is to make an invisible Node2D/Control that's child of main node, which follows the mouse at all times.
And you add the TextureRect as child of that node during the drag.

#

Otherwise you can upload your project and I'll mess around with it to see if I can get set_drag_preview() working

turbid dune
#

Okay, I think I follow that, and honestly thank you for bearing with me. I might start with just redoing the whole Inventory bit. Sometimes I get so tangled up in a problem I can't find the end of the string again y'know?

echo kite
turbid dune
echo kite
#

Okay so if I move Inventory into the CanvasLayer...
then in Player.gd change

@onready var inv_display = $Inventory

to

@onready var inv_display = $UI/Inventory

and then reposition the Inventory in the center of the blue square ... it works

#

If you want to use set_drag_preview() you will need to make your Inventory part of a CanvasLayer.
Because if the inventory is a child of the Player:

  • The camera is zoomed in on the player which screws up the coordinates used in set_drag_preview()
  • Its position will change with the Player's position , which can also mess with the coordinates
#

You can scale it up here and it still appears to work (although the drag preview is small)

#

@turbid dune

turbid dune
#

Thank you! That does make sense

echo kite
#

gdyipee np good luck
I see you've dove in and explored a lot of the engine's features, good work so far, it's not as messy as you might think!