Unity - move 3d object in an AR scene - unity3d

I have an AR scene that has one AR camera, an image target and 3d object below as.
I create an .cs file and attach to ARCamera. I want to move AR object to mouse click position. I tried many codes for this. But I couldn't success it.
I know that Input.mouseposition returns screen position. I convert to ScreenToWorldPosition and put 3d object on this position. 3d object is moved, but not mouse click position. I don't know where it is moved.
How can I move to mouse click position? My code is here :
Camera cam;
Vector3 target = new Vector3(0.0f, 10f,0.5f);
// Use this for initialization
void Start () {
if (cam == null)
cam = Camera.main;
}
void Update()
{
if (Input.GetMouseButtonDown(0)) {
Debug.Log("MouseDown");
Vector3 mousePos = Input.mousePosition;
mousePos = cam.ScreenToWorldPoint(mousePos);
GameObject.Find("Car1").gameObject.transform.position = mousePos;
}
}
EDIT 1
If I add a plane to scene, I can move to the position of mouse click only on the plane. The code is taken from here. But the plane prevents to show AR camera view. The screenshot is below:

Instead of playing with ScreenToWorldPoint, you should use a raycast against a plane, see this answer: https://stackoverflow.com/a/29754194/785171.
The plane should be attached to your AR marker.

ScreenToWorldPoint takes a Vector3, mousePosition is basically a Vector2 (with a 0 z-axis value). You need to set the mousePosition.z value to something for it to be placed in a viewable position. Example:
Vector3 mousePos = Input.mousePosition;
mousePos = cam.ScreenToWorldPoint(mousePos);
mousePos.z = 10;
GameObject.Find("Car1").gameObject.transform.position = mousePos;
This would set the position to 10 units away from the camera.

Related

Unity3D - Move camera perpendicular to where it's facing

I'm adding the option for players to move the camera to the sides. I also want to limit how far they can move the camera to the sides.
If the camera was aligned with the axis, I could simply move around X/Z axis and set a limit on each axis as to how far it can go. But my problem is that the camera is rotated, so I'm stuck figuring out how to move it and set a limit. How could I implement this?
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class CameraController : MonoBehaviour
{
Camera cam;
Vector3 dragOrigin;
bool drag = false;
void Awake()
{
cam = GetComponent<Camera>();
}
void LateUpdate()
{
// Camera movement with mouse
Vector3 diff = (cam.ScreenToWorldPoint(Input.mousePosition)) - cam.transform.position;
if (Input.GetMouseButton(0))
{
if (drag == false)
{
drag = true;
dragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
}
}
else
{
drag = false;
}
if (drag)
{
// Here I want to set a constraint in a rectangular plane perpendicular to camera view
transform.position = dragOrigin - diff;
}
}
}
Transform in Unity comes with a handy Transform.right property, which regards the object's rotation. To move your camera sideways you could further utilize Lerp to make the movement smooth.
transform.position += transform.right * factor
moves an object to the right.
Use factor to adjust the desired distance and by doing so you can also set limits. Negative factor would mean moving left by the way:) Hope that helps!
It can be tricky to deal with constraints on rotated objects. The math behind this includes some vector/rotation math to figure out the correct limits relative to the object's orientation, and whether you've exceeded them.
Luckily though, Unity gives you some shortcuts to skip this math: Transform.InverseTransformPoint() and Transform.TransformPoint()! These two methods allow you to transform a point in world space into a point in local space, and vice versa.
That means that no matter how your camera is oriented, you can interpret a position from the orientation of the camera - and with just a couple extra steps, your X/Z constraints are usable because you can calculate X/Z from the camera's point of view.
Let's try to adapt your current script to use this:
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class CameraController : MonoBehaviour
{
// Set the X and Z values in the editor to define the rectangle within
// which your camera can move
public Vector3 maxConstraints;
public Vector3 minConstraints;
Camera cam;
Vector3 dragOrigin;
bool drag = false;
Vector3 cameraStart;
void Awake()
{
cam = GetComponent<Camera>();
// Here, we record the start since we'll need a reference to determine
// how far the camera has moved within the allowed rectangle
cameraStart = transform.position;
}
void LateUpdate()
{
// Camera movement with mouse
Vector3 diff = (cam.ScreenToWorldPoint(Input.mousePosition)) - cam.transform.position;
if (Input.GetMouseButton(0))
{
if (drag == false)
{
drag = true;
dragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
}
}
else
{
drag = false;
}
if (drag)
{
// Now, rather than setting the position directly, let's make sure it's
// within the valid rectangle first
Vector3 newPosition = dragOrigin - diff;
// First, we get into the local space of the camera and determine the delta
// between the start and possible new position
Vector3 localStart = transform.InverseTransformPoint(cameraStart);
Vector3 localNewPosition = transform.InverseTransformPoint(newPosition);
Vector3 localDelta = localNewPosition - localStart;
// Now, we calculate constrained values for the X and Z coordinates
float clampedDeltaX = Mathf.Clamp(localDelta.x, minConstraint.x, maxConstraint.x);
float clampedDeltaZ = Mathf.Clamp(localDelta.z, minConstraint.z, maxConstraint.z);
// Then, we can use the constrained values to determine the constrained position
// within local space
Vector3 localClampedPosition = new Vector3(clampedDeltaX, localDelta.y, clampedDeltaZ)
+ localStart;
// Finally, we can convert the local position back to world space and use it
transform.position = transform.TransformPoint(localConstrainedPosition);
}
}
}
Note that I'm somewhat assuming dragOrigin - diff moves your camera correctly in its present state. If it doesn't do what you want, please include details on the unwanted behaviour and we can sort that out too.

