Unity C#物体鼠标与触摸旋转功能实现问题求助
Fixing Touch Rotation in SimpleMouseRotator_E Script
Hey there! Let's get that touch rotation working for your Unity object. The core issue with your current script is that you're tracking touch input but not actually connecting it to the rotation logic—plus your whileDragging state isn't triggering correctly when using touch. Here's how to fix it step by step:
Key Issues in Your Current Script
- Touch input is being recorded (start position, direction) but never used to drive rotation.
whileDraggingis only set viaBeginDrag()/EndDrag()(likely called by UI events), but touch interactions aren't triggering these methods.- When not dragging, the script uses mouse position (not delta movement) which isn't relevant for touch-based rotation.
Modified Script with Touch Support
Here's the updated version of your script that properly handles touch input alongside mouse:
using System; using UnityEngine; using UnityStandardAssets.CrossPlatformInput; namespace UnityStandardAssets.Utility { public class SimpleMouseRotator_E : MonoBehaviour { // A mouselook behaviour with constraints which operate relative to // this gameobject's initial rotation. // Only rotates around local X and Y. // Works in local coordinates, so if this object is parented // to another moving gameobject, its local constraints will // operate correctly // (Think: looking out the side window of a car, or a gun turret // on a moving spaceship with a limited angular range) // to have no constraints on an axis, set the rotationRange to 360 or greater. public Vector2 rotationRange = new Vector2(70, 70); public float rotationSpeed = 10; public float dampingTime = 0.2f; public bool autoZeroVerticalOnMobile = true; public bool autoZeroHorizontalOnMobile = false; public bool relative = true; public GameObject reflectionprobe; private Vector3 m_TargetAngles; private Vector3 m_FollowAngles; private Vector3 m_FollowVelocity; private Quaternion m_OriginalRotation; private bool whileDragging; private void Start() { whileDragging = false; m_OriginalRotation = transform.localRotation; } private void Update() { // Handle touch input to trigger drag state if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); switch (touch.phase) { case TouchPhase.Began: BeginDrag(); break; case TouchPhase.Ended: case TouchPhase.Canceled: EndDrag(); break; } } if (whileDragging) { // Reset to original rotation for relative calculations transform.localRotation = m_OriginalRotation; // Read input from mouse OR touch (CrossPlatformInputManager handles both) float inputH = CrossPlatformInputManager.GetAxis("Mouse X"); float inputV = CrossPlatformInputManager.GetAxis("Mouse Y"); // Wrap values to avoid sudden jumps between positive/negative angles if (m_TargetAngles.y > 180) { m_TargetAngles.y -= 360; m_FollowAngles.y -= 360; } if (m_TargetAngles.x > 180) { m_TargetAngles.x -= 360; m_FollowAngles.x -= 360; } if (m_TargetAngles.y < -180) { m_TargetAngles.y += 360; m_FollowAngles.y += 360; } if (m_TargetAngles.x < -180) { m_TargetAngles.x += 360; m_FollowAngles.x += 360; } // Handle mobile vs desktop input logic #if MOBILE_INPUT if (autoZeroHorizontalOnMobile) { m_TargetAngles.y = Mathf.Lerp(-rotationRange.y * 0.5f, rotationRange.y * 0.5f, inputH * .5f + .5f); } else { m_TargetAngles.y += inputH * rotationSpeed; } if (autoZeroVerticalOnMobile) { m_TargetAngles.x = Mathf.Lerp(-rotationRange.x * 0.5f, rotationRange.x * 0.5f, inputV * .5f + .5f); } else { m_TargetAngles.x += inputV * rotationSpeed; } #else // Desktop mouse input: direct control without springback m_TargetAngles.y += inputH * rotationSpeed; m_TargetAngles.x += inputV * rotationSpeed; #endif // Clamp angles to your defined rotation range m_TargetAngles.y = Mathf.Clamp(m_TargetAngles.y, -rotationRange.y * 0.5f, rotationRange.y * 0.5f); m_TargetAngles.x = Mathf.Clamp(m_TargetAngles.x, -rotationRange.x * 1f, rotationRange.x * 0.2f); } else { // Optional: Smoothly reset angles when not dragging (adjust speed as needed) m_TargetAngles = Vector3.Lerp(m_TargetAngles, Vector3.zero, Time.deltaTime * 2f); } // Smoothly interpolate to target angles m_FollowAngles = Vector3.SmoothDamp(m_FollowAngles, m_TargetAngles, ref m_FollowVelocity, dampingTime); // Apply the final rotation transform.localRotation = m_OriginalRotation * Quaternion.Euler(-m_FollowAngles.x, m_FollowAngles.y, 0); } public void BeginDrag() { whileDragging = true; // Reset target angles to current state to avoid sudden jumps on drag start m_TargetAngles = m_FollowAngles; } public void EndDrag() { whileDragging = false; } } }
What Changed?
- Touch Input Integration: Now when a touch starts (
TouchPhase.Began), we triggerBeginDrag()to enable rotation mode. When the touch ends or is canceled, we callEndDrag()to exit rotation mode. - Removed Unused Code: Got rid of the
startPos,direction, anddirectionChosenvariables since they weren't contributing to rotation logic. - Unified Input Handling: Leveraged
CrossPlatformInputManagerwhich automatically maps touch drags to the "Mouse X" and "Mouse Y" axes—so we use the same input code for both mouse and touch. - Improved Drag Start: When starting a drag (mouse or touch), we set
m_TargetAnglesto the currentm_FollowAnglesto prevent sudden rotation jumps. - Idle Reset (Optional): Added a smooth reset to zero angles when not dragging—you can remove this if you want the object to stay in its rotated position.
Testing Tips
- In the Unity Editor, use the Simulate Touch feature (Window > Analysis > Input Debugger) to test touch input without a physical device.
- On mobile, ensure your object has a collider if you're using UI events, but this script handles touch input directly via
Input.touchCountso no extra setup is needed for basic touch rotation.
内容的提问来源于stack exchange,提问作者Constantin Finkbeiner
相关产品推荐
相关产品推荐

