DragAndDrop Physics based object Mover / Pick up system

Ok,

this should be about as easy to use as possible

just append the object GrabIt into your blend, and set the range,

now when the camera is aimed at a object with the property ‘Phys’ that is dynamic, or rigid body,

hold left click to pick up a object,

(best when combined with a mouse look actuator or script)

Attachments

DragDropGrabAndMove.blend (465 KB)

1 Like

Very, very cool;)

So the range thing works that you need to be near it to grab it. Though after grabbing it moves it away for a certain distance which is a little weird. You might like to fix that. Also changing the range doesn´t seem to change it.

Edit:
Ok I found out how to adjust it:
In line 42 by changing the last number. But the distance from the camera should depend of the size of the object. Also it seems to slow them down, the smaller you set the number.

Edit2:
Ok cool just found out that the system is dependent on the mass of the grabbed object. Very neat! Also I changed the amount of force applied in line 44 to a multiplier of 30 instead of 10.

Line 41 - 46:

#Move The Object
             offset = cam.worldPosition+(cam.worldOrientation*Vector([0,0,-2]))
             V=offset-own['Grabbed'].worldPosition
             own['Grabbed'].applyForce((V)*30*V.magnitude,0)
             own['Grabbed'].applyForce((0,0,9.8*own['Grabbed'].mass),0)
             own['Grabbed'].worldLinearVelocity*=.9  

Set up like this it works really nice for me now. Thanks a lot for the template!

Used it in my Survival Game. Great work!

1 Like

Absolutely amazing, this could be used for so many things!

Yeah it could be used to make Portal to Fallout 3 remakes in Blender game engine.

I actually made something similar some time ago except that it doesn’t snap objects to a point in front of a camera, it moves them relative to view vector. Run it on any object in script mode attached it to a positive triggering always sensor and try dragging around objects. Haven’t tested with a moving camera.


from bge import logic, render, events
from mathutils import Vector


mouse = logic.mouse
JUST_ACTIVATED = logic.KX_INPUT_JUST_ACTIVATED
ACTIVE = logic.KX_INPUT_ACTIVE
sc = logic.getCurrentScene()
obs = sc.objects
cam = sc.active_camera


def isTargetted():
    cam = sc.active_camera
    ray = cam.getScreenRay(logic.mouse.position[0], logic.mouse.position[1],90000, "")
    return ray
        
    
def mousePosition(z):
    
    camera = logic.getCurrentScene().active_camera
    vec = cam.getScreenVect(*logic.mouse.position)
    camPos = cam.worldPosition
    projectedPos = (camPos - vec)*z
    
    return Vector(projectedPos)




def mouseDrag(cont):
  if not "ray" in cont.owner:
    cont.owner["ray"] = None
    cont.owner["offset"] = []
    cont.owner["dist"] = 0
    
  if mouse.events[events.LEFTMOUSE] == JUST_ACTIVATED:
          cont.owner["ray"] = isTargetted()
          if cont.owner["ray"]:
            obs["Armature"]["chain"].selectActive(obs["Armature"], cont.owner["ray"]["bone"])
            cont.owner["dist"] = cont.owner["ray"].getDistanceTo(sc.active_camera)
            pos = mousePosition(cont.owner["dist"])
            cont.owner["offset"] = Vector(pos-cont.owner["ray"].worldPosition.copy())
  elif mouse.events[events.LEFTMOUSE] == ACTIVE:
      if cont.owner["ray"]:
        cont.owner["ray"].worldPosition = mousePosition(cont.owner["dist"])-cont.owner["offset"]
        
        for i in range(obs["Armature"]["chain"].steps):
            obs["Armature"]["chain"].update()
        
        
    
mouseDrag(logic.getCurrentController())    

This is actually a great resource 5 Stars for this. I keep coming back to this script haha its so versatile !

Jackii, I did somthing similar in #Wrectified

