Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 Jason87 · Apr 27, 2014 at 11:39 PM · transformpositiononmousedownonmouse

Input.MousePosition creating weird Z axis object translation

Hello All! I have been messing around with getting an object to follow my mouse position on mouse down. I have this working alongside input.touch as well, but for the sake for debugging, I would like to be able to use the mouse as well to check values when playing to ensure it is working as desired. There is a really odd thing that happens when I use the code below that I can't put my finger on. When i click on the object, it moves correctly in the x and y axis, but for some reason it jumps forward a specific number (~9.7) in the z. I have went over my code and I can't find anything that would influence the object in the z axis....and I'm about to go insane :-)

I really appreciate anybody who takes the time out to scan the code below to find any possible reasons why an object would be translated in the Z. Thank you very much in advance!

attached to main camera

 sing System.Security.Cryptography.X509Certificates;
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class TouchManager : MonoBehaviour
 {
 
     public LayerMask touchInputMask;
     private RaycastHit hit;
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () 
     {
 #if UNITY_EDITOR
 
         if (Input.GetMouseButton(0) || Input.GetMouseButtonUp(0) || Input.GetMouseButtonDown(0))
         {
             Ray ray = camera.ScreenPointToRay(Input.mousePosition);
             
             
             
 
                 if (Physics.Raycast(ray, out hit, touchInputMask))  //if the raycast hits an objects collider within the layermask
                 {
                     GameObject recipient = hit.transform.gameObject;
 
                     if (Input.GetMouseButtonDown(0))    //if a finger has just been put down on the object
                     {
                         //mark the object as selected
                         //set position of object to touch.position
 
                         Debug.Log("Get Mouse Button Down called!!");
 
                         float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
 
                         Vector3 position = camera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0    ));
 
                         hit.transform.position = position;
 
                         //recipient.SendMessage("OnTouchDown", position, SendMessageOptions.DontRequireReceiver);
                     }
 
                  
                     /*if (Input.GetMouseButtonUp(0))    //if a finger has just been put down on the object
                     {
                         //mark the object as not selected
                         //make sure the object continues in the direction it was headed at the same speed when the finger is lifted off the screen
 
                         recipient.SendMessage("OnTouchUp", SendMessageOptions.DontRequireReceiver);
                     }
 
                     if (Input.GetMouseButton(0))    //if a finger has just been put down on the object
                     {
                         recipient.SendMessage("OnTouchStay", Input.mousePosition, SendMessageOptions.DontRequireReceiver);
                     }*/
                 }
                
             }
 
 #endif
         if (Input.touchCount > 0)
         {
             foreach (Touch touch in Input.touches)  //for every screen touch to the screen
             {
                 Ray ray = Camera.main.ScreenPointToRay(touch.position);
                 RaycastHit hit;
 
                 if (Physics.Raycast(ray, out hit, touchInputMask))  //if the raycast hits an objects collider within the layermask
                 {
                     GameObject recipient = hit.transform.gameObject;
 
                     if (touch.phase == TouchPhase.Began)    //if a finger has just been put down on the object
                     {
                         //mark the object as selected
                         //set position of object to touch.position
 
                         recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
                     }
 
                     if (touch.phase == TouchPhase.Moved)    //if a finger has just been put down on the object
                     {
                         //mark the object as selected
                         //move the object by touch.DeltaPosition
 
                         recipient.SendMessage("OnTouchMoved", hit.point, SendMessageOptions.DontRequireReceiver);
                     }
 
                     if (touch.phase == TouchPhase.Ended)    //if a finger has just been put down on the object
                     {
                         //mark the object as not selected
                         //make sure the object continues in the direction it was headed at the same speed when the finger is lifted off the screen
 
                         //float speed = touch.deltaPosition.magnitude/touch.deltaTime;
 
                         recipient.SendMessage("OnTouchUp", touch.deltaPosition, SendMessageOptions.DontRequireReceiver);
 
 
 
                         
                     }
 
                     if (touch.phase == TouchPhase.Canceled)    //if a finger has just been put down on the object
                     {
                         //mark the object as not selected
                         //make sure the object continues in the direction it was headed at the same speed when the finger is lifted off the screen
                     }
                 }
             }
         }
     }
 }

