2017-09-12 12 views
2

私はビデオゲームプログラミングを勉強している2年生ですが、私は今この問題を少しでも苦労しています。この問題を解決する方法に関する最善の提案。Unity3D - 方向が変わるのを防ぐ3Dキャラクター

私は、歩く、走る、ジャンプする、ダブルジャンプする、回転してカーソルに向き合うことができる3Dキャラクターを持っています。しかし、私はキャラクターが空中での動きをコントロールできるようなバグに気づいた。例えば

あなたは左Shiftキー + Wを保持することによって実行し、ジャンプした場合、あなたは前進停止して空中に残って機銃掃射を開始することができます。私はキャラクターの動きに関連していない任意のコードを削除した

void Update() 
{ 
    // Turns off all animations while in the air 
    if (isInAir) 
    { 
     animator.SetBool("Running", false); 
     animator.SetBool("Walking", false); 
    } 

    if (Input.GetKey(KeyCode.W)) 
    { 
     // If the character is not in the air then turn on the walk animation 
     if (!isInAir) 
     { 
      animator.SetBool("Walking", true); 
     } 
     transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime); 
    } 
    else if (Input.GetKey(KeyCode.S)) 
    { 
     // If the character is not in the air then turn on the walk animation 
     if (!isInAir) 
     { 
      animator.SetBool("Walking", true); 
     } 
     transform.Translate(Vector3.back * movementSpeed * Time.deltaTime); 
    } 

    if (Input.GetKey(KeyCode.A)) 
    { 
     // If the character is not in the air then turn on the walk animation 
     if (!isInAir) 
     { 
      animator.SetBool("Walking", true); 
     } 
     transform.Translate(Vector3.left * movementSpeed * Time.deltaTime); 
    } 
    else if (Input.GetKey(KeyCode.D)) 
    { 
     // If the character is not in the air then turn on the walk animation 
     if (!isInAir) 
     { 
      animator.SetBool("Walking", true); 
     } 
     transform.Translate(Vector3.right * movementSpeed * Time.deltaTime); 
    } 

    if (Input.GetKey(KeyCode.LeftShift)) 
    { 
     // If the character is not in the air then turn on the run animation 
     // and change the character's movementSpeed 
     if (!isInAir) 
     { 
      movementSpeed = runSpeed; 
      animator.SetBool("Running", true); 
     } 
    } 
    else 
    { 
     // If the character is not in the air then reset their movement speed 
     // and turn off the run animation. 
     if (!isInAir) 
     { 
      movementSpeed = walkSpeed; 
      animator.SetBool("Running", false); 
     } 
    } 

    // When a key is released, turn off the movement animations 
    // This does not cause an issue since each movement if statement turns the animation back on 
    if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D)) 
    { 
     animator.SetBool("Walking", false); 
     animator.SetBool("Running", false); 
    } 
    #endregion 

    // Jumping 
    if (Input.GetButtonDown("Jump") && jumpCounter != 2) 
    { 
     jumpCounter++; 
     isInAir = true; 
     myRigidbody.AddForce(new Vector3(0, jumpForce)); 
     if (jumpCounter == 1) 
     { 
      firstJumpStamp = Time.time; 
     } 
    } 

    if(Physics.Raycast(groundCheckRay, groundCheckRayDistance) && Time.time > firstJumpStamp + 0.5f) 
    { 
     jumpCounter = 0; 
     isInAir = false; 
    } 
} 

は、ここに私のコードです。

誰も私がこの仕事をするために使用できる方法について私に示唆を与えることができますか?

私はこの問題、ただの提案を修正するためのコードを求めていないよ...私は自分自身でこれを学ぶ必要があるように私は感じ

、私はちょうど私を指すように誰かを必要とします方向。

コードの一部を理解していない場合は、お気軽にお問い合わせください。私が喜んで行っていることをお見せします。 :)例えば、ある種の行を書くより良い方法を知っているかもしれません。

(私はそれを超える100%のコントロールを持っていないとき、それは難しい動きをするために見つけるので、私はInput.GetAxisかかわらを使用して回避しようとします)

+0

? –

+0

Input.GetKey(KeyCode.A)とKeyCode Dを確認してから、文字を左右に翻訳するだけです。 コードはS –

答えて

4

私はあなたがあなたの要件を再評価示唆していることを比較することができますあなたが書いたものに。記述した内容とコードで行ったこととの間には若干の違いがあります。まず最初に、そのキャラクターが、前後に同じように左右どちらかに移動でき、同時に移動できないようにしたいということです。

これを助けるには、現在使用しているInput.GetKeyの代わりにInput.GetAxisを使用してください。私が提案することができます


2つ目は力を計算して、あなたのキャラクターにこれを適用するために、ローカルVector3を使用することです。 Vector3の値に基づいて、アニメーター変数を設定できます。


あなたの主な問題は、使用される移動技法で構成されています。文字を移動するのにRigidbodyを使用する代わりにTransform.Translateを使用することに決めたので、位置デルタオーバーフレームを計算する必要があります。
あなたのキャラクターは[ x:1.00f, y: 0.00f, z: 1.00f ]の位置から始まり、1の方向[ x: 0.30f, y: 0.00f, z: 0.70f ]に移動し、ジャンプすることを決めたとします。あなたがしなければならないことは、 (フレームが変更される前のもの)をつかみ、[ x:1.00f, y: 0.00f, z: 1.00f ]となり、現在の位置からそれを引きます。これは[ x:1.30f, y: 0.00f, z: 1.70f ]です。これは、前の位置デルタ([ x: 0.30f, y: 0.00f, z: 0.70f ])に等しいベクトルを返します。今度は、この位置を現在の位置に追加するだけで、同じコース(方向)にする必要があります。
これは摩擦を含まないので、あなたのキャラクターは空中で常に同じ方向に同じ速度で移動します。

あなたがコードを求めていなくても、それは(:)少なくとも私にとっては)平易な英語で、それでそれを記述するためにはるかに簡単ですので、ここでの例のコードは次のとおりです。

// value indicating what was the position before change 
Vector3 previousPosition; 

void Update() 
{ 
    // get user input as a vector 
    Vector3 horizontal = Vector3.right * Input.GetAxis("horizontal"); 
    Vector3 vertical = Vector3.forward * Input.GetAxis("vertical"); 

    bool isRunning = Input.GetKey(KeyCode.LeftShift); 
    float speedModifier = isRunning ? runSpeed : walkSpeed; 

    // add these inputs together 
    Vector3 currentVelocity = (horizontal + vertical); 

    // check if player is in mid air 
    if (IsInAir) 
    { 
     // if it is, get the previous and current positions 
     // add calculate the distance between frames 
     // and normalize it to get the movement direction 
     Vector3 currentPosition = transfor.position; 
     Vector3 direction = (currentPosition - previousPosition).Normalize(); 
     // apply movement direction to the "currentVelocity" 
     currentVelocity = direction * speedModifier * Time.deltaTime; 
    } 
    else 
    { 
     // user is not in mid air so you can just calculate 
     // the position change 
     currentVelocity = currentVelocity.Normalize() * speedModifier * Time.deltaTime; 

     if (currentVelocity != Vector3.zero) 
     { 
      animator.SetBool("walking", !isRunning); 
      animator.SetBool("running", isRunning); 
     } 
    } 

    // current position (before changes) 
    // should be copied to a previous position 
    // to calculate it in the next frame update 
    previousPosition = currentPosition; 

    // do the translation 
    transform.Translate(currentVelocity); 
} 

追加情報: 私はまだ強くキャラクターが空中にあるとき、それは速度だ「再利用」だけRigidbodyTransform.Translateから切り替えることをお勧めしてしまいます。これにより、各フレームの位置デルタを計算する必要がなくなり、使い易くなります。

+0

のチェックのすぐ下にあります。このコードは非常に専門的です。私が感銘を受けた!私が決してあなたがユニティで行うことができなかった多くのこと。 ご協力いただきありがとうございます。私はまだそれを試していないが、それは間違いなく私を助けるように見えます。私の割り当ての要件については:) 、彼らは単にだ: - 文字が前後に移動 ください - キャラクターを作成し 左右の機銃掃射 - 文字ダブルジャンプ を作る - 文字ラン を作ります - キャラクターを回すことができるようにする これは単純な要件です。私は自分の学習効果のためにそれをさらに追加しようとしています。 :) もう一度ありがとうございます! –

+0

@PierreGravelleフィードバックいただきありがとうございます。また、このコードにはジャンプロジックが含まれていません。元のコードで使用されていたコードは大丈夫だったので、私はこれを書き直さないことにしました。何かが意図したとおりに動作していないと私はそれを修正するつもりのコメントを自由に感じる、私はテストなしでこれを書いた(私はオフィスにいる、働いている:)) –

+1

ありがとうございました。私はいくつかのスペルミスを気づいたが、私はそれらに気付いてから大したことではない。 :)私がこれまでに見た唯一の問題は、speed修飾子のインラインif文がwalkSpeedでなければならないときの移動速度を使用することです。私はコード内に変数宣言を表示したことはないことを知っていますが、それは私のせいです。他のプログラマーが自分の提案を投稿するのをやめさせたくないので、私はあなたの答えを受け入れられた答えとしてマークしていません。 –

1

transformifに移動することが必要だと思います。今はあなたはオブジェクトをどちらかの方法で動かしているので、ブールを更新しないだけです。例えば

if (Input.GetKey(KeyCode.W)) 
    { 
     // If the character is not in the air then turn on the walk animation 
     if (!isInAir) 
     { 
      animator.SetBool("Walking", true); 
      transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime); //<-- New line 
     } 
     //transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime); //<-- Removed line 
    } 

あなたはすべての動きのためにこれを行う必要がありますif

あなたのコードが機銃掃射のためである
+0

私はこの質問をする前にこれを試しましたが、一度ジャンプするとあなたの動きは保存されないので動作しません。空中で止まるだけで、もう移動できません。私がしようとしているのは、ユーザーの入力なしで空中にいる間、動きを続けることです。 –

関連する問題