Unity中如何按指定速度将Light.spotAngle从30逐步增至100?
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.deltaTimeensures 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 replaceprogresswithMathf.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




