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

Unity中void Update()内分步执行轨道跟随代码的问题咨询

Fixing Sequential Movement then Rotation in Unity Update Loop

It looks like your issue comes from running both the MoveTowards and rotation logic every frame simultaneously in Update(). That's why the ball jumps straight to P1 and starts rotating right away—both actions are fighting to set the position on the first frame.

To fix this, we need to add a state system to control which phase the ball is in: first moving to P1, then starting the rotation once it's arrived. Here's how to implement it step by step:

Step 1: Add a State Tracker

First, define a simple enum to track the current phase of the ball's movement. This keeps our logic clean and easy to extend if you add more steps later.

Step 2: Modify the Update Loop

Update the Update() method to only run the logic for the current state. Once the ball reaches P1, switch to the rotation state.

Full Modified Code

using UnityEngine;

public class BallController : MonoBehaviour
{
    Rigidbody rigidbody; 
    public GameObject ball; 
    Vector3 P1 = new Vector3(-5, 1.5f, 25); 
    public float theta; 

    // Enum to track our current state
    private enum BallState { MovingToP1, Rotating }
    private BallState currentState = BallState.MovingToP1;

    // Small threshold to check if we've reached P1 (adjust based on your needs)
    private float positionThreshold = 0.1f;

    void Start() { 
        rigidbody = GetComponent<Rigidbody>(); 
    } 

    void Update() { 
        switch(currentState)
        {
            case BallState.MovingToP1:
                // Move towards P1 each frame
                ball.transform.position = Vector3.MoveTowards(ball.transform.position, P1, 0.05f);

                // Check if we're close enough to P1
                if(Vector3.Distance(ball.transform.position, P1) < positionThreshold)
                {
                    // Snap to P1 exactly (optional but clean)
                    ball.transform.position = P1;
                    // Switch to rotation state
                    currentState = BallState.Rotating;
                }
                break;

            case BallState.Rotating:
                // Run rotation logic only after moving is done
                if(theta < 210)
                {
                    theta += 1;
                    ball.transform.position = Rot(theta);
                }
                break;
        }
    } 

    Vector3 Rot(float theta) // rotation by trigonometric equations 
    { 
        Vector3 P2; 
        P2.x = (3 * Mathf.Cos(theta * Mathf.PI / 180) - 3 * Mathf.Sin(theta * Mathf.PI / 180)) -8; 
        P2.y = 1.5f; 
        P2.z = (3 * Mathf.Sin(theta * Mathf.PI / 180) + 3 * Mathf.Cos(theta * Mathf.PI / 180)) + 22 ; 
        return P2; 
    }
}

Key Fixes Explained

  • State Control: The BallState enum ensures only one action runs at a time. No more conflicting position updates.
  • Position Check: Using Vector3.Distance (or Vector3.SqrMagnitude for better performance, since it avoids square root) lets us detect when the ball has reached P1. We use a small threshold instead of checking for exact equality because floating-point positions are rarely perfectly precise.
  • Clean Transition: Once the ball arrives, we snap it to P1 (optional but prevents tiny jitters) and switch to the rotation phase.

Optional Optimization

For better performance, replace Vector3.Distance with Vector3.SqrMagnitude because calculating square roots is expensive:

if((ball.transform.position - P1).sqrMagnitude < positionThreshold * positionThreshold)

Just make sure to square your threshold value to match!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:56