Unity中实现按S键切换对象缩放并同步180度旋转的需求
Solution for Toggle Scale + Synchronized 180° Rotation
Got it, let's revamp your ScaleRotate script to handle both the toggle behavior and synchronized rotation. Here's how we'll approach it:
- Toggle Logic: Track whether the object is currently at its max scale or min scale, and switch the target scale each time the S key is pressed.
- Synchronized Rotation: Modify the scaling coroutine to simultaneously animate a 180° rotation over the same duration as the scale transition.
- Prevent Overlapping Coroutines: Keep a reference to the active coroutine so we can stop it if the user presses S mid-animation, avoiding janky behavior.
Here's the updated script:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScaleRotate : MonoBehaviour { public Vector3 minScale; public Vector3 maxScale; public float duration = 1f; // Set your preferred rotation axis here (default is Y-axis) public Vector3 rotationAxis = Vector3.up; private bool isAtMaxScale = true; private Coroutine activeScaleRotateCoroutine; private void Start() { // Initialize at max scale as requested transform.localScale = maxScale; } private void Update() { if (Input.GetKeyDown(KeyCode.S)) { // Determine the target scale based on current state Vector3 targetScale = isAtMaxScale ? minScale : maxScale; // Stop any ongoing animation to avoid conflicting movements if (activeScaleRotateCoroutine != null) { StopCoroutine(activeScaleRotateCoroutine); } // Start the combined scale + rotation animation activeScaleRotateCoroutine = StartCoroutine(ScaleAndRotateOverSeconds(targetScale, duration)); // Toggle the state for the next button press isAtMaxScale = !isAtMaxScale; } } private IEnumerator ScaleAndRotateOverSeconds(Vector3 targetScale, float seconds) { float elapsedTime = 0; Vector3 startingScale = transform.localScale; Quaternion startingRotation = transform.localRotation; // Calculate target rotation: 180 degrees around the specified axis Quaternion targetRotation = startingRotation * Quaternion.Euler(rotationAxis * 180f); while (elapsedTime < seconds) { float t = elapsedTime / seconds; // Optional: Add smooth easing for more natural movement t = Mathf.SmoothStep(0f, 1f, t); // Update scale with linear interpolation transform.localScale = Vector3.Lerp(startingScale, targetScale, t); // Update rotation using quaternion lerp to avoid gimbal lock issues transform.localRotation = Quaternion.Lerp(startingRotation, targetRotation, t); elapsedTime += Time.deltaTime; yield return null; } // Ensure we end exactly at the target values to avoid floating point errors transform.localScale = targetScale; transform.localRotation = targetRotation; // Clear the coroutine reference once the animation finishes activeScaleRotateCoroutine = null; } }
Key Changes Explained:
- State Tracking: Added
isAtMaxScaleboolean to track the current scale state, so we know which target to switch to on each S press. - Combined Animation: Renamed the coroutine to
ScaleAndRotateOverSecondsto handle both scale and rotation. We useQuaternion.Lerpfor rotation to avoid gimbal lock issues that can come with raw Euler angles. - Coroutine Management: Added
activeScaleRotateCoroutinereference to stop any ongoing animation when the user presses S mid-transition—this prevents overlapping animations from causing weird stutters or position jumps. - Easing (Optional): Used
Mathf.SmoothStepto add a subtle ease-in/ease-out to the animation, making it feel more polished. You can remove this line if you prefer a strict linear movement. - Configurable Rotation Axis: Added
rotationAxispublic variable so you can easily change which axis the object rotates around (Y-axis by default).
How to Use:
- Attach this script to your GameObject.
- Set the
minScaleandmaxScalevalues in the Inspector. - Adjust the
durationto control how fast the scale/rotation animation happens. - (Optional) Change the
rotationAxisif you want the object to rotate around a different axis (e.g.,Vector3.rightfor X-axis).
Now every time you press the S key, the object will toggle between max and min scale while completing a 180° rotation over the set duration.
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

