You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity中如何按指定速度将Light.spotAngle从30逐步增至100?

Gradually Increase Light.spotAngle from 30 to 100 in Unity

Hey there! Let's get that spotAngle tweening working for you. The issue with your initial Time.deltaTime attempt is almost certainly that you weren't updating the value every frame — you need to run this logic repeatedly (either in Update() or a coroutine) for the gradual change to be visible. Here are two solid approaches to fix this:

Method 1: Use Update() for Frame-by-Frame Adjustment

This is perfect if you want the angle to keep increasing until it hits the target, and you want control over the speed in degrees per second.

First, define some class-level variables to track your start/target values and speed, then initialize everything in Start() and update the angle in Update():

// These variables live at the top of your MonoBehaviour class (not inside any method)
private Light spotA;
private readonly float startSpotAngle = 30f;
private readonly float targetSpotAngle = 100f;
private float angleIncreaseSpeed = 15f; // Adjust this to make it faster/slower (degrees per second)

void Start()
{
    // Grab your light component like you did before
    Transform thisLight = lightOB.transform.GetChild(0);
    spotA = thisLight.GetComponent<Light>();
    
    // Initialize the angle to your starting value
    spotA.spotAngle = startSpotAngle;
}

void Update()
{
    // Only adjust the angle if we haven't reached the target yet
    if (spotA.spotAngle < targetSpotAngle)
    {
        // Increase the angle by speed * Time.deltaTime to keep speed consistent across frame rates
        spotA.spotAngle += angleIncreaseSpeed * Time.deltaTime;
        
        // Make sure we don't overshoot the target angle
        spotA.spotAngle = Mathf.Min(spotA.spotAngle, targetSpotAngle);
    }
}

Key Notes:

  • Time.deltaTime ensures the speed stays the same no matter how fast/slow the game runs.
  • Mathf.Min() prevents the angle from accidentally going above 100 if the last frame's increment would push it over.

Method 2: Use a Coroutine for a Timed Transition

If you want the angle to transition over a specific amount of time (e.g., 2 seconds total), a coroutine is cleaner. It lets you use smooth interpolation and stops automatically once the animation is done.

// Class-level variables again
private Light spotA;
private readonly float startSpotAngle = 30f;
private readonly float targetSpotAngle = 100f;
private float transitionDuration = 2f; // Total time to go from 30 to 100 (in seconds)

void Start()
{
    Transform thisLight = lightOB.transform.GetChild(0);
    spotA = thisLight.GetComponent<Light>();
    spotA.spotAngle = startSpotAngle;
    
    // Start the animation coroutine
    StartCoroutine(AnimateSpotAngleOverTime());
}

IEnumerator AnimateSpotAngleOverTime()
{
    float elapsedTime = 0f;
    
    while (elapsedTime < transitionDuration)
    {
        // Calculate how far along we are in the transition (0 = start, 1 = finished)
        float progress = elapsedTime / transitionDuration;
        
        // Smoothly interpolate between start and target angle
        spotA.spotAngle = Mathf.Lerp(startSpotAngle, targetSpotAngle, progress);
        
        // Add the time since last frame to our elapsed time
        elapsedTime += Time.deltaTime;
        
        // Wait until the next frame before continuing the loop
        yield return null;
    }
    
    // Ensure we end exactly at the target angle (in case of floating point precision issues)
    spotA.spotAngle = targetSpotAngle;
}

Key Notes:

  • Use Mathf.Lerp() for a smooth, linear transition. If you want an ease-in/ease-out effect, you can replace progress with Mathf.SmoothStep(0f, 1f, progress).
  • You can trigger this coroutine from any event (like a button click) instead of Start() if you don't want the animation to begin immediately.

内容的提问来源于stack exchange,提问作者Anghelina Guznac

火山引擎 最新活动