Attached to Object

 using System;
 using UnityEngine;
 using System.Collections;
 
 public class Movement : MonoBehaviour
 {
 
     // Use this for initialization
     public float defaultSpeed;
     public float currentSpeed; //change to private once testing is completed.
     public bool selected = false; //change to false when testing is completed.
     
     
 
     public GroundController groundController;
 
 
     private void Awake()
     {
         CheckIsSlow();
 
         groundController = GetComponent<GroundController>();
     }
 
     private void Update()
     {
         if (!selected)
         {
             transform.Translate(0.0f, -currentSpeed*Time.deltaTime, 0.0f, Space.World);
         }
     }
 
     private void CheckIsSlow()
     {
         Debug.Log("CheckIsSlow Called");
 
         if (EventManager.isSlow)
         {
             Debug.Log("Event Manager Is Slow enabled");
             currentSpeed = EventManager.slowModifier;
         }
 
         else
         {
             Debug.Log("Event Manager Is Slow is not enabled");
             currentSpeed = defaultSpeed;
         }
 
     }
 
     private void OnCollisionEnter(Collision otherObject)
     {
         if (otherObject.gameObject.tag == "floor")
         {
             currentSpeed = 0;
             rigidbody.isKinematic = true;
             groundController.SetToGround();
         }
 
         else if (otherObject.gameObject.tag == "orb" || otherObject.gameObject.tag == "powerup")
         {
             if (otherObject.gameObject.GetComponent<GroundController>().isGrounded)
             {
                 currentSpeed = 0;
                 rigidbody.isKinematic = true;
                 groundController.SetToGround();
             }
         }
     }
 
     private void OnTouchDown(Vector3 position)
     {
         selected = true;
 
         gameObject.transform.position = new Vector3(position.x, position.y, 0);
     }
 
     private void OnTouchStay(Vector3 position)
     {
         selected = true;
 
         gameObject.transform.position = new Vector3(position.x, position.y, 0);
     }
 
     private void OnTouchMoved(Vector3 position)
     {
         selected = true;
 
         gameObject.transform.position = new Vector3(position.x, position.y, 0);
     }
 
     private void OnTouchUp(Vector3 force)
     {
         //newSpeed = currentSpeed;
 
         rigidbody.AddForce(force.x, force.y, 0);
 
         selected = false;
     }
 }

There is some code that is commented out, but I was back tracking from getting an object to move with the same speed and in the same direction after touchpase.ended or mouseup, but that is a completely separate beast.

Again, I really appreciate any amount of time that you take to help me out :-)

Thanks,

A brain fried coder

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

2 Replies

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

Answer by robertbu · Apr 28, 2014 at 12:01 AM

Your problem is likely on this line:

 Vector3 position = camera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0    ));

The 'z' parameter of a Vector3 passed to ScreenToWorldPoint() needs to be set to the distance in front of the camera. You are setting the value to 0, so your world position is coming back as the position of the camera or the near clip plane. I'm assuming you have an Orthographic camera, or this code would not work at all.

A quick solution is to insert at line 43:

 position.z = hit.transform.position;

Note the use of ScreenToWorldPoint() like you have here assumes the camera has a rotation of (0,0,0).

Comment
Add comment · Show 11 · 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
avatar image Jason87 · Apr 28, 2014 at 12:39 AM 0
Share

robertbu and Jeff,

I took the advice of both of you.

Robertbu, I had it set to the position of hit.z before and it continued to jump forward in the z, always that same 9.297 number. I did put it back to that though because that just makes sense and ensures that no matter where it is, it will never move in the z.

Jeff, I have no idea why hit.transform.position = position; was in there at all. I took it out.

I changed the code a bit, but the only difference is that my Touch$$anonymous$$anager uses Send$$anonymous$$essage to call the function OnTouchDown on the object to move its position and mark it as selected.

Touch$$anonymous$$anager Code:

 #if UNITY_EDITOR
 
         if (Input.Get$$anonymous$$ouseButton(0) || Input.Get$$anonymous$$ouseButtonUp(0) || Input.Get$$anonymous$$ouseButtonDown(0))
         {
             Ray ray = camera.ScreenPointToRay(Input.mousePosition);
             
             
             
 
                 if (Physics.Raycast(ray, out hit, touchInput$$anonymous$$ask))  //if the raycast hits an objects collider within the layermask
                 {
                     GameObject recipient = hit.transform.gameObject;
 
                     if (Input.Get$$anonymous$$ouseButtonDown(0))    //if a finger has just been put down on the object
                     {
                         //mark the object as selected
                         //set position of object to touch.position
 
                         Debug.Log("Get $$anonymous$$ouse Button Down called!!");
 
                         float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
 
                         Vector3 position = camera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,recipient.transform.position.z));
 
                         recipient.Send$$anonymous$$essage("OnTouchDown", position, Send$$anonymous$$essageOptions.DontRequireReceiver);
 
                         
                     }

