- Home /
Detect Collisions with Object following Mouse Movement
Hi Everyone,
Have a script that makes a block follow by mouse movement which is working just fine. However, this allows the held object to move directly through other objects. Apparently using either heldBlock.rigidbody.MovePosition() or setting heldBlock.transform.position overrides any sort of collision detection?
So I'm wondering... is there a way to have both of these things at once? Following the mouse while still performing collisions (which would then halt the object's movement)? Or is there a different way to manipulate my object to make this work?
I've been looking all over the place, but I couldn't find this specific question... sorry if it's a re-post.
Thanks in advance, and have a super fantastic day! -Matt
Answer by FireHaze · Mar 26, 2013 at 10:18 PM
Hello there, try to set an empty gameobject with an spring joint, set the rigidbody it adds automatically to your empty gameobject to be kinematic, after that you will set your block's rigidbody as target in the spring joint properties, and finally you add and mod your current block's script to handle the empty gameobject instead of directly move the block, as a result the block will follow by forces your empty gameobject colliding against stuff in the way, you just have to play a bit with the spring, damp forces and drag to set it properly. Give it a try :)
Thanks for the reply! This sounds like a great idea, let me give it a shot and I'll get back to you! =D
Is there a simple way to make the object actually snap to the mouse location? I don't want it bouncing about, but I've made the values as high/low as I could.... for example, I set max distance to zero, damper to 1e-5, and Spring to 10000.
Should I try hinge joint ins$$anonymous$$d? It's a rather odd scenario because I want to control the movement of the object entirely with the mouse, yet I still want some collision detection to occur (which ideally would then prevent the object from following the mouse).
umm, you should try to mess around with another property, I didn´t specify in my first answer what I meant with "drag", but you should try to increase the drag value for your "controlled" rigidbody (not the one that has the spring), in this case that one should be the block's rigidbody, try with 100, 1000, etc... It will avoid your object from being bouncing and moving like a moon around a planet lol.
The only problem I found with this method that I am still trying to solve is to control the rotation of the controlled gameobject, you can always freeze it or set a high angular drag to avoid it from spinning, but if you freeze it you won´t be able to handle rotation by code. So if you find a better alternative to handle an object using collisions and physics (in my case a tennis racket), please let me know :) for now try that, I think it will work just fine.
The drag property is exactly what I needed! I'm still working with it, trying to get collisions to work exactly as I intend, but I think I'll get it soon with your suggestion! As far as rotation goes, I have it easy because I don't want my pieces to rotate, so I just froze the rotation values. I think you can do that and still change the values in code, like this: yourObj.transform.Rotate(new Vector3(0.0f,90.0f,0.0f));
Answer by cello_91 · May 08 at 11:30 AM
This is a super old thread, but maybe someone wants to do the same..
I found a better way than the spring joint mentioned here.
This thread
https://forum.unity.com/threads/collision-detection-while-dragging-object.182493/
links to this video
https://www.youtube.com/watch?v=ZfjVR-0ZFHU
which explains a solution.
If you don't want to watch or read too much:
Basically you should stop setting the transform, because this cancels physics!
This is all you need:
private void Update()
{
rb.velocity = (getWorldPosition() - transform.position) * followSpeed;
}
private Vector3 getWorldPosition()
{
lastMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
lastMousePos.z = 0;
return lastMousePos - offset;
}
private void OnMouseDown()
{
lastMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
lastMousePos.z = 0;
offset = lastMousePos - transform.localPosition;
}