- Home /
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.
Answer by AlucardJay · Dec 12, 2013 at 07:53 AM
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);
}
}
@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 thought this would come up. $$anonymous$$y answer was just showing where your code went wrong, but really you need to :
do a raycast on touch down first,
see if you hit an object
store a reference to that object
only move and rotate that object
do another raycast on touch down again
if that ray hit the same object, make that reference a null to stop rotating it
I was confused by your method of touch down again to stop rotating, and didn't know what you were actually after (like keeping the object under the finger while dragging). Normally an object becomes deselected on touch up, so I just fixed your current code. Have a look at raycasting objects. If you get stuck I shall edit my answer tonight to show how to select an object, rotate and drag it, then deselect it on release. I have some other answers out there on doing this but cannot find them right now (am busy today). Good Luck !
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.
Answer by pritxm · Jul 29, 2020 at 06:49 PM
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.
Your answer
Follow this Question
Related Questions
Input.acceleration to camera 0 Answers
UNITY3D: TEXTFILE I/O : Don't write same things 0 Answers
Disabling all renderers in Hierarchy 1 Answer
What is wrong with this script? 2 Answers
How to Make my Character Run? 1 Answer