however I found the best method was to add a empty on grabbing at the mouse.hitPosition, and then apply forces to move the object to put that point under the cursor,

I will add a demo of this shortly.

Thanks everyone, I am trying really hard to put out useful resources based on what I have learned via wrectified.

i hate to necro post like this, but this is exactly what im looking for. i want to make draggable ragdoll but im not sure how to use this for it, im imagining i parent and empty to the points i want to drag from on the characters ragdoll armature yes?

How long will it be before the survival game videogame is ready?

Hi, im using your script and i would like to add the following fonction:
when the grabbed object is blocked by another thing (object, floor/wall friction,…) i would like it to drop (ungrab) at a certain distance from the player.

can you help please ?

sure thing

just cast a ray from the player physics hitbox to the picked up object,
if the ray is obstructed, drop the object

thanks for the quick response.
i just started using python and im quite noob at it
can you explain more in details?

I will have to look into exactly how I coded this,

but we don’t want the ray to detect the player physics hitbox as an obstruction so we have the player hitbox cast a ray at the targeted object

It’s been a while but I will code it tonight into this same demo for you
(I am but a lowely mobile phone peasant until I get off work)

Ok, thank you very much :smiley:

Learned quite a bit since I initially coded this so I recoded it from scratch to be less spammy and be ‘timed’
(so ‘dropping’ can’t be instantly recovered etc.)

This should work better and uses a ray cast from the camera instead of mouse_over,



iimport bge



def main():


    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    MouseClick = cont.sensors['Mouse']
    TimeNotZ = cont.sensors['Time']
    Cam=own.scene.objects['Camera']
    
    #Set this to your players physics hitBox
    #RayCaster = own.scene.objects['PlayerHitBoxName']
    
    
    RayCaster  = Cam
    
    if own['Clock']>=1:
        own['Clock']-=1
        
    
    
    
    if 'Lifting' not in own:
        #if Clock is zero and mouse is clicked cast ray to attempt to choose target
        if MouseClick.positive and not TimeNotZ.positive:
            
            own['Clock']=30
            End = Cam.worldPosition+(Cam.worldOrientation.col[2]*-own['Range'])
            Start = Cam.worldPosition
            
            
            
            #Debug ray
            bge.render.drawLine(End,Start,(0,1,0))
            
            Ray = RayCaster.rayCast(End,Start,0,own['Ident'],0,0,0)
            
            if Ray[0]:
                print('hit')
                
                own['Lifting']=Ray[0]
                own['Clock']=-30
                #picking up object
                
    else:
        if own['Clock']<=-2:
            own['Clock']+=1
            
        
            
        
        
        Position = Cam.worldPosition+(Cam.worldOrientation.col[2]*-own['DistanceOut'])
        
        #Apply lifting force
        V=Position-own['Lifting'].worldPosition
        own['Lifting'].applyForce((V)*10*V.magnitude,0)
        own['Lifting'].applyForce((0,0,9.8*own['Lifting'].mass),0)
        own['Lifting'].worldLinearVelocity*=.9                 
        
        
        #Drop if obstructed
        
        End = own['Lifting'].worldPosition
        Start = Cam.worldPosition
        if own['Clock']==-1:
            ray = RayCaster.rayCast(End,Start,0,'',0,0,0)
            if ray[0]:
                if ray[0]!=own['Lifting']:
                    own['Clock']=60
                    del own['Lifting']
                    
            #Drop if not holding mouse click        
            if not MouseClick.positive:
                own['Clock']=30
                if 'Lifting' in own:
                    del own['Lifting']    
        
                        
        
    
        
   


main()





Attachments

DragAndDrop_Update.blend (108 KB)

thank you very much it works well :smiley: but when i grab something its moove far away from the camera (same for the first version but i have take the set up of “CG-sky”)

check out the properties in the grab and drop object

distanceOut and Range

Hannnnn Thank you :eek::smiley: you are the boss