Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by BilboStabbins · Apr 02, 2013 at 02:19 AM · raycastdragscreenspaceboundary

Help changing plane.Raycast dragging script

I have a script which was initially written to drag the Player around the screen in the X-Y plane. It basically creates a Plane in front of the camera (normals facing away) with the Player on other side of it and records the point of intersection of a plane.Raycast into the plane. It then converts this local intersection position to World space and moves the Player there.

However, what I would like to do now is to only move the Player to the mouse position when he is clicked on and dragged there, rather than just clicking the mouse somewhere on the screen/plane. I have tried to include a further Physics.Raycast if- that checks if the Player collider was hit and then moves him to the position. The problem is that whilst dragging the Player, if the mouse moves off of him then he will stop moving. This makes sense as the ray knows nothing about holding a mouse button down.

Also, one of the reasons I used a plane.Raycast is so that I could create screen boundaries. These can be seen in the form of offsets on the Mathf.clamp functions near the bottom.

Any suggestions on how I could do this would be great.

The script is below.

 void FixedUpdate()
     {
         if (movementEnabled)
         {
             // Variable to represent the camera
             Camera myCamera = Camera.main;
 
             // Create a plane with normal in the opposite direction to where the Main Camera is facing,          and with a 
             // fixed position which is set distance from the camera.
             Plane plane = new Plane(-myCamera.transform.forward, myCamera.transform.position + myCamera.transform.forward * DesiredPlayerDistanceFromCam);
 
             // Create a ray to hold the information when the mouse is clicked on the screen. 
             // Returns a ray going from camera through a screen point.
             // Resulting ray is in world space, starting on the near plane of the camera and going through position's
             // (x,y) pixel coordinates on the screen (position.z is ignored)
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 
             float dist = DesiredPlayerDistanceFromCam;
 
             // If mouse LMB is pressed (or held down)..
             if (Input.GetButton("Fire1"))
             {
                 // If the ray intersects the plane..
                 if (plane.Raycast(ray, out dist))
                 {
                     // Find the position on the plane and store in variable pos
                     Vector3 pos = ray.GetPoint(dist);
 
                     RaycastHit hit;
 
                     if (Physics.Raycast(ray, out hit, 100))
                     {
                         if (hit.collider.tag == "Player_Main_Collider")
                         {
                             PlayerTouched = true;
 
                             pos2 = new Vector3(pos.x, pos.y - mouseYoffset, pos.z);
 
                             // Move the Player to the position that was clicked buy the user on the plane
                             Player.position = Vector3.Lerp(Player.position, pos2, Time.deltaTime * Smooth);
 
                             // Find the Player's Local position relative to the camera.
                             // This operation is unaffected by scale.
                             Vector3 localPos = myCamera.transform.InverseTransformPoint(Player.position);
 
                             //              Debug.Log("localPos = " + localPos);
 
                             // Find the World space position of the left-bottom boundary of the viewport
                             leftBottom = myCamera.ViewportToWorldPoint(new Vector3(0, 0, DesiredPlayerDistanceFromCam));
                             //                Debug.Log("leftBottom = " + leftBottom);
 
                             // Find the World space position of the right-top of the viewport
                             rightTop = myCamera.ViewportToWorldPoint(new Vector3(1, 1, DesiredPlayerDistanceFromCam));
                             //                Debug.Log("rightTop = " + rightTop);
 
                             // Get the Local position of the leftBottom point in World Space
                             leftBottom = myCamera.transform.InverseTransformPoint(leftBottom);
 
                             // Get the Local position of the rightTop point in World Space
                             rightTop = myCamera.transform.InverseTransformPoint(rightTop);
                             //        Debug.Log("rightTop = " + rightTop);
 
 
                             //Player.position = pos2;
 
                             Vector3 pos2Local = myCamera.transform.InverseTransformPoint(pos2);
 
                             // Define the bounds to clamp for the X and Y axes
                             float x = Mathf.Clamp(localPos.x, leftBottom.x + leftRightOffset, rightTop.x - leftRightOffset);
                             float y = Mathf.Clamp(localPos.y, leftBottom.y + bottomOffset, rightTop.y - topOffset);
 
                             // Move the Player to coordinates defined by the Mathf.Clamp functions, converting them
                             // back into World Space coordinates first
                             //                Player.position = myCamera.transform.TransformPoint(new Vector3(x, y, localPos.z));
 
 
                             Player.position = myCamera.transform.TransformPoint(new Vector3(x, y, localPos.z));
                         }
                         else
                             PlayerTouched = false;
                     }
                         
                 } 
 
             } 
 
         }
 
     } 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by robertbu · Apr 02, 2013 at 05:39 AM

Consider capturing three different states: mouse down, mouse dragging, and mouse up. You only do the raycast in the mouse down setting a boolean to true if your raycast hits. So you have something like:

         if (Input.GetMouseButtonDown(0)) {
             RaycastHit hit;

             if (Physics.Raycast(ray, out hit, 100) && (hit.collider.tag == "Player_Main_Collider")) {
                 isDragging = true;
             }
         }
         
         if (Input.GetMouseButtonUp (0)) {
             isDragging = false;
         }
 
         // If mouse LMB is pressed (or held down)..
         if (Input.GetMouseButton(0) && isDragging)
         {
            // Your dragging code goes here
         }

A few other points:

  • I don't see any reason this code should be in FixedUpdate(). Instead place it in Update().

  • While your Plane code will work, a simpler method of doing these calculations is to use Camera.ScreenToWorldPoint() and Camera.ViewportToWorldPoint(). The 'Z' value of the Vector3 passed to these two functions is the distance in front of the camera.

  • If DesiredPlayerDistanceFromCam is a constant, and if the camera does not move (or seldom moves), you are doing a lot of calculation in every frame that could be done upfront.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Click&Drag Misterious Disappearing! 1 Answer

c# Object Drag ScreenToWorldPoint Limits 0 Answers

Override Sorting disables Blocks Raycasts 1 Answer

GameObject Moving Slow when drag with hand 0 Answers

Touch with 2 fingers makes conflict with 2 different components. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges