You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. State Tracking: Added isAtMaxScale boolean to track the current scale state, so we know which target to switch to on each S press.
  2. Combined Animation: Renamed the coroutine to ScaleAndRotateOverSeconds to handle both scale and rotation. We use Quaternion.Lerp for rotation to avoid gimbal lock issues that can come with raw Euler angles.
  3. Coroutine Management: Added activeScaleRotateCoroutine reference to stop any ongoing animation when the user presses S mid-transition—this prevents overlapping animations from causing weird stutters or position jumps.
  4. Easing (Optional): Used Mathf.SmoothStep to 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.
  5. Configurable Rotation Axis: Added rotationAxis public variable so you can easily change which axis the object rotates around (Y-axis by default).

How to Use:

  1. Attach this script to your GameObject.
  2. Set the minScale and maxScale values in the Inspector.
  3. Adjust the duration to control how fast the scale/rotation animation happens.
  4. (Optional) Change the rotationAxis if you want the object to rotate around a different axis (e.g., Vector3.right for 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:13:15