On Finger Touch and Drag Rotate 3D Ball - Unity 3D

My 3d ball was moving continuously in the forward direction so I want to give X-rotation for this plus game player was dragging ball horizontally on the screen so for this horizontal movement, I want to give Z-rotation.
To achieve my desire, the result I have made ball parent and child game objects, where parent game object only contains collider and rigidbody and this will do the actual physical movement.
Another side, child game object only contains mesh renderer, this will do desire rotation.
Following image gives you more idea about my structure:
Ball Parent:
Ball Child:
For giving rotation to ball mesh as like parent physics ball, I have written this code:
public class BallMeshRolling : MonoBehaviour
{
private Vector3 ballLastPosition;
void Start ()
{
ballLastPosition = transform.parent.position;
}
void Update ()
{
//implementation-1
//float speed = Vector3.Distance (transform.parent.position, ballLastPosition) * 30f;
//transform.RotateAround (transform.position, Vector3.right, speed);
//implementation-2
//Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized;
//transform.Rotate (differenceInPosition * 10f);
//implementation-3
Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized * 50f;
Quaternion rotation = Quaternion.LookRotation(differenceInPosition);
transform.rotation = rotation;
ballLastPosition = transform.parent.position;
}
}
But none of the above ways working properly, so I expect some other better suggestions from your side.
EDIT: Overall I am trying to achieve something like this:
Catch up - Ketchapp - Highscore 1274
There is a tutorial series from Unity about rolling and moving a 3d ball that can help you to figure out the basics for your problem. Wish it could help.
Roll-a-ball tutorial in Unity Tutorials

Unity3D follow Sphere player camera rotation

