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 :-)
– satya144@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.
– satya144I have edited my answer to show how to select an object, rotate and drag it, then deselect it on release.
– AlucardJayThanks 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.
– satya144Ok, 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.
– AlucardJay