2017-07-10 6 views
0

私のゲームの1つでは、蛇のように、部分が0.125fであると思われるバグがありますが、その間の距離は最初と2番目の部分の距離と同じです。私は、関連するコードであると信じる何誤った動き

enter image description here

 using UnityEngine; 
     using System.Collections; 
     using System.Collections.Generic; 

public class SnakeHead : MonoBehaviour 
{ 
    public float growTime = 5; 
    private float moveSpeed; 
    private Transform origin, prevPart = null; 
    private List<GameObject> snakeBodyPartsList; 
    public Mesh mesh; 
    public Material material; 
    private GameObject body, sphere; 
    private RaycastHit hit; 

    void Start() 
    { 
     sphere = GameObject.Find("Sphere"); 
     origin = new GameObject("SnakeHead Origin").transform; 
     origin.parent = sphere.transform; 
     transform.parent = origin; 
     snakeBodyPartsList = new List<GameObject>(); 
     snakeBodyPartsList.Add(gameObject); 
     StartCoroutine("addBodyPart"); 
    } 

    void Update() 
    { 
     if (Input.GetKey(KeyCode.Escape)) 
     { 
      Application.Quit(); 
     } 
     foreach (GameObject part in snakeBodyPartsList) 
     { 
      moveSpeed = 30 + (snakeBodyPartsList.Count * 2.5f); 
      if (part == gameObject) 
      { 
       if (Input.GetKey("a") || Input.GetKey("d")) 
       { 
        var turnRate = Input.GetKey("a") ? -120 : 120; 
        part.transform.parent.Rotate(0, 0, turnRate * Time.deltaTime); 
       } 
       part.transform.rotation = Quaternion.LookRotation(transform.forward, part.transform.position - sphere.transform.position); 
       part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, part.transform.forward)) * part.transform.parent.rotation; 
      } 
      else 
      { 
       part.transform.rotation = Quaternion.LookRotation(prevPart.transform.position, part.transform.position - sphere.transform.position); 
       if (prevPart != null && Vector3.Distance(part.transform.position, prevPart.position) > 0.125f) 
       { 
        // moveSpeed = moveSpeed + Vector3.Distance(part.transform.position, prevPart.position)* 100; 
        part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, -(prevPart.position - part.transform.position).normalized * 0.125f)) * part.transform.parent.rotation; 
       } 
      } 
      returnToSurface(part); 
      prevPart = part.transform; 
     } 
    } 

    private IEnumerator addBodyPart() 
    { 
     yield return new WaitForSeconds(1); 
     body = createNewGameObject(body, "Body " + snakeBodyPartsList.Count, null, mesh, material, snakeBodyPartsList[snakeBodyPartsList.Count - 1].transform.position, Vector3.one/10, true, true); 
     snakeBodyPartsList.Add(body); 
     yield return new WaitForSeconds(Mathf.Abs(growTime - 1)); 
     StartCoroutine("addBodyPart"); 
    } 

    public GameObject createNewGameObject(GameObject uGO, string Name, Transform Parent, Mesh Mesh, Material Material, Vector3 Position, Vector3 localScale, bool needsOrigin, bool needscollider) 
    { 
     uGO = new GameObject(Name); 
     if (needsOrigin) 
     { 
      origin = new GameObject("BodyPart Origin " + snakeBodyPartsList.Count).transform; 
      origin.parent = sphere.transform; 
      uGO.transform.parent = origin; 
     } 
     else 
     { 
      uGO.transform.parent = Parent; 
     } 
     uGO.gameObject.AddComponent<MeshFilter>().mesh = Mesh; 
     uGO.AddComponent<MeshRenderer>().material = Material; 
     uGO.transform.position = Position; 
     uGO.transform.localScale = localScale; 
     if (needscollider) 
     { 
      uGO.AddComponent<BoxCollider>().size = Vector3.one; 
      uGO.GetComponent<BoxCollider>().isTrigger = true; 
     } 
     uGO.transform.forward = transform.forward; 
     uGO.transform.rotation = transform.rotation; 
     return uGO; 
    } 

    void returnToSurface(GameObject a) 
    { 
     if (Vector3.Distance(a.transform.position, sphere.transform.position) > 1.05) 
     { 
      while (Vector3.Distance(a.transform.position, sphere.transform.position) >= 1.045) 
      { 
       a.transform.position = new Vector3(a.transform.position.x, a.transform.position.y, a.transform.position.z - 0.001f); 
      } 
     } 
     else if (Vector3.Distance(a.transform.position, sphere.transform.position) < 1.04) 
     { 
      while (Vector3.Distance(a.transform.position, sphere.transform.position) <= 1.045) 
      { 
       a.transform.position = new Vector3(a.transform.position.x, a.transform.position.y, a.transform.position.z + 0.001f); 
      } 
     } 

    } 
    public List<GameObject> getPartsList() 
    { 
     return snakeBodyPartsList; 
    } 
} 

私は、任意の一般的なヒントとクリーンアップは、一般的にもかなり新しい歓迎されていますので、ブロックの動きは、おそらくひどく符号化されます。ブロックは球の周りを動き回っているため、恐らく奇妙な動きのコードになります。

+0

これはまっすぐです。ヘビはoldschoolヘビゲームのように振る舞います(古いノキア3310のような)が、飛行機ではなく球で動作しますか? –

+0

かなり、私が言ったように、それをリリースしようとしていない、何か趣味の仕事。 –

+0

これは「基本的な」動きではありません。少なくともあなたが思ったほど基本的ではありません。 –

答えて

0

私はこのことについて間違っているかもしれませんが、私はコメントするのに十分な担当者を持っていないので、あなたがしようとするために、私は返事として、それを投稿します:

をあなたの問題は最初のヘッドとの間にあるので、最初の実行時にprevPartが設定されていないためです(gameObject本体の部分がforeachで最初にチェックされる必要はありません)。 foreachの前に最初のif文を処理して、最初の実行のためにすべてが正しく設定されることを保証することができます。 gameObjectの本体部分をリストの外に保つか、if(この例のように)で大文字小文字を処理することができます。このような

何か:

void Update() 
{ 
    moveSpeed = 30 + (snakeBodyPartsList.Count * 2.5f); 

    // First update the head (gameObject) 
    if (Input.GetKey("a") || Input.GetKey("d")) 
    { 
     var turnRate = Input.GetKey("a") ? -120 : 120; 
     transform.parent.Rotate(0, 0, turnRate * Time.deltaTime); 
    } 
    transform.rotation = Quaternion.LookRotation(transform.forward, transform.position - sphere.transform.position); 
    transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(transform.parent.position - transform.position, transform.forward)) * transform.parent.rotation; 
    returnToSurface(part); 
    prevPart = part.transform; 

    // Then update the body (snakeBodyPartsList) 
    foreach (GameObject part in snakeBodyPartsList) 
    { 
     if (part != gameObject) 
     { 
      if (prevPart != null) // prevPart is already used here, so you might as well check it here instead of after the next line 
      { 
       part.transform.rotation = Quaternion.LookRotation(prevPart.transform.position, part.transform.position - sphere.transform.position); 
       if (Vector3.Distance(part.transform.position, prevPart.position) > 0.125f) 
       { 
        part.transform.parent.rotation = Quaternion.AngleAxis(moveSpeed * Time.deltaTime, Vector3.Cross(part.transform.parent.position - part.transform.position, -(prevPart.position - part.transform.position).normalized * 0.125f)) * part.transform.parent.rotation; 
       } 
      } 
      else 
      { 
       Debug.Log('No prevPart in the snakeBodyPartsList foreach'); // EDIT: Might as well add something here just in case... :) 
      } 
      returnToSurface(part); 
      prevPart = part.transform; 
     } 
    } 
} 

はその助けをしていますか?

PS:動きのあるコードは私にはうまく見えますが、わかりやすくするためにあなたのマジックナンバーに変数名を付けることをお勧めします。

+0

よく、私は考えを理解し、それに同意しますが、このコードは実装されています。まったく同じエラーがそれ自体現れる。コードをクラス全体で更新し、prevPartもnullとして初期化されるため、そのように干渉してはいけません。 –

0

これは、旋回中に頭の移動速度を半分にすることで解決されました。なぜ頭が頭よりも速く動いて体の部分から引き離されます。 solent uniから@ Bruinsに感謝します。