- Home /
Drag and drop ray-casting conundrum!
Howdy, folks.
So, I'm attempting get my player object to be drag and droppable via the mouse. I'm doing this by allowing the object to translate based on a certain ratio between the mouse's position on screen and the 3d space. When I run the script below it begins to work...but then crashes with a NullReferenceException error pointing to the line that translates the object in the script. It crashes when I move only a little ways away from the object's origin...but until then it appears to work fine. Could it be because the object I'm trying to "drag" around has a rigidbody on it, and rigidbodies don't like translation? I'm really kind of miffed as to why this is happening. If you can figure out this spooky mystery, I will proudly present you with the key to the city in front of a crowd of cheering citizens...
Thanks for your help, in advance!
--Simon
var pickedUpPlayer = false;
var originalMouseX = 0.000; var originalMouseY = 0.000; var deltaMouseX = 0.000; var deltaMouseY = 0.000; var screenRatio = 100.000;
function FixedUpdate () { var hitOrigin : RaycastHit; var rayOrigin = Camera.main.ScreenPointToRay (Input.mousePosition);
if ( Physics.Raycast( rayOrigin, hitOrigin, 100 ) && !pickedUpPlayer)
{
//detects if the player has been clicked on.
if (Input.GetMouseButton(0))
{
//if the user has clicked on the player tagged object, they can start to move him or her around via the next if statement...
//so we need to know at what point on the screen the player has clicked, such that in the next if statement we can determine
//the change in mouse position, and translate the player's transform accordingly.
if ( hitOrigin.collider.gameObject.renderer && hitOrigin.collider.gameObject.tag == "Player")
{
pickedUpPlayer = true;
originalMouseX = Input.mousePosition.x;
originalMouseY = Input.mousePosition.y;
}
}
}
//allows you to drag the player according to where the mouse is on the screen. The game knows that the distance the mouse moves onscreen
//coordinates to a certain distance that it is moving in the 3d space. since there is no z coordinate changed, this works.
if (pickedUpPlayer)
{
deltaMouseX = Mathf.Abs(Input.mousePosition.x) - Mathf.Abs(originalMouseX);
deltaMouseY = Mathf.Abs(Input.mousePosition.y) - Mathf.Abs(originalMouseY);
print("Delta X: " + deltaMouseX + ", Delta Y: " + deltaMouseY);
hitOrigin.collider.gameObject.transform.Translate(deltaMouseX / screenRatio, deltaMouseY / screenRatio, 0);
}
if (!Input.GetMouseButton(0) && pickedUpPlayer)
{
pickedUpPlayer = false;
print("Dropped the player");
}
}
Order expressions such that cheapest is left of &&, not right of, as it short-circuits.
Answer by Waz · Aug 23, 2011 at 11:52 AM
Your code relies on the ray keeping a bead on the player collider, otherwise it will crash. Currently it is ray casting every frame even after you've picked up the player, and that can't be right. It then keeps using that hit to try to keep knowing what to translate, but it could be anything, or nothing in subsequent frames. You're also translating it by an amount that keeps increasing.
Basically, read the code out aloud to yourself in high-level terms and you'll see it doesn't really implement a logical attack on the task.
Keep a script variable that is the object being dragged:
var dragged : Transform;
Start from there and you should make it.
Thanks for looking it over, Warwick. I understand what you're saying, and I'll try again...I guess I thought that it wouldn't matter if the ray was still hitting the player, as long as the...OH, DUH. Yeah, thanks. I'll see what I can get up to in the next few $$anonymous$$utes. To answer your questions:
1) I always try pushing the format code button, but it seems to never format everything correctly. $$anonymous$$aybe it's some formatting thing I'm doing in my code that's disrupting it? Not sure.
2) Good to know about short-circuiting. I had always wondered if that's the way it worked.
3) Um...well...at the moment, I am a mayor of the totally lame city of Phrenology-town. I assume you don't ever go there intentionally (if at all :), but the next time you're in, I'll have the key sent up to your hotel room.
Ah, yes, so I've fixed the crashing problem. Now I just have to fix the cumulative speed issue. Thanks for your clear assessment and giving me an enticing hint on how to do it myself.
Cheers.
S
Feel free to edit your question with your new code. Otherwise, my tip would be to not try to use a delta but rather a new absolute position. Check the docs of ScreenToWorldPoint.
Your answer
Follow this Question
Related Questions
Pick up, drop, rotate, and zoom a rigidbody gameObject 2 Answers
How do I mimic dragging and dropping a FBX to the hierarchy window with an editor script? C# 1 Answer
Collision objects when I drag and drop them by touch (Unity Android) 0 Answers
How to Stop a Game Object from Passing through a Collider while it's being Dragged? 3 Answers
Drag Rigidbody 2 Answers