So i’m creating a AR app with the Google Tango. Players are able to place objects, rotate etc. Dragging the object to change it’s positions works but when the player rotates to place an object behind him, it starts acting weird.
When i start the app, it scans the room. i place an object and everything works perfect. Dragging up, drags the object further away in the Z axis, and dragging down drags it closer. Left and right work as well. However, when i turn around to place a object behind me, left and right still work. but dragging up bring the object closer, and dragging towards me makes the object get further away. So basicly when i turn around the up/down dragging does the opposite.
Here’s my movement code:
private float factor = 1f;
private Vector3 v3StartPos; // Initial position of object
private Vector3 v3DownPos; // Initial position of the mouse in world coordinates
private float fZMap; // Base Z distance to use in conversion
void OnMouseDown() {
v3StartPos = transform.localPosition;
Vector3 v3T = Camera.main.WorldToScreenPoint(v3StartPos);
fZMap = v3T.z;
v3DownPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, fZMap);
v3DownPos = Camera.main.ScreenToWorldPoint(v3DownPos);
}
void OnMouseDrag() {
Vector3 v3T = Camera.main.WorldToScreenPoint(v3StartPos);
fZMap = v3T.z;
v3T = new Vector3(Input.mousePosition.x, Input.mousePosition.y, fZMap);
v3T = Camera.main.ScreenToWorldPoint(v3T);
Vector3 v3T2 = v3StartPos;
v3T2 = v3StartPos;
v3T2.x = v3T2.x + (v3T.x - v3DownPos.x);
v3T2.z = v3T2.z + (v3T.y - v3DownPos.y) * factor;
#if UNITY_EDITOR
transform.localPosition = v3T2;
#endif
if (Input.touchCount == 1) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
transform.localPosition = v3T2;
}
}
}
I’m stuck and have been trying things for days now, so any help would be highly appreciated!
Note: The reason it converts the Y axis to the Z axis is because dragging upwards should move the object on the Z axis. so the Y pos is basicly always 0. The object isnt able to move up. Since it’s an app about placing furniture inside your living room (to check how it looks before you buy it) it doesn’t need to be able to go up or down on the Y axis.
A sort of simple idea might be to use an unmoving reference GameObject. Modify the furniture or what not, using that object’s rotation instead of the player’s.
What do ya think?
If i understand you correct, you mean always let it face that unmoving object right? Cause that way people can’t rotate their object anymore. Or well, they can but it will change as soon as they move the object around.
Sorry, I’m trying to think this over. I’m not entirely sure that my previous advice was good / relevant.
So far, all I can think of is that your objects are probably going the opposite direction because their rotation (or at least that’s one way of looking at it)
I’m not an expert at this, but I wrote a simple drag script, similar to yours but just moving close/far and rotated 1 cube 180 deg around and then up / down movement pushed away/pulled closer.
No need for a sorry, i appreciate the help. And yea, what happens is, my script converst the Y to Z. so when i drag up (on the Y) it moves in the Z. Nothing special. But what happens is, when i rotate the camera, the dragging behaviour stays the same. Resulting in, if i drag up from my start position it will go up (away from me) on the Z axis. But when i rotate the camera, and drag up. It still gets up from the Z axis, but since i rotated the camera it will than try to move towards me. Sicne dragging up will still add on the Z axis.
What it think is the best solution is to find a way to check if i rotated the camera, and if i did. Change the behaviour. So when the camera is rotated to -180 dragging up should no longer add the Z axis, but rather go on the - in the Z axis.
I just have no idea how to do this, hope this makes it a bit more clear and u can help me.
Yep, that makes perfect sense and was one of the ideas that was also on my mind.
Did the idea of rotating the objects you drop seem viable to you at all?
Plus, one thing you never said explicitly, is are there just 2 directions that you can face? 0 and 180 ? Or can you pivot any amount, because then it’s a bit more complicated…
If you have a starting direction, say rotation 0. You could have a simple bool that switches when you turn. Then you could either: A) rotate any objects you drop 180 on Y when turned, and use the original up/down logic that you had.
or B) according to the bool, inverse the drag logic that you have now for the Z.
for just 2 directions, either is good (almost the same anyways).
I dont think it’s viable, as than, as i said people would have trouble with rotating the furniture right, since it changes when they move the object. And unfortunately you can pivot any amount you want. As you can decorate your entire room, and look around/walk around all you want. objects stay where they’re placed/moved to.
Hi robson, first of all thanks for replying! Second, i cant really find a way to implement that in my code to test it. Perhaps i’m overlooking something? Or maybe you can give me a push in the right direction. Would appreciate it.
// Get the cameras forward direction, limited to the plane
Vector3 camFwd = Vector3.ProjectOnPlane(Camera.main.forward).normalized;
// Calculate the dot product with the forward vector
float dot = Vector3.Dot(Vector3.forward, camFwd);
// Use the dot product to determine direction
if (dot >= 0f) {
MoveThisWay();
} else {
MoveThatWay();
}
Hi @patrick508 , I took another look at you code and maybe (big maybe) what you overlooked is that during your OnMouseDrag you’ll have the opportunity to check the angles and see if the device rotated to face it’s rear (in comparison to when the app started).
Sorry for not being specific to your scenario, try to experiment with something like the code below:
// your code
private Camera _camera;
private Transform _cameraTrans;
void Start()
{
_camera = Camera.main; // if more than one camera in the scene, make sure this is the 'Tango Camera'
_cameraTrans = _camera.transform;
}
void OnMouseDown()
{
//your code, but now check if the device is inverted from where it started
if (_cameraTrans.rotation.eulerAngles.y < -90.0f || (_cameraTrans.rotation.eulerAngles.y > 90.0f && _cameraTrans.rotation.eulerAngles.y < 270.0f))
{
// maybe you need to invert your calculations, mine was like below
// zOffset = -1.0f * zOffset;
}
}
void OnMouseDrag()
{
//your code, but now check if the device is inverted from where it started
if (_cameraTrans.rotation.eulerAngles.y < -90.0f || (_cameraTrans.rotation.eulerAngles.y > 90.0f && _cameraTrans.rotation.eulerAngles.y < 270.0f))
{
// maybe you need to invert your calculations, mine was like below
// zOffset = -1.0f * zOffset;
}
}
I’ve been messing around with your code and some own idea’s. Unfortunately not the results i was looking for. I’ve tried out a bunch of things. The thing that worked almost as wanted i guess is doing your suggestion but than with the Z axis. Like so:
I added that just above the movement part in OnMouseDrag();
The answer is probably right in front of me but i’m just staring myself to death on the code atm.
Your example actually almost works! When standing on start position (0 degrees) it works fine, and when rotating 180 degrees it works fine as well! But inbetween those numbers it’s acting weird (dragging sideways when touching up)
It’s an improvement tho. I think the main problem is since you can walk and rotate around freely you have a lot of different situations.
Thanks a lot for helping me by the way, appreciate the kindness
Euler angles are almost never the answer. This sounds like the cause of your weirdness with the suggested code. You should read the linked article, but the short version of it in this case would be that the Y component of Euler angles is nearly meaningless without considering the other two components as well. If you want to check for inversion, use transform.up < 0f instead of checking Euler angles.
If I understand the original problem correctly, I think you probably want to make a new rotation by which you modify your “user is dragging in this direction” vector. The easiest way to do that is to simply “multiply” the rotation by the vector. (It’s not really multiplying, but it uses the * operator.) But just using camera.transform.rotation would send it through the floor if you drag forward, so you can’t do that. If that’s an accurate way to phrase the problem, then it can be solved by created a “flattened” rotation.
This code assumes that dragMovedThisFrame is a Vector2 with X,Y being how much the user dragged the mouse/touch this frame.