- Home /
Touch to move
Hi. I'm trying to conduct a little project for android but I've reached an issue. I'm trying to have my character move along a terrain so I made it to where if you click somewhere, a marker appears at the location and your character automatically follows it, as this script does:
function Update () {
for (var i = 0; i < Input.touchCount; i++) {
if (Input.GetTouch(i).phase == TouchPhase.Moved) {
var touchPos : Vector3 = Input.GetTouch(i).position;
touchPos.z = 4.0;
touchPos.y *= 4.0;
var createPos = myCam.ScreenToWorldPoint(touchPos);
projectile.position = createPos;
}
}
I also set up 2 cameras; one that follows the player and another that is at a top-down angle facing the terrain and character (which is the one that is referenced to in the script), both of which are orthographic. My problem is that I can't seem to get the touch marker to move/conform along the terrain, or if there's a high area the marker would just go through it, as it doesn't change its Y value if part of the terrain is raised. How would I go about accurately pinpointing the touch location in relation to the 3d environment? I've tried placing the marker high up and raycasting downwards but the touch part wouldn't respond at all, or very poorly.
Answer by redeemer · May 18, 2015 at 05:38 AM
I'd suggest to use raycast to detect the exact point where the tpuch and the terrain collides.
Something like should work :
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits = Physics.RaycastAll(ray, 200);
foreach(RaycastHit hit in hits) {
if(hit.collider.CompareTag("Terrain")) Debug.Log(hit.point);
}
Instead the mouse position, use your touch position.
Of course you could set the raycast to only detect the layers you want, this will detect the terrain point even if you touch over other object as long as the terrain is in the ray.
Hope this helps
I'm kind of confused; for this approach, should I keep my 2-cam setup or would this work for my main camera?
That code uses the main camera Camera.main.ScreenPointToRay(Input.mousePosition), but you can use the camera you want.
For example :
Camera topCam = GameObject.FindGameObjectWithTag("TopCam");
Ray ray = topCam.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits = Physics.RaycastAll(ray, 200);
foreach(RaycastHit hit in hits) {
if(hit.collider.CompareTag("Terrain")) Debug.Log(hit.point);
}
Take a look at this http://docs.unity3d.com/ScriptReference/Camera.ScreenPointToRay.html
In your case, I guess your following camera is the main cam, so if you want to click in that cam use the first code, if you want to click in the "$$anonymous$$i-map" or "top-down" cam, use the second one.
Of course, you terrain must have a collider since you're not using the Unity Terrain in order to being detetcted by the raycast.
Did I get this right (using your prior suggestion) because after rewriting it in javascript I get no errors though nothing is printed. I made sure my objects are tagged as well.. var rays : Ray; rays = mainCamera.ScreenPointToRay(Input.mousePosition); var hits : RaycastHit[];
hits = Physics.RaycastAll(rays, 200);
for(var hit : RaycastHit in hits) {
if(hit.collider.CompareTag("Terrain"))
{
print(hit.point);
}
Testing it with mouse first just to see if it works.
I've made you two examples, one with a cube used as the terrain and another with a Unity Terrain. Hope this help you solve any doubts. I leave you the link to the unitypackage
https://mega.co.nz/#!i1NlFJgJ!fToUf5WbZuwTiZd03NU0eXx_6pYmqV$$anonymous$$c5FHvlF0Qcss
Answer by hanger · May 18, 2015 at 06:14 AM
I've never used it, but what you want to do is query the terrain height at a particular world position. If you're using the Unity terrain system, there's a call for that.
Sorry, maybe I should've specified that my terrain was made manually in blender.
Answer by abhi_360 · May 18, 2015 at 06:09 AM
Your touchPos has no height component i.e the Input.GetTouch(i).position provides the ScreenSpace positions which is (pixelWidth,pixelHeight) like a vector2 so when your changing screen to world point that function has no height to it which then sets to zero you can Debug.Log(createPos).
You can use Physics RayCasts for this job. But if you have Unity 5 then you can download there standard assets which already has the kind of controller (like strategy games Civilization, Dota).
So in what way should I try setting up the raycasts, because I've used them but am experiencing issues with my current setup.
if you can be more specific about your raycast problems then i can give a solution. Like what issues are you experiencing
Going into areas with accessible overhangs where the ray is interrupted, having the ray-casting follow touch/click location somewhat accurately, if at all. $$anonymous$$y current setup has a gameobject, high up, following the touch position in relation to the top-down camera (not the main one following player) raycasting downwards and at the hitpoint is a separate gameobject (a marker).