0

タイマーに基づいて 2 つのオブジェクト間でターゲット lerp を作成しようとしています。

現時点では、次のコードがあります。

   float distCovered = (Time.time - waitTime) * speed;
    float fracJourney = distCovered / journeyLength;
    if (_moveDown == false)
    {
        if (startTime + waitTime < Time.time)
        {

            transform.position = Vector3.Lerp(start.position, end.position, fracJourney);

            if (transform.position == end.position)
            {
                Debug.Log("going down");
               _moveDown = true;

                transform.position = Vector3.Lerp(end.position, start.position, fracJourney);
            }


        }
    }

    if (_moveDown == true)
    {
        float distCovered1 = (Time.time - goDowntimer) * speed;
        float fracJourney1 = distCovered1 / journeyLength;
        transform.position = Vector3.Lerp(end.position, start.position, fracJourney1);

        if (transform.position == start.position)
        {
            Debug.Log("going up");
           // waitTime = 20;
            _moveDown = false;

        }

    }

このコードは update 関数にあり、上下に移動する各オブジェクトにアタッチされています。各オブジェクトは、他のオブジェクトとは独立して待機時間を設定できるため、5 秒後に 1 つの移動、10 秒後に別の移動などを行うことができます。

その後、各ターゲットは数秒待ってから下に戻ります。ただ、動きは滑らかではなく、一定の距離をジャンプしがちです。しかし、その後、底に戻ると、_movedown bool の間でおかしくなり、動かなくなります。

これらの問題を解決する方法を知っている人はいますか?

オブジェクトを常に 2 点間で前後に移動させる Mathf.PingPong メソッドは知っていますが、各セクションで移動を一時停止することはできません。とはいえ、これを行う方法を誰かが知っている場合は、私にも知らせてください。

4

3 に答える 3

1

コードの簡単なハックを次に示します。おそらくよりクリーンになる可能性がありますが、ピンチで行う必要があります。OP の if/then ブロックを、最初から最後まで移動しているか、端から最初まで移動しているかを示す「方向」変数に置き換えました。

Vector3.Lerp () は [0,1] の範囲のt値を取り、概念的には始点から終点までの % 距離です。その方向を逆にしたい場合は、範囲が [1,0] (逆方向) になるように 1 から減算するだけです。以下のdirection_で行っているのはこれだけです。fracJourney が範囲外になるとすぐに、方向を切り替え、一時停止をトリガーし、メイン タイマーをリセットします。

一時停止コードをUpdate () に入れて移動コードから分離しましたが、両方のコード ブロックをFixedUpdate () またはUpdate ()のいずれかに配置できない理由はありません。

この例は、Vector3.Lerp のドキュメントにあるものの修正版です。

// additional data members beyond Vector3.Lerp's documentation
public float PauseTime = 2.0f;
int direction_ = 1;
bool doPause_ = false;

void Update(){
    float elapsedTime = Time.time - startTime;

    //  if the elapsed time has exceeded the pause time and we're paused
    //  unpause and reset the startTime;
    if(elapsedTime > PauseTime && doPause_){
        doPause_ = false;
        startTime = Time.time;
    }
}
void FixedUpdate(){
    if(doPause_)return;

    float distCovered = (Time.time - startTime) * Speed;
    float fracJourney = distCovered / journeyLength;

    // +direction means we are going from [0,1], -direction means [1,0]
    fracJourney = (direction_>0)?fracJourney:1.0f-fracJourney;
    transform.position = Vector3.Lerp(StartPt.position, EndPt.position, fracJourney);

    // When fracJourney is not in [0,1], flip direction and pause
    if(fracJourney > 1.0 || fracJourney < 0.0){
        direction_ = -direction_;
        startTime = Time.time;
        doPause_ = true;
    }
}

私の '方向' メンバーは簡単に愚か者だったかもしれませんが、私は他の目的のために署名された方向を持っているのが好きです.

于 2013-03-28T18:35:33.513 に答える
0

意図を明確にするのに役立ついくつかのコメントを以下に追加しました。

float distCovered = (Time.time - waitTime) * speed;
float fracJourney = distCovered / journeyLength;

// Going up...
if (_moveDown == false)
{
    // Should we be checking this in the other half of the statement too?
    // Or, outside the conditional altogether?
    if (startTime + waitTime < Time.time)
    {
        transform.position = Vector3.Lerp(start.position, end.position, fracJourney);

        if (transform.position == end.position)
        {
            Debug.Log("going down");

           // The way this is structured, we're going to *immediately* fall into the
           // following block, even if that's not your intended behavior.
           _moveDown = true;

            // Going down, but with the fracJourney value as though we were going up?
            transform.position = Vector3.Lerp(end.position, start.position, fracJourney);
        }
    }
}

// As noted above, we're going to fall directly into this block on the current pass,
// since there's no *else* to differentiate them.
if (_moveDown == true)
{
    // Doesn't follow the same pattern as in the previous block, though that may be intended
    float distCovered1 = (Time.time - goDowntimer) * speed;
    float fracJourney1 = distCovered1 / journeyLength;
    transform.position = Vector3.Lerp(end.position, start.position, fracJourney1);

    if (transform.position == start.position)
    {
        Debug.Log("going up");
       // waitTime = 20;
        _moveDown = false;

       // Should there be a Lerp here, as above, to start heading back the other way again?  Or, do you need to remove the other one?
    }
}
于 2013-03-28T15:18:57.727 に答える
0

これを試して :

transform.position = Vector3.Lerp(start.position, end.position, fracJourney * Time.deltaTime);

または、おそらくこれでさえ:

transform.position = Vector3.Lerp(start.position, end.position, speed * Time.deltaTime);

x *Time.deltaTime はこのような場合、基本的に移動メソッドに x メートル/秒でオブジェクトを移動するように指示します。deltaTime がなければ、代わりにフレームあたり x メートルでこれらの動きを実行しています。

于 2013-03-28T15:15:10.727 に答える