Hi I'm trying to get my camera to follow my player (Sphere) when ever it moves around. I have got the camera to follow the player, but when the sphere spins, so do the camera. That is not what i'm looking for. I need the camera to stay put on the sphere and rotate when I turn. This is my code so far:
EDIT: What I'm looking for is something like you see in the vid. where the camera rotate when the sphere is turning, so it's behind it all the time. https://www.youtube.com/watch?v=jPAgPQi1l0c
using UnityEngine;
using System.Collections;
public class TransformFollower : MonoBehaviour
{
[SerializeField]
private Transform target;
[SerializeField]
private Vector3 offsetPosition;
[SerializeField]
private Space offsetPositionSpace = Space.Self;
[SerializeField]
private bool lookAt = true;
private void Start()
{
offsetPosition = new Vector3(-3, -2, 0);
}
private void Update()
{
Refresh();
}
public void Refresh()
{
if (target == null)
{
Debug.LogWarning("Missing target ref !", this);
return;
}
// compute position
if (offsetPositionSpace == Space.Self)
{
transform.position = target.TransformPoint(offsetPosition);
}
else
{
transform.position = target.position + offsetPosition;
}
// compute rotation
if (lookAt)
{
transform.LookAt(target);
}
else
{
transform.rotation = target.rotation;
}
}
}
You should implement the following logic:
Create an empty gameObject:Character, where it will have as childs: Camera, Sphere
when you move, you simply transform the Character, so the Camera and the Sphere transform in the exact same way.
Now, when you want to rotate only the Sphere, but not the camera, just apply your rotation(or anything else), only in the sphere.
To do so, in your script you can pass the Character and the Sphere.
So moving transformations will be applied in on the Character and any custom move, only in the sphere.
Nik
Did you write this code yourself?
It simply seems that if lookat is true, it will do what you want. If it is false, if will do what you describe.
Just look in the editor and check the 'look at' box.
If you never want to use it you can remove it from the code by removing the lookat variable and replacing
// compute rotation
if (lookAt)
{
transform.LookAt(target);
}
else
{
transform.rotation = target.rotation;
}
by
// compute rotation
transform.LookAt(target);
EDIT more explanation:
In your code, you have two options: lookat and offsetPositionSpace.
Basically, offsetPositionSpace can be two values:
Self -> The camera will always be behind the player (if you rotate the player, it moves to stay behind
World -> The camera will always imitate the player's moves (If the player rotates, the camera won't move
LookAt can also have two values
true -> the camera looks at the player, always
false -> the camera imitate the players rotation (if the player rotates, the camera does the same and stops looking at the player)

Move a particular sprite to a target position on touch in unity 4.6

I have just started unity. I have 4 Images(sprites) aligned in a grid. Now i want to move an image to a target position as soon as I touch the image. How can i do that?
I wrote the following code for move:
void Update () {
float step=speed*Time.deltaTime;
transform.position=Vector3.MoveTowards(transform.position,target.position,step);
}
I just don't know to move that particular sprite on which I touch.
Thanks
From http://answers.unity3d.com/questions/420808/how-to-get-position-of-touch-on-touch-screen.html
fingerPos = Input.GetTouch(0).position;
Vector3 pos = fingerPos;
pos.z = transform.position.z;
// simplified check
if (transform.position == Camera.main.ScreenToWorldPoint(pos))
{
// move towards the target as you want
}
Notice that i kept it brief with that if, but, of course, you should check if the touch position is withing the boundaries of your object.

How to drag a cube in orthographic camera in Unity 3d?

I am trying to create a isometric game like clash of clans. I created a Terrain and I set my camera position to (0,300,-10) and Rotation to (40,45,0) and Perspective to Orthographic. I am using below code to drag a cube but when i drag the cube at some position cube is not able to visible or only some portion of cube is visible. It seems like position (X,Y,Z) all three are changing using below code. But i want to drag cube just like any top down game like Clash of Clans. Please help me to resolve my issue.
void OnMouseDrag ()
{
Vector3 mousePosition = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0);
Vector3 objPosition = Camera.main.ScreenToWorldPoint (mousePosition);
this.target.transform.position = objPosition;
}
You need raycasting to solve it. Try this-
void OnMouseDrag ()
{
RaycastHit hitInfo;
bool hit = Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hitInfo, Mathf.Infinity, 1 << LayerMask.NameToLayer ("ground"));
if(hit){
this.target.transform.position = hitInfo.point;
}
}
You can use your existing ground or surface or on whatever your object will move, change the layer name to ground. Be aware that the ground must have a collider.