Snap to closest object BGE

So I’ve started using Blender Game Engine again to try to make an inventory system mostly out of Logic bricks :open_mouth:
So far, it is going very good!

But when I tried to make the items snap to the slots when placing it, I came to a halt…

I have no idea how to do it! I’ve tried giving it a Constraint when it collides with one of the slots but that gets EXTREMELY complex extremely fast, and doesn’t even work some times!

Basically what I want it to do, is to make the item snap to the closest thing to it I am desperate for advice from anyone! Please help, and keep in mind that I’m trying to use as less as possible scripting!

First off, i recommend you use logic bricks for much simpler things than making an inventory system which just isn’t going to be wieldly in the long run.

using logic bricks to do this, you might want to try
object icon controller —> track to icon slot with track to actuator

i dont think you can do anything with distance with logic bricks without python

but i dont use logic bricks very often outside of what can’t be done with the code so i am not sure what the best option is solely with bricks

you should have a python script, and the script should say something like

---- write this part in a script with an always sensor ticing all the time

---- unclick is a mouse sensor

if unclick.positive: #possibly use negative tic sense on the logic brick sensor to do this
tab-> module.snap_to(icon_slot)

---- write this part in a module called inventory_module with an always sensor that tics one time

---- it is your ‘library of functions’

---- in the controller write inventory_module.init

---- write this function to satisfy the necessary call of a function. it is called in the controller

---- when you write inventory_module.init <<—

def init():
pass # this just does nothing for the sake of having a function called on the controller

---- replace object 1 with item_icon_object , replace object 2 with icon_slot_object

item_icon_object = logic.getScene()[whatever scene index here: 0,1,2 etc].objects[‘name of your item icon’]

icon_slot_object = ditto but whatever the name of the slot is

def snap_to(object1,object2)
tab->distance = object1.getDistanceTo(object2)
tab->if distance <= 4: #the hover distance
tab->tab->object1.worldposition = object2.worldPosition #the icon will go right to the slot position

if you know how to implement the above idea into a python module and have your script call the module function, its gonna be great

take a few weeks or months practicing using python and your bge life is going to skyrocket if you stick to it if you don’t already know it

I agree with this. Use logic bricks for simple things.
It’s better to use python. You’ll find it more organized and cleaner/you’ll be able to get things to work exactly how you want to if you learn python.

EDIT:

It’s getSceneList() @ 100h.

Looking at the sole “snapping” it is a pretty simple but dynamic operation.

Simple:
A) find closest object (out of ?)
B) set position of (?) to the result of A)

Dynamic:

  • You do not know the closest object before the BGE runs (you can’t hard-code it with the GUI).

You see there is are question marks.

A1) -> any object or a set of objects? How to differentiate between findable objects?Example: by property name
B1) -> what is the object to “snap”?

Overall this sounds like you try a drag&drop operation. I’m not sure if a “find closest” is really sufficient.

Could it be you want to drag an “item” over a “slot” and drop it there?
item = an object that represents the ontent of a slot
slot = a place that can hold items

Yes exactly. I want the item to line up perfectly with the slot it is placed within.

in that case the mouse cursor should be over the slot.

This means you can use a mouse over any sensor (with filter on “slot” + each slot needs such a property).

The sensor gives you the target object:


def demonstrate(controller):
    sensor = controller.sensors["Mouse over slot"] # note the name!
    if sensor.positive:
        target = sensor.hitObject
        print("target is", target)

Now your object to snap.

Typically it is the one you started dragging with. But I do not know how you want to do that. So here is a very simple example:


def beginDrag(controller):
    sensor = controller.sensors["Mouse over item"] # note the name!
    if sensor.positive:
        draggedObject = sensor.hitObject

You see it looks pretty much the same as the other code.
The difference is:

  • A) the sensor to ask (one senses slots and one senses items)
  • B) the owner of the controller (it could be the same)

I do not want to go into more details. Please have a look at:

Prof. Monster’s Drag&Drop Support

Thank you Monster! This helped a lot!