Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by martymcsly · Jul 01, 2012 at 08:37 AM · touchrotateinertiatouchcount

Spinning an object using touch input

Hey guys and gals,

I have literally been pulling my hair out for a few days over this. I have done countless test builds to my iPad to try to fix the issue all to no avail. I feel that I can't move on until I solve this problem.

I am simply trying to spin an object smoothly based on user touches and swipes. The code (below) which I have cobbled together from various sources (based on mouse input) is largely working as expected. It is currently configured to spin an object using one finger. However it seems that if the user spins the object leaving the first finger on the screen and places another finger down. On the release of the second finger (with the first one still touching) the object jumps to an unexpected angle! I have a feeling this should be a fairly simple fix and that I am doing something rather silly. Any input would be seriously appreciated.

Here is my current code (just attached to any object, currently using a simple cube). There is some ugly stuff here (like using onMouseDown) this is mainly so that I can test the script to some extent without having to build it each time. The unity remote is practically useless when testing touches... so damn laggy and unresponsive.

 //Start code
 
 var rotationSpeed = 2.0;
 var lerpSpeed = 1.0;
 
 private var speed = new Vector3();
 private var avgSpeed = new Vector3();
 private var dragging = false;
 private var targetSpeedX = new Vector3();
 
 function OnMouseDown() 
 {
     dragging = true;
 }
 
 function Update() {
 
 if (Input.touchCount == 1)
 {
     var theTouch : Touch = Input.GetTouch(0);
 
     if (theTouch.phase == TouchPhase.Moved)
     {
         OnMouseDown();
     }
 
     if ((theTouch.phase == TouchPhase.Ended) || (theTouch.phase == TouchPhase.Canceled))
     {
         dragging = false;
     }
  }
 
  if (Input.touchCount > 1)
 {
     dragging = false;
 }
 
     //Debug.Log ("Speed = " + speed);
     //Debug.Log ("Dragging = " + dragging);
 
     if ((theTouch.phase == TouchPhase.Moved) && dragging)
         {
         speed = new Vector3(theTouch.position.x, theTouch.position.y, 0);
         avgSpeed = Vector3.Lerp(avgSpeed,speed,Time.deltaTime * 5);
         }
 
 
     if (Input.GetMouseButton(0) && dragging) 
         {
         speed = new Vector3(-Input.GetAxis ("Mouse X"), Input.GetAxis("Mouse Y"), 0);
         avgSpeed = Vector3.Lerp(avgSpeed,speed,Time.deltaTime * 5);
         }
 
      else 
         {
         if (dragging) {
             speed = avgSpeed;
             dragging = false;
         }
         var i = Time.deltaTime * lerpSpeed;
         speed = Vector3.Lerp( speed, Vector3.zero, i);   
     }
 
     transform.Rotate( Camera.main.transform.up * speed.x * rotationSpeed, Space.World );
     transform.Rotate( Camera.main.transform.right * speed.y * rotationSpeed, Space.World );
 
 }
 
 //End code snippet
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · Mar 11, 2014 at 04:37 PM 0
Share

the simplest way is just to ADD TORQU$$anonymous$$

7 Replies

· Add your reply
  • Sort: 
avatar image
9

Answer by stek · Sep 08, 2015 at 01:37 PM

Hello!

I made this C# script. I think this is the easiest way to spin an object. Simply attach it to your object and it will spin while drag, and when you release the spin will slow down.

 using UnityEngine;
 using System.Collections;
 
 public class SpinLogic : MonoBehaviour {
 
     float f_lastX = 0.0f;
     float f_difX = 0.5f;
     float f_steps = 0.0f;
     int i_direction = 1;
 
     // Use this for initialization
     void Start () 
     {
         
     }
     
     // Update is called once per frame
     void Update () 
     {
         if (Input.GetMouseButtonDown(0))
         {
             f_difX = 0.0f;
         }
         else if (Input.GetMouseButton(0))
         {
             f_difX = Mathf.Abs(f_lastX - Input.GetAxis ("Mouse X"));
 
             if (f_lastX < Input.GetAxis ("Mouse X"))
             {
                 i_direction = -1;
                 transform.Rotate(Vector3.up, -f_difX);
             }
 
             if (f_lastX > Input.GetAxis ("Mouse X"))
             {
                 i_direction = 1;
                 transform.Rotate(Vector3.up, f_difX);
             }
 
             f_lastX = -Input.GetAxis ("Mouse X");
         }
         else 
         {
             if (f_difX > 0.5f) f_difX -= 0.05f;
             if (f_difX < 0.5f) f_difX += 0.05f;
 
             transform.Rotate(Vector3.up, f_difX * i_direction);
         }
     }
 }

