how to rotate a object on touch and stop it on next touch.

Hello everyone,
I am new to unity 3d and just started using javascript.I want my object to rotate when i touch it once and it should stop rotating when I touch it again.
Here is what i have written but my object rotates just once and stops,if i keep touching it it keeps rotating.
function Update () {

		if (Input.touchCount > 0){
		
		transform.Rotate(0,0,rotspeed*Time.deltaTime);
		
		switch(Input.GetTouch(0).phase)
		{
			case TouchPhase.Began:
			transform.Rotate(0,0,rotspeed*Time.deltaTime);
			
			case TouchPhase.Moved:
			// Get movement of the finger since last frame
			var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;
			
			// Move object across XY plane
			transform.Translate (touchDeltaPosition.x * speed, 
						touchDeltaPosition.y * speed, 0);
		}
		} 

Please help me out.

2 Answers

2

FINAL EDIT : added GUI request from the comments

First, remember to separate your switch cases with a break;

The answer is to store all your rotating objects in a List. Here is a great resource on using List and Array in Unity : http://wiki.unity3d.com/index.php?title=Which_Kind_Of_Array_Or_Collection_Should_I_Use?

I don’t have any way to test this on a touch device, so I have written it to work with a mouse while running in the editor. It compiles and is tested and working, so it should (hopefully) work when built out to a device.

Again, I have left a lot of comments throughout the process, hopefully this will give you a starting point to writing your own code specific to your needs.

  • create a new scene
  • create some cubes at random positions

attach this script to an empty gameObject or the camera :

//------------------------------//
//  TouchDragAndRotate.js       //
//  Written by Alucard Jay      //
//  12/13/2013                  //
//------------------------------//

#pragma strict

// to use List
import System.Collections.Generic;

public var rotationSpeed : float = 180.0;
public var moveSpeed : float = 0.05;

var touchedObject : Transform; // private var, left public for testing
var rotatingObjects : List.< Transform >; // private var, left public for testing

var textToShow : String = "";


function Start() 
{
	rotatingObjects = new List.< Transform >();
}


function Update() 
{
	// to use mouse inputs in the editor
	// and device touch inputs in build
	#if UNITY_EDITOR
	UsingMouseInputs();
	#else
	UsingTouchInputs();
	#endif
}


function OnGUI() 
{
	if ( textToShow != "" )
	{
		GUI.Box( Rect( Screen.width * 0.5 - 150, 10, 300, 25), textToShow );
	}
}


function ClearTextToShow() 
{
	textToShow = "";
}


// --


function UsingTouchInputs() 
{
	// has the screen got a touch?
	if ( Input.touchCount > 0 )
	{
		// what is the current state of the touch 0?
		switch( Input.GetTouch(0).phase )
		{
			case TouchPhase.Began :
				// get the touch position on the screen
				var touchPos : Vector3 = new Vector3( Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0 );
				
				// create a Ray from the touch position
				var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
				
				// create a RaycastHit variable to gather Raycast information
				var hit : RaycastHit;
				
				// cast a ray
				// ideally this would be done using a layermask
				if ( Physics.Raycast( ray, hit, 1000 ) )
				{
					// check the hit object by name
					// ideally this would be done by checking the tag
					if ( hit.collider.gameObject.name == "Cube" )
					{
						// if the object is a cube
						// store a reference to the object 
						touchedObject = hit.transform;
					}
				}
				
				// check if there are any items in the list
				if ( rotatingObjects.Count > 0 )
				{
					// check if the touchedObject is in the rotatingObjects list
					var inList : boolean = false;
					
					for ( var i : int = 0; i < rotatingObjects.Count; i ++ )
					{
						// if it is, then remove it from the list
						if ( rotatingObjects[ i ] == touchedObject )
						{
							rotatingObjects.RemoveAt( i );
							
							inList = true;
							
							textToShow = "You just stopped the cube!";
							CancelInvoke( "ClearTextToShow" );
							Invoke( "ClearTextToShow", 1.5 );
							
							break;
						}
					}
					
					// if not, add it to the list
					if ( !inList && touchedObject )
					{
						rotatingObjects.Add( touchedObject );
						
						textToShow = "That cube is now spinning!";
						CancelInvoke( "ClearTextToShow" );
						Invoke( "ClearTextToShow", 1.5 );
					}
				}
				else if ( touchedObject ) // list is empty, so add the object as it is not rotating
				{
					rotatingObjects.Add( touchedObject );
					
					textToShow = "That cube is now spinning!";
					CancelInvoke( "ClearTextToShow" );
					Invoke( "ClearTextToShow", 1.5 );
				}
			break;
			
			case TouchPhase.Moved :
				// check if there is a gameObject stored in the variable
				if ( touchedObject )
				{
					// Get movement of the finger since last frame
					var touchDeltaPosition : Vector2 = Input.GetTouch(0).deltaPosition;
					
					// Move object across XY plane
					//touchedObject.Translate( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
					touchedObject.position += new Vector3( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
				}
			break;
			
			case TouchPhase.Stationary :
				
			break;
			
			case TouchPhase.Ended :
				// remove the reference to the gameObject
				touchedObject = null;
			break;
			
			default : // TouchPhase.Cancelled
				// remove the reference to the gameObject
				touchedObject = null;
			break;
		}
	}
	
	
	// check if there are any items in the list
	// if so, rotate the objects
	if ( rotatingObjects.Count > 0 )
	{
		for ( var r : int = 0; r < rotatingObjects.Count; r ++ )
		{
			rotatingObjects[ r ].Rotate( 0, 0, rotationSpeed * Time.deltaTime );
		}
	}
}


// --


// enumerator to emulate touch phases
enum MousePhase
{
	Idle,
	Began,
	Stationary,
	Moved,
	Ended,
	Cancelled
}

var mouseTouchPhase : MousePhase;

var lastMousePos : Vector3;
var currMousePos : Vector3;


function UsingMouseInputs() 
{
	// using mouse as I have no provisioning profile for my touch device
	if ( Input.GetMouseButtonDown(0) )
	{
		mouseTouchPhase = MousePhase.Began;
	}
	else if ( Input.GetMouseButton(0) )
	{
		mouseTouchPhase = MousePhase.Moved;
	}
	else if ( Input.GetMouseButtonUp(0) )
	{
		mouseTouchPhase = MousePhase.Ended;
	}
	else
	{
		mouseTouchPhase = MousePhase.Idle;
	}
	
	
	// get the touch position on the screen
	var touchPos : Vector3 = Input.mousePosition;
	
	lastMousePos = currMousePos;
	currMousePos = touchPos;
	
	
	// what is the current state of the touch 0?
	switch( mouseTouchPhase )
	{
		case MousePhase.Began :
			// create a Ray from the touch position
			var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
			
			// create a RaycastHit variable to gather Raycast information
			var hit : RaycastHit;
			
			// cast a ray
			// ideally this would be done using a layermask
			if ( Physics.Raycast( ray, hit, 1000 ) )
			{
				// check the hit object by name
				// ideally this would be done by checking the tag
				if ( hit.collider.gameObject.name == "Cube" )
				{
					// if the object is a cube
					// store a reference to the object 
					touchedObject = hit.transform;
				}
			}
			
			// check if there are any items in the list
			if ( rotatingObjects.Count > 0 )
			{
				// check if the touchedObject is in the rotatingObjects list
				var inList : boolean = false;
				
				for ( var i : int = 0; i < rotatingObjects.Count; i ++ )
				{
					// if it is, then remove it from the list
					if ( rotatingObjects[ i ] == touchedObject )
					{
						rotatingObjects.RemoveAt( i );
						
						inList = true;
						
						textToShow = "You just stopped the cube!";
						CancelInvoke( "ClearTextToShow" );
						Invoke( "ClearTextToShow", 1.5 );
						
						break;
					}
				}
				
				// if not, add it to the list
				if ( !inList && touchedObject )
				{
					rotatingObjects.Add( touchedObject );
					
					textToShow = "That cube is now spinning!";
					CancelInvoke( "ClearTextToShow" );
					Invoke( "ClearTextToShow", 1.5 );
				}
			}
			else if ( touchedObject ) // list is empty, so add the object as it is not rotating
			{
				rotatingObjects.Add( touchedObject );
				
				textToShow = "That cube is now spinning!";
				CancelInvoke( "ClearTextToShow" );
				Invoke( "ClearTextToShow", 1.5 );
			}
		break;
		
		case MousePhase.Moved :
			// check if there is a gameObject stored in the variable
			if ( touchedObject )
			{
				// Get movement of the finger since last frame
				var touchDeltaPosition : Vector3 = currMousePos - lastMousePos;
				
				// Move object across XY plane
				//touchedObject.Translate( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
				touchedObject.position += new Vector3( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
			}
		break;
		
		case MousePhase.Ended :
			// remove the reference to the gameObject
			touchedObject = null;
		break;
		
		default :
			
		break;
	}
	
	
	// check if there are any items in the list
	// if so, rotate the objects
	if ( rotatingObjects.Count > 0 )
	{
		for ( var r : int = 0; r < rotatingObjects.Count; r ++ )
		{
			if ( rotatingObjects[ r ] )
			{
				rotatingObjects[ r ].Rotate( 0, 0, rotationSpeed * Time.deltaTime );
			}
		}
	}
}

========================================================================

Edited Answer 2 considering the OPs code and requirements :

OK, so I got a bit carried away in my last edit, thinking about what I thought it should be rather than what you wanted.

The answer is to store all your rotating objects in a List. Here is a great resource on using List and Array in Unity : http://wiki.unity3d.com/index.php?title=Which_Kind_Of_Array_Or_Collection_Should_I_Use?

  • create a new scene
  • create some cubes at random positions

attach this script to an empty gameObject or the camera :

#pragma strict

// to use List
import System.Collections.Generic;

public var rotationSpeed : float = 180.0;
public var moveSpeed : float = 0.05;

var touchedObject : Transform; // private var, left public for testing
var rotatingObjects : List.< Transform >; // private var, left public for testing


function Start() 
{
	rotatingObjects = new List.< Transform >();
}


function Update() 
{
	// to use mouse inputs in the editor
	// and device touch inputs in build
	#if UNITY_EDITOR
	UsingMouseInputs();
	#else
	UsingTouchInputs();
	#endif
}


// --


function UsingTouchInputs() 
{
	// has the screen got a touch?
	if ( Input.touchCount > 0 )
	{
		// what is the current state of the touch 0?
		switch( Input.GetTouch(0).phase )
		{
			case TouchPhase.Began :
				// get the touch position on the screen
				var touchPos : Vector3 = new Vector3( Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0 );
				
				// create a Ray from the touch position
				var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
				
				// create a RaycastHit variable to gather Raycast information
				var hit : RaycastHit;
				
				// cast a ray
				// ideally this would be done using a layermask
				if ( Physics.Raycast( ray, hit, 1000 ) )
				{
					// check the hit object by name
					// ideally this would be done by checking the tag
					if ( hit.collider.gameObject.name == "Cube" )
					{
						// if the object is a cube
						// store a reference to the object 
						touchedObject = hit.transform;
					}
				}
				
				// check if there are any items in the list
				if ( rotatingObjects.Count > 0 )
				{
					// check if the touchedObject is in the rotatingObjects list
					var inList : boolean = false;
					
					for ( var i : int = 0; i < rotatingObjects.Count; i ++ )
					{
						// if it is, then remove it from the list
						if ( rotatingObjects[ i ] == touchedObject )
						{
							rotatingObjects.RemoveAt( i );
							
							inList = true;
							
							break;
						}
					}
					
					// if not, add it to the list
					if ( !inList && touchedObject )
					{
						rotatingObjects.Add( touchedObject );
					}
				}
				else if ( touchedObject ) // list is empty, so add the object as it is not rotating
				{
					rotatingObjects.Add( touchedObject );
				}
			break;
			
			case TouchPhase.Moved :
				// check if there is a gameObject stored in the variable
				if ( touchedObject )
				{
					// Get movement of the finger since last frame
					var touchDeltaPosition : Vector2 = Input.GetTouch(0).deltaPosition;
					
					// Move object across XY plane
					//touchedObject.Translate( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
					touchedObject.position += new Vector3( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
				}
			break;
			
			case TouchPhase.Stationary :
				
			break;
			
			case TouchPhase.Ended :
				// remove the reference to the gameObject
				touchedObject = null;
			break;
			
			default : // TouchPhase.Cancelled
				// remove the reference to the gameObject
				touchedObject = null;
			break;
		}
	}
	
	
	// check if there are any items in the list
	// if so, rotate the objects
	if ( rotatingObjects.Count > 0 )
	{
		for ( var r : int = 0; r < rotatingObjects.Count; r ++ )
		{
			rotatingObjects[ r ].Rotate( 0, 0, rotationSpeed * Time.deltaTime );
		}
	}
}


// --


// enumerator to emulate touch phases
enum MousePhase
{
	Idle,
	Began,
	Stationary,
	Moved,
	Ended,
	Cancelled
}

var mouseTouchPhase : MousePhase;

var lastMousePos : Vector3;
var currMousePos : Vector3;


function UsingMouseInputs() 
{
	// using mouse as I have no provisioning profile for my touch device
	if ( Input.GetMouseButtonDown(0) )
	{
		mouseTouchPhase = MousePhase.Began;
	}
	else if ( Input.GetMouseButton(0) )
	{
		mouseTouchPhase = MousePhase.Moved;
	}
	else if ( Input.GetMouseButtonUp(0) )
	{
		mouseTouchPhase = MousePhase.Ended;
	}
	else
	{
		mouseTouchPhase = MousePhase.Idle;
	}
	
	
	// get the touch position on the screen
	var touchPos : Vector3 = Input.mousePosition;
	
	lastMousePos = currMousePos;
	currMousePos = touchPos;
	
	
	// what is the current state of the touch 0?
	switch( mouseTouchPhase )
	{
		case MousePhase.Began :
			// create a Ray from the touch position
			var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
			
			// create a RaycastHit variable to gather Raycast information
			var hit : RaycastHit;
			
			// cast a ray
			// ideally this would be done using a layermask
			if ( Physics.Raycast( ray, hit, 1000 ) )
			{
				// check the hit object by name
				// ideally this would be done by checking the tag
				if ( hit.collider.gameObject.name == "Cube" )
				{
					// if the object is a cube
					// store a reference to the object 
					touchedObject = hit.transform;
				}
			}
			
			// check if there are any items in the list
			if ( rotatingObjects.Count > 0 )
			{
				// check if the touchedObject is in the rotatingObjects list
				var inList : boolean = false;
				
				for ( var i : int = 0; i < rotatingObjects.Count; i ++ )
				{
					// if it is, then remove it from the list
					if ( rotatingObjects[ i ] == touchedObject )
					{
						rotatingObjects.RemoveAt( i );
						
						inList = true;
						
						break;
					}
				}
				
				// if not, add it to the list
				if ( !inList && touchedObject )
				{
					rotatingObjects.Add( touchedObject );
				}
			}
			else if ( touchedObject ) // list is empty, so add the object as it is not rotating
			{
				rotatingObjects.Add( touchedObject );
			}
		break;
		
		case MousePhase.Moved :
			// check if there is a gameObject stored in the variable
			if ( touchedObject )
			{
				// Get movement of the finger since last frame
				var touchDeltaPosition : Vector3 = currMousePos - lastMousePos;
				
				// Move object across XY plane
				//touchedObject.Translate( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
				touchedObject.position += new Vector3( touchDeltaPosition.x * moveSpeed, touchDeltaPosition.y * moveSpeed, 0 );
			}
		break;
		
		case MousePhase.Ended :
			// remove the reference to the gameObject
			touchedObject = null;
		break;
		
		default :
			
		break;
	}
	
	
	// check if there are any items in the list
	// if so, rotate the objects
	if ( rotatingObjects.Count > 0 )
	{
		for ( var r : int = 0; r < rotatingObjects.Count; r ++ )
		{
			if ( rotatingObjects[ r ] )
			{
				rotatingObjects[ r ].Rotate( 0, 0, rotationSpeed * Time.deltaTime );
			}
		}
	}
}

Hopefully I got it right this time. The end result here is the same as my original answer, but use a list instead of a boolean.


Edited Answer with an alternate method using rays :

I have made an example script of how you would move and rotate a selected object while dragging. Again, without knowing the specifics of what you are trying to achieve, I have made it for a camera with an Orthographic projection, and keeping the different objects at the same distance away from the camera.

I don’t have any way to test this on a touch device, so I have written it to work with a mouse while running in the editor. It compiles and is tested and working, so it should (hopefully) work when built out to a device.

Again, I have left a lot of comments throughout the process, hopefully this will give you a starting point to writing your own code specific to your needs.

This script will move and rotate cubes while being touched and dragged around the screen.

  • Create a new scene
  • set the camera projection to Orthographic
  • set the camera size to 7
  • create several cubes and randomly place them in the scene, leaving the position z at 0

attach this script to an empty gameObject or the camera :

#pragma strict

public var rotationSpeed : float = 180.0;
public var distanceFromCamera : float = 9.7;

var touchedObject : Transform; // private var, left public for testing


function Update() 
{
	// to use mouse inputs in the editor
	// and device touch inputs in build
	#if UNITY_EDITOR
	UsingMouseInputs();
	#else
	UsingTouchInputs();
	#endif
}


// --


function UsingTouchInputs() 
{
	// has the screen got a touch?
	if ( Input.touchCount > 0 )
	{
		// get the touch position on the screen
		var touchPos : Vector3 = new Vector3( Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 0 );
		
		// create a Ray from the touch position
		var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
		
		
		// what is the current state of the touch 0?
		switch( Input.GetTouch(0).phase )
		{
			case TouchPhase.Began :
				// create a RaycastHit variable to gather Raycast information
				var hit : RaycastHit;
				
				// cast a ray
				// ideally this would be done using a layermask
				if ( Physics.Raycast( ray, hit, 1000 ) )
				{
					// check the hit object by name
					// ideally this would be done by checking the tag
					if ( hit.collider.gameObject.name == "Cube" )
					{
						// if the object is a cube
						// store a reference to the object 
						touchedObject = hit.transform;
					}
				}
			break;
			
			case TouchPhase.Moved :
				// check if there is a gameObject stored in the variable
				if ( touchedObject )
				{
					// move the object to underneath the touch position
					touchedObject.position = ray.origin + ( ray.direction * distanceFromCamera );
					
					// rotate the object
					touchedObject.Rotate( 0, 0, rotationSpeed * Time.deltaTime );
				}
			break;
			
			case TouchPhase.Stationary :
				// check if there is a gameObject stored in the variable
				if ( touchedObject )
				{
					// rotate the object
					touchedObject.Rotate( 0, 0, rotationSpeed * Time.deltaTime );
				}
			break;
			
			case TouchPhase.Ended :
				// remove the reference to the gameObject
				touchedObject = null;
			break;
			
			default : // TouchPhase.Cancelled
				// remove the reference to the gameObject
				touchedObject = null;
			break;
		}
	}
}


// --


// enumerator to emulate touch phases
enum MousePhase
{
	Idle,
	Began,
	Stationary,
	Moved,
	Ended,
	Cancelled
}

var mouseTouchPhase : MousePhase;


function UsingMouseInputs() 
{
	// using mouse as I have no provisioning profile for my touch device
	if ( Input.GetMouseButtonDown(0) )
	{
		mouseTouchPhase = MousePhase.Began;
	}
	else if ( Input.GetMouseButton(0) )
	{
		mouseTouchPhase = MousePhase.Moved;
	}
	else if ( Input.GetMouseButtonUp(0) )
	{
		mouseTouchPhase = MousePhase.Ended;
	}
	else
	{
		mouseTouchPhase = MousePhase.Idle;
		
		return;
	}
	
	
	// get the touch position on the screen
	var touchPos : Vector3 = Input.mousePosition;
	
	// create a Ray from the touch position
	var ray : Ray = Camera.main.ScreenPointToRay( touchPos );
	
	
	// what is the current state of the touch 0?
	switch( mouseTouchPhase )
	{
		case MousePhase.Began :
			// create a RaycastHit variable to gather Raycast information
			var hit : RaycastHit;
			
			// cast a ray
			// ideally this would be done using a layermask
			if ( Physics.Raycast( ray, hit, 1000 ) )
			{
				// check the hit object by name
				// ideally this would be done by checking the tag
				if ( hit.collider.gameObject.name == "Cube" )
				{
					// if the object is a cube
					// store a reference to the object 
					touchedObject = hit.transform;
				}
			}
		break;
		
		case MousePhase.Moved :
			// check if there is a gameObject stored in the variable
			if ( touchedObject )
			{
				// move the object to underneath the touch position
				touchedObject.position = ray.origin + ( ray.direction * distanceFromCamera );
				
				// rotate the object
				touchedObject.Rotate( 0, 0, rotationSpeed * Time.deltaTime );
			}
		break;
		
		case MousePhase.Ended :
			// remove the reference to the gameObject
			touchedObject = null;
		break;
		
		default :
			
		break;
	}
}

Hope this helps, Happy Coding =]


Original answer using the OPs code :

First, remember to separate your switch cases with a break;

Hopefully the comments in this example script will explain the steps.

Store the rotation state in a global boolean variable, then change the state of this boolean for each touch down.

If you only want the object to be moved while rotating, use an if-else conditional to check if isRotating before getting the delta and moving the object.

// move speed
var speed : float = 2.0;

// rotation speed
var rotspeed : float = 5.0;

// we want to know if the object is already rotating or not
var isRotating : boolean = false;

function Update()
{
	// has the screen got a touch?
	if ( Input.touchCount > 0 )
	{
		// what is the current state of the touch 0?
		switch ( Input.GetTouch(0).phase )
		{
			// touch down
			case TouchPhase.Began :
				/*
				// are we rotating?
				if ( isRotating ) // yes
				{
					// stop rotating
					isRotating = false;
				}
				else // no
				{
					// start rotating
					isRotating = true;
				}
				*/
				// all the above if-else can be done with one line
				isRotating = !isRotating; // the boolean is now equal to the opposite of the current boolean state
			break; // don't forget the break after each case
			
			// touch moved
			case TouchPhase.Moved :
				// If you only want the object to be moved while rotating, use an if-else conditional
				// if ( isRotating )
				// {
					// Get movement of the finger since last frame
					var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;

					// Move object across XY plane
					transform.Translate (touchDeltaPosition.x * speed,
						touchDeltaPosition.y * speed, 0);
				//}
			break;
		}
	}
	
	// if we are rotating, rotate the object!
	if ( isRotating )
	{
		transform.Rotate(0,0,rotspeed*Time.deltaTime);
	}
}

Thanks buddy....you are awesome :-)

@alucardj : there is an other problem...i have linked my script with my object but touching anywhere on screen is making my object to do actions written in my script?I want actions to be performed only when i touch my object.

I have edited my answer to show how to select an object, rotate and drag it, then deselect it on release.

Thanks for help.I wanted my my object when touched once should start rotating and on next touch it should stop rotating.and if my object is dragged then it should move according to drag on screen.Thanks once again for your help....hopefully i will be able to do it.

Ok, I think I've finally understood and have a solution for you. The final actual answer is to store all your touched objects in a List. If you touch an object and it is in the List, Remove it. If you touch an object and it is not in the List, then Add it. Then at the end, rotate all the objects in the List. Basically this is using a list of objects instead of the original boolean.

Hey @AlucardJay ! Can you please help me on this?
I can make this rotate around with keyboard but I cant make it work with touch controls.
I want to make the player move along the radius to the left when i touch the left side of the screen.