- Home /
Moving objects with *Isometric* mouse position (JS)
Hello there!
My scene has an orthographic camera at 45 degrees on the x & y axis.
I have this piece of code placed to an object that follows the mouse around. The camera being 270 units off the ground meant to avoid placing the object directly under the camera I had to add 195 units to the z & x axis. There is also a clamp to ensure it doesn't leave the ground. Eventually I want this to depend on terrain height, but i'm more concerned about the current situation of it not moving exactly to the mouse position. The Y axis must ALWAYS be at 0 as the item must not leave the ground. My scene is basically the beginnings of a system where you place a building on terrain (which has no hills, at the current time, so it doesn't matter if the Y axis is stuck to 0).
My code works nicely for side to side mouse swiping, but upwards and downwards it moves very slowly compared to sideways. Is there a better way to do this so it ACTUALLY DOES follow the mouse, or is it always going to have an offset that I must work out how to counteract, and can you help me work out how to counteract this?
var myCamera : Camera;
function Update () {
var vec : Vector3 = myCamera.ScreenToWorldPoint (Input.mousePosition);
var top : float = 0.0;
vec.y = Mathf.Clamp(vec.y, -top, top);
vec.z = vec.z + 195;
vec.x = vec.x + 195;
//vec.z = 0.0;
transform.position = vec;
}
Kind regards, Liam
Answer by robertbu · Sep 12, 2013 at 06:18 AM
One solution is to use Unity's mathematical Plane class. Since you always want the 'y' to be zero, you would place your plane at the origin (Vector3.zero), and use Vector3.up as the normal. Then you can use Camera.ScreenPointToRay() with the mouse position. And then use the ray in Plane.Raycast() to position your object.
I don't have access to Unity to writeup some sample source, but this code has been posted before a few times.
robertbu is correct (as usual), but I think his answer won't help you understand what you are doing wrong. ScreenToWorldPoint will convert a point on the screen to a point world space. This will give you a point that is just in front of the camera that corresponds to the point on the screen.
However, there are an infinite number of points that the point on the screen could represent (all in one line "behind" your finger). A datatype that will cover all these points is a Ray, which contains origin (the camera) and direction (the line behind the touch).
By doing a Raycast against a collider (a simplified version of your terrain), you can find the point along that line that intersects with your terrain. Note that when you start adding hills it is possible there will be more than one point.
I'm afraid your generous answers were met by a bit of confusion after trying and testing, it would really help me to see snippets of code to understand better what you are conveying, but I know a lot of devs frown upon people who ask for it!!. I tried a few things myself, I don't understand where i'm supposed to declare the plane variable, or what you even meant by the plane variable- my object or the terrain?
#pragma strict
var myCamera : Camera;
//var myPlane : Plane;
//Plane.Raycast(myCamera);
function Update () {
Plane.Raycast(myCamera);
var vec : Vector3 = myCamera.ScreenPointToRay(Input.mousePosition);
vec.y = Vector3.zero;
vec.x = Vector3.up;
vec.z = Vector3.right;
transform.position = vec;
}
PS, what should I be searching to find these examples that are apparently posted a few times?
Normally I give example code, but I'm traveling and only have my iPad. Here is one link to a Plane/Raycast example:
http://forum.unity3d.com/threads/15802-Plane-Raycast-Example
Note the use of Vector3.up and Vector3.zero in the creation of the plane in this sample script.
Thank you so much! That answer gave me the grounds to finally complete what had been holding me back for a while! Have it working now and when I rotate the camera around a pivot point it doesn't alter how it works at all! Plane ray point really is incredibly useful for strategy games.
$$anonymous$$ind regards, Liam