I hope it helps!

Happy Coding!

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cardex107 · Nov 26, 2016 at 01:36 PM 0
Share

Thanks!!! very good and simple

avatar image
0

Answer by martymcsly · Jul 01, 2012 at 05:47 PM

Ok I found the original clean and beautiful code (from user duck) that I brutally butchered with the finesse of a drunk rhino above. Thinking about it i really wish i posted this in response to the thread i found ducks example in:

http://answers.unity3d.com/questions/34317/rotate-object-with-mouse-cursor-that-slows-down-on.html

I'm basically trying to make this work as well as it does with a mouse but with fingers on a touchscreen with no unexpected issues with potentially multiple fingers touching and releasing in the heat of action. Should be a simple conversion job, but for me it is turning into a real nightmare. I feel so stupid right now. Please don't think I'm some script kiddie that wants something for free without working for it. I literally can't get my head around what may be wrong and have spent 2 full days on this tweaking/rebuilding/failing/starting over/coming back/swearing etc. This motion working properly and reliably is the only thing holding me back and it is the main action for my game so it needs to be as efficient as possible. Thanks so much for any help, suggestions or if you must negative comments ;-)

 var rotationSpeed = 10.0;
 var lerpSpeed = 1.0;
 
 private var speed = new Vector3();
 private var avgSpeed = new Vector3();
 private var dragging = false;
 private var targetSpeedX = new Vector3();
 
 function OnMouseDown() 
 {
     dragging = true;
 }
 
 function Update () 
 {
 
     if (Input.GetMouseButton(0) && dragging) {
         speed = new Vector3(-Input.GetAxis ("Mouse X"), Input.GetAxis("Mouse Y"), 0);
         avgSpeed = Vector3.Lerp(avgSpeed,speed,Time.deltaTime * 5);
     } else {
         if (dragging) {
             speed = avgSpeed;
             dragging = false;
         }
         var i = Time.deltaTime * lerpSpeed;
         speed = Vector3.Lerp( speed, Vector3.zero, i);   
     }
 
     transform.Rotate( Camera.main.transform.up * speed.x * rotationSpeed, Space.World );
     transform.Rotate( Camera.main.transform.right * speed.y * rotationSpeed, Space.World );
 
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image justinpatterson · Feb 20, 2014 at 03:09 PM 0
Share

Hey martymcsly, did you ever manage to find a solution to this? I'm hitting a similar issue heh.

avatar image TomWong · Oct 13, 2016 at 01:11 PM 0
Share

U are my HERO ! , you save my day ...

avatar image
0

Answer by HALXP · Mar 03, 2017 at 05:59 PM

Here's my version that uses physics and touch input from a mobile device if it can help anyone

 using UnityEngine;
 using System.Collections;
 
 public class SpinWithTouch : MonoBehaviour
 {
     public Rigidbody rb;
 
     void Start()
     {
         rb = GetComponent<Rigidbody>();
     }
 
     void Update()
     {
         if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
         {
             // Get movement of the finger since last frame
             Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
 
             rb.AddTorque(Camera.main.transform.up * -touchDeltaPosition.x);
             rb.AddTorque(Camera.main.transform.right * touchDeltaPosition.y);
         }
     }
 }
 
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Voronoi · Aug 03, 2019 at 05:35 PM 0
Share

This worked really well for my needs in an AR project. I modified it below so that only objects with a collider are rotated when the touch is over the object:

 using UnityEngine;
 using System.Collections;
 
 [RequireComponent(typeof(Rigidbody))]
 public class SpinWithTouch : $$anonymous$$onoBehaviour
 {
     Rigidbody rb;
 
     void Awake()
     {
         rb = GetComponent<Rigidbody>();
     }
 
     void On$$anonymous$$ouseOver()
     {
         if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.$$anonymous$$oved)
         {
 
             // Get movement of the finger since last frame
             Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
 
             rb.AddTorque(Camera.main.transform.up * -touchDeltaPosition.x);
             rb.AddTorque(Camera.main.transform.right * touchDeltaPosition.y);
         }
     }
 }
