Duckbridge









Level 0 Tutorial: Implementing basic 2D touch controls in unity. « on: November 30, 2014, 07:35:01 AM »



0: Setting up

Because I’m not sure how much Unity experience you have, we will start at the beginning. So create a new Unity project which you can call whatever you want. Make new scene and add a new c# script, call it TouchListener and add it to a new empty gameObject in the scene.



1: Touching an object

In order to touch an object, we need to add the following variable to the TouchListener class:



public Camera usedCamera;

public float minimumDragDistance = 1f;



private bool isTouching;

private Vector3 touchPoint;



private static GameObject selectedObject;



We will use the usedCamera to detemine which camera we want to use for the FixedUpdate function and add the following:



if(!isTouching) {

if (Input.GetMouseButtonDown(0)) {

isTouching = true;

selectedObject = null;



RaycastHit hitSummary;

Physics.Raycast(usedCamera.ScreenPointToRay(Input.mousePosition), out hitSummary, 200);



this.touchPoint = usedCamera.ScreentoWorldPoint(Input.mousePosition);



if (hitSummary.collider != null) {

selectedObject = hitSummary.collider.gameObject;

selectedObject.SendMessage("OnTouched", hitSummary, SendMessageOptions.DontRequireReceiver);

}

}

}



What this will do is, check if you’re not touching an object already and then use Raycasting to raycast from the position of your finger inside the camera into the depth. When the raycast hits, it checks if the hit object has a collider.



If it has a collider, it uses the collider to get the gameobject that was hit. And it sends an OnTouched event message to that object! We also register the touchPoint which will be used for the dragging.



2 Test the touch:

If you want to test out if this works, just create a new Cube in the scene and give it a (new) TouchableObject c# script and modify your camera to be ‘orthographic’. Make sure that the cube is inside the camera’s z axis (so you should be able to see it in the ’game’ window). Drag the camera into the ‘usedCamera’ variable inside the Touch Listener in the Unity editor.



Then inside the TouchableObject script, add a new function : OnTouched:



public void OnTouched(RaycastHit hitSummary) {

Debug.Log(‘hello!’);

}



Then run the scene and try to click the object, congrats you now have basic touch behaviour!



3: Dragging an object

So now we got the basic touch behaviour working, we can move on to dragging, which is a bit more tricky, but uses the same idea!



So we go back inside the TouchableObject and inside the FixedUpdate function again. Add the following code:



if(Input.GetMouseButtonUp(0)) {

this.isTouching = false;



if(selectedObject != null) {

selectedObject.SendMessage("OnDraggingStopped", null, SendMessageOptions.DontRequireReceiver);

}



selectedObject = null;

}



if(isTouching && selectedObject != null) {

OnTouchHeld();

}



I know that the code won’t compile yet, but we’ll fix that soon. Anwyays, what this piece of code is about is; you basically check if the user is still touching, if not, then the touched object is unset and a OnDraggingStopped event is sent to that object. So you can add custom behaviour to the object that was dragged/touched.



Small note: when you implement the OnDraggingStopped function on a TouchableObject, make sure that the OnDraggingStopped function has no parameters!



In order to fix the compile error, we need to add the most crucial part! The OnTouchHeld behaviour. Before we get into that, we need to create a new struct, which we will call DragSummary. So let’s create a new c# script, call it DragSummary and add the following code:





using UnityEngine;



public struct DragSummary {



public Vector3 position;

public Vector3 direction;

public Vector3 amount;



}



That’s all we need! If you’re wondering why we use a struct and not a class, it is beacuse Unity doesn’t like it when we create a new class, so we use a struct.



We’re almost done! We only need to fill the OnTouchHeld function with the right code. Add the following to the TouchListener class:



private void OnTouchHeld() {

Vector3 currentMousePosition = usedCamera.ScreenToWorldPoint(Input.mousePosition);

Vector3 dragAmount = (currentMousePosition - touchPoint);

Vector3 directionToCurrentMousePosition = currentMousePosition - selectedObject.transform.position;



DragSummary dragSummary = new DragSummary();

dragSummary.position = currentMousePosition;

dragSummary.amount = dragAmount;

dragSummary.direction = directionToCurrentMousePosition;



if(dragAmount.magnitude > minimumDragDistance) {

selectedObject.SendMessage("OnDrag", dragSummary, SendMessageOptions.DontRequireReceiver);

}



if(Mathf.Abs(dragAmount.x) > minimumDragDistance) {

selectedObject.SendMessage("OnHorizontalDrag", dragSummary, SendMessageOptions.DontRequireReceiver);

}



if(Mathf.Abs(dragAmount.y) > minimumDragDistance) {

selectedObject.SendMessage("OnVerticalDrag", dragSummary, SendMessageOptions.DontRequireReceiver);

}

}



This might seem like a lot of code, but it’s not really. So at first we take the current mouse position, and save that. Then we decide how much is dragged by subtracting our original touch position with the new position of the finger.



Then when we have that, we also calculcate the direction that the object needs to use in order to reach our finger’s new position. This might seem useless, because we could just set the object’s position to the position of our finger, right?



The thing is that that solution works fine, but we want to be able to control how fast the object will move towards the finger position.



The rest of this function is bascially checking the distance between the original touch position and the current touch position. Beacuse you might want to drag certain objects only horizontal/vertically or after a certain distance.



So okay, the final thing that we need to do is, go into the TouchableObject and add the following variable:



public float onTouchMoveSpeed = .5f;



And add the following function, which will allow for dragging:



public void OnDrag(DragSummary dragSummary) {

this.transform.position += onTouchMoveSpeed * new Vector3(dragSummary.direction.x, dragSummary.direction.y, 0f);

}



That should do the trick! Now when you test the scene again you should be able to drag the TouchableObject and also control how fast it can be dragged!



That’s it!, if you weren’t able to figure out some stuff, feel free to

Hey all, I’m marciano Viereck, the programmer @ Duckbridge and the other day I got a question about how to implement some basic 2D touch controls in Unity (for example that you can move something up, down, left and right by dragging it. In our framework we have code that allows us to use touch controls, so in this post I’ll go over how we implemented it in Unity3D and it might help you!:)Because I’m not sure how much Unity experience you have, we will start at the beginning. So create a new Unity project which you can call whatever you want. Make new scene and add a new c# script, call itand add it to a new empty gameObject in the scene.In order to touch an object, we need to add the following variable to theclass:We will use theto detemine which camera we want to use for the raycast . Now that we have this, go into thefunction and add the following:What this will do is, check if you’re not touching an object already and then use Raycasting to raycast from the position of your finger inside the camera into the depth. When the raycast hits, it checks if the hit object has a collider.If it has a collider, it uses the collider to get the gameobject that was hit. And it sends anevent message to that object! We also register the touchPoint which will be used for the dragging.If you want to test out if this works, just create a new Cube in the scene and give it a (new)c# script and modify your camera to be ‘orthographic’. Make sure that the cube is inside the camera’s z axis (so you should be able to see it in the ’game’ window). Drag the camera into the ‘usedCamera’ variable inside the Touch Listener in the Unity editor.Then inside thescript, add a new function :Then run the scene and try to click the object, congrats you now have basic touch behaviour!So now we got the basic touch behaviour working, we can move on to dragging, which is a bit more tricky, but uses the same idea!So we go back inside theand inside thefunction again. Add the following code:I know that the code won’t compile yet, but we’ll fix that soon. Anwyays, what this piece of code is about is; you basically check if the user is still touching, if not, then the touched object is unset and aevent is sent to that object. So you can add custom behaviour to the object that was dragged/touched.Small note: when you implement thefunction on a, make sure that thefunction has no parameters!In order to fix the compile error, we need to add the most crucial part! Thebehaviour. Before we get into that, we need to create a new struct, which we will call. So let’s create a new c# script, call itand add the following code:That’s all we need! If you’re wondering why we use aand not a, it is beacuse Unity doesn’t like it when we create a new class, so we use a struct.We’re almost done! We only need to fill thefunction with the right code. Add the following to theclass:This might seem like a lot of code, but it’s not really. So at first we take the current mouse position, and save that. Then we decide how much is dragged by subtracting our original touch position with the new position of the finger.Then when we have that, we also calculcate the direction that the object needs to use in order to reach our finger’s new position. This might seem useless, because we could just set the object’s position to the position of our finger, right?The thing is that that solution works fine, but we want to be able to control how fast the object will move towards the finger position.The rest of this function is bascially checking the distance between the original touch position and the current touch position. Beacuse you might want to drag certain objects only horizontal/vertically or after a certain distance.So okay, the final thing that we need to do is, go into theand add the following variable:And add the following function, which will allow for dragging:That should do the trick! Now when you test the scene again you should be able to drag theand also control how fast it can be dragged!That’s it!, if you weren’t able to figure out some stuff, feel free to download the example project, which contains all the stuff you need. « Last Edit: December 03, 2014, 02:29:31 PM by Duckbridge » Logged Dutch indie game developer that is currently working on Luckslinger , you can follow us on Twitter and Facebook