Pick up, drop, rotate, and zoom a rigidbody gameObject

Hey guys, so I have been stuck on this problem for a while now. I have a still camera looking down on a map (Birds eye view / top-down) and there are object in this map (chair, table, desk) that are rigidbodies. I would like it so that when you click on one of these objects they get picked up (or stuck) to the mouse and can be moved around the room. This would be great but if you could I would also like it so that using the mouse wheel the object moves up or down. Then using ‘r’ or any button you can rotate that object on its ‘y’ axis, and every time ‘r’ is pressed it is rotated 90 degrees.
Sorry that I don’t have code, I got frustrated and deleted it all. Any help is appreciated, sorry if it is confusing or long. Have a good day.

NOTE: I mainly work in Javascript so that would be recommended, but if you know how to do it in another language I would enjoy that as well.

Sorry to hear you’re frustrated. That’s a fact of life in game development! Shrug it off, learn from your mistakes and move on!

I don’t want to write the entire script for you, but I can describe the steps and give you some code that will hopefully point you in the right direction :slight_smile:

Please note I usually use C# so my JS might not be 100% on-point. Anybody, please correct any mistakes (community edit is on). I also didn’t test all of this, so it might not be totally correct.

In your script’s Update() function:

  1. If the mouse is down and you don’t have anything selected, perform a ray cast from where the camera is to where the mouse click is and if there’s a hit, save it to some var you have in your script’s global scope (can be seen/accessed outside of your Update() function), let’s call it grabbed (so somewhere outside of Update() you would have something like var grabbed : GameObject).

    if(Input.GetMouseButton(0) && !grabbed){
        // grab any raycast hit
        var hit : RaycastHit;
        var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, hit)){
            // You might want to do some sort of filtering here so you don't grab things you don't want to, such as the ground (a different topic altogether)
            grabbed = hit.collider.gameObject;
        } else {
            grabbed = null;
        }
    } else {
        // set grabbed to null so we know we're not holding onto anything
        grabbed = null;
    }
    
  2. Now that you know which object you’re grabbing, you can manipulate its transform as you please, still in the Update() function after step 1

    if(grabbed){
         // my guess is that you're also going to want to stop the object from moving/rotating on its own while it's grabbed
         grabbed.rigidbody.velocity = Vector3.zero;
         grabbed.rigidbody.angularVelocity = Vector3.zero;
    
    
        /* rotate by 90 degrees */
        if(Input.GetKeyDown(KeyCode.R)){
            var euler = grabbed.transform.rotation.eulerAngles;
            euler.y += 90.0f;
            grabbed.transform.rotation = Quaternion.Euler(euler);
        }
    
    
         /* move by mouse movement */
         // NOTE: These have to be defined in Edit -> Project Settings -> Input as an axes, should be there by default.
         float scroll = Input.GetAxis("Mouse ScrollWheel");
         float mouseDX = Input.GetAxis("Mouse X");
         float mouseDY = Input.GetAxis("Mouse Y");
        
         // NOTE: This will probably move the object by WAY too much.
         // You will need to make these numbers smaller
         // like, say, divide them by 2 or something; test to figure out what works best for your scenario
         // If it moves on the wrong axes, try mixing these around or negating them.
         var trans = Vector3(mouseDX, scroll, mouseDY);
    
         // Rotate translation to correlate to camera
         // Not sure if these next two lines work in JS, let me know
         trans = Camera.main.transform.rotation * trans;
         grabbed.transform.position += trans;
     }