$$anonymous$$ovement Code on Object: public class $$anonymous$$ovement : $$anonymous$$onoBehaviour {

     // Use this for initialization
     public float defaultSpeed;
     public float currentSpeed; //change to private once testing is completed.
     public bool selected = false; //change to false when testing is completed.
     
     
 
     public GroundController groundController;
 
 
     private void Awake()
     {
         CheckIsSlow();
 
         groundController = GetComponent<GroundController>();
     }
 
     private void Update()
     {
         if (!selected)
         {
             transform.Translate(0.0f, -currentSpeed*Time.deltaTime, 0.0f, Space.World);
         }
     }
 
     private void CheckIsSlow()
     {
         Debug.Log("CheckIsSlow Called");
 
         if (Event$$anonymous$$anager.isSlow)
         {
             Debug.Log("Event $$anonymous$$anager Is Slow enabled");
             currentSpeed = Event$$anonymous$$anager.slow$$anonymous$$odifier;
         }
 
         else
         {
             Debug.Log("Event $$anonymous$$anager Is Slow is not enabled");
             currentSpeed = defaultSpeed;
         }
 
     }
 
     private void OnCollisionEnter(Collision otherObject)
     {
         if (otherObject.gameObject.tag == "floor")
         {
             currentSpeed = 0;
             rigidbody.is$$anonymous$$inematic = true;
             groundController.SetToGround();
         }
 
         else if (otherObject.gameObject.tag == "orb" || otherObject.gameObject.tag == "powerup")
         {
             if (otherObject.gameObject.GetComponent<GroundController>().isGrounded)
             {
                 currentSpeed = 0;
                 rigidbody.is$$anonymous$$inematic = true;
                 groundController.SetToGround();
             }
         }
     }
 
     private void OnTouchDown(Vector3 position)
     {
         selected = true;
 
         gameObject.transform.position = new Vector3(position.x, position.y,position.z);
     }

Thanks again!

avatar image Jeff-Kesselman · Apr 28, 2014 at 01:42 AM 0
Share

You still have the same problem.

You are setting your object's Z to the Z position of the mouse click on the screen.

Don't do that.

$$anonymous$$eep its current Z.

avatar image Jeff-Kesselman · Apr 28, 2014 at 01:43 AM 0
Share

Eg this...

  private void OnTouchDown(Vector3 position)
     {
         selected = true;
  
         gameObject.transform.position = new Vector3(position.x, position.y,position.z);
     }

Should be this:

 private void OnTouchDown(Vector3 position)
     {
         selected = true;
         position.z = gameObject.Transform.position.z;
         gameObject.transform.position = new Vector3(position.x, position.y,position.z);
     }
avatar image Jeff-Kesselman · Apr 28, 2014 at 02:08 AM 1
Share

So, to do that in the code have able would look like this more or less.

Note that there are more efficient ways to organize this but not without changing the OPs code structure.

He should NOT transform the mouse position to world coords in the sender, but pass it straight to this code in screen coords.

  private void OnTouchDown(Vector3 mousePos)
         {
             selected = true;
  
 
             Vector3 objInScreenSpace =
                               camera.WorldToScreenPoint(gameObject.transform.position);
             gameObject.transform.position = 
                      camera.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y,
 `                                       objInScreenSpace.z);
         }
avatar image Jeff-Kesselman · Apr 28, 2014 at 03:43 PM 1
Share

Sure,

So, in this case we are having to transform the object's position to screen space to get the Z every time we call this. But if what if you are looking for is a drag or drag like effect, then by definition the Z isn't going to change through multiple moves.

So, we could cache the transformed point "objInScreenSpace" to a global. . The trick is to know when the Z has changed. If its a drag we can cache it until drag end, If its a series of taps then its trickier, but you could also save the untransformed Z of the object and only recalculate when that Z changes, if that makes sense.

For the first version, this guy does a good job with his code;

http://answers.unity3d.com/questions/12322/drag-gameobject-with-mouse.html

 enter code hereusing UnityEngine;
 using System.Collections;
  
 [RequireComponent(typeof($$anonymous$$eshCollider))]
  
 public class GizmosController : $$anonymous$$onoBehaviour 
 {
  
 private Vector3 screenPoint;
 private Vector3 offset;
  
 void On$$anonymous$$ouseDown()
 {
     screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
  
     offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
  
 }
  
 void On$$anonymous$$ouseDrag()
 {
     Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
  
 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) +offset;
 transform.position = curPosition;
  
 }
  
 }

For the latter, I can write you a code patch when i have a few more $$anonymous$$utes then right now...

Show more comments
avatar image
2

Answer by Jeff-Kesselman · Apr 27, 2014 at 11:58 PM

What are you trying to accomplish? This looks very strange...

  Vector3 position = camera.ScreenToWorldPoint(
                                     new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0    ));
  
 hit.transform.position = position;

What this code seems to be trying to do is move the clicked object to be on the plane of the screen. What you probably want is:

 Vector3 position = 
          camera.ScreenToWorldPoint(
               new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0    ));
     position.z = hit.transform.z;
     hit.transform.position = position;
Comment
Add comment · Show 2 · 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
avatar image Jason87 · Apr 28, 2014 at 12:40 AM 0
Share

Hey Jeff! I responded to you as well in my post to rebertbu below. Thanks for pointing that out.

avatar image robertbu · Apr 29, 2014 at 04:12 AM 0
Share

@Jeff $$anonymous$$esselman deserves the credit for answering this one. He went beyond the editor specific code to take a look at the whole problem. Thumbs up Jeff.

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

21 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Change position of camera on scene load? 1 Answer

Create a straight gradient equation with a grid of 3d objects 1 Answer

Following another object's position/rotation like parent/child relationship? 4 Answers

How do you set the initial value of a variable to an objects current position in unity? 1 Answer

Create an animation with variables? 1 Answer


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