avatar image
0

Answer by tmalhassan · Sep 16, 2017 at 03:35 AM

Following @stek very simple and very helpful example. I took his code and modified it so it can spin on both sides while accepting touch controls so it can work on mobile devices. Simply, attach the script to the spinning object. Bare with me, i am a beginner. The script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;


 public class SpinWheelScript : MonoBehaviour {


 float pointerY;
 float f_lastX = 0.0f;
 float f_difX = 0.5f;
 float f_steps = 0.0f;
 int i_direction = 1;


 void Start()
 {
     pointerY = Input.GetAxis("Mouse Y");
 }

 void Update()
 {

     if (Input.GetMouseButtonDown(0))
     {
         f_difX = 0.0f;
     }


     else if (Input.touchCount > 0)
     {
         pointerY = Input.touches[0].deltaPosition.y;
         f_difX = Mathf.Abs(f_lastX - pointerY);
         var touch = Input.GetTouch(0);

         if (touch.position.x > Screen.width / 2)
         {
             // Right
             if (f_lastX < Input.GetAxis("Mouse Y"))
             {
                 i_direction = 1;
                 transform.Rotate(Vector3.forward, f_difX * Time.deltaTime);
             }

             if (f_lastX > Input.GetAxis("Mouse Y"))
             {
                 i_direction = -1;
                 transform.Rotate(Vector3.forward, -f_difX * Time.deltaTime);
             }
         }
         else if (touch.position.x < Screen.width / 2)
         {
             // Left
             if (f_lastX < Input.GetAxis("Mouse Y"))
             {
                 i_direction = -1;
                 transform.Rotate(Vector3.forward, -f_difX * Time.deltaTime);
             }

             if (f_lastX > Input.GetAxis("Mouse Y"))
             {
                 i_direction = 1;
                 transform.Rotate(Vector3.forward, f_difX * Time.deltaTime);
             }
         }

         f_lastX = -pointerY;
         f_difX = 500f;
     Debug.Log(f_difX);
     }
     else
     {
         if (f_difX > 0.5f) f_difX -= 1f;
         if (f_difX < 0.5f) f_difX += 1f;

         transform.Rotate(Vector3.forward, f_difX * i_direction * Time.smoothDeltaTime);
     }
 }
 }

Currently, the object will spin based on a swipe along the Y axis, you can simple change it by replacing the Y's with X's. Also, i've modified the speeds to fit my liking. Hope this helps.

Cheers!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by tangowhiskeygirl · Oct 05, 2017 at 12:06 AM

I don't know if anyone else needs this. But in my case I didn't want the object to rotate, but rather rotate the camera around it, so this is the script I made (for mobile), in case anyone else wants something similar. (The swiper object is an empty gameobject which is the parent of the camera. I didn't include code to change the swiper transform to match the object since I only use one object, but that should be easy to add if you need to rotate many different things). cheers :)

 using UnityEngine;
 using UnityEngine.EventSystems;
 
 public class Rotator : MonoBehaviour, IDragHandler
 {
     public Transform world;
     public GameObject swiper;
     public float zoomSpeed;
     float direction;
 
     public void OnDrag(PointerEventData eventData)
     {
         if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
         {
 
             // Get movement of the finger since last frame
             Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
 
             //actual touch
             Touch touchZero = Input.GetTouch(0);
             //current touch x position
             float touchZeroCurrPos = touchZero.position.x;
             //previous touch x position
             float touchZeroPrevPos = touchZero.position.x - touchDeltaPosition.x;
             //difference between previous and current finger position
             float Diff = touchZeroPrevPos - touchZeroCurrPos;
 
            
             if (touchZeroCurrPos < touchZeroPrevPos )
             {
                 Debug.Log("right");
                 direction = -1;
                 swiper.transform.Rotate(Vector3.up, -Diff * Time.deltaTime * zoomSpeed);
             }
             if (touchZeroCurrPos > touchZeroPrevPos)
             {
                 Debug.Log("left");
                 direction = 1;
                 swiper.transform.Rotate(Vector3.down, Diff * Time.deltaTime * zoomSpeed);
             }
 
         }
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to scale and rotate a sprite renderer using one touch? 0 Answers

Inertia Scrolling Touch 1 Answer

how do I create a 3d model viewer app using unity 0 Answers

How to rotate an object based on angles? 1 Answer

two finger touch always detects one finger touch first 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges