2017-02-07 3 views
0

このゲームの仕組みは、ゲームが最大のボールで始まることです。ロケットが大きなボールに当たると、2つの中ボールと2つの小さなボールに分かれます。ロケットが最小のボールに当たると、ロケットは破壊されます。Unity 2D C#gameObjectは、互いに衝突したときに、他のgameObjects if文をアクティブにしません。どうして?

私が抱えている問題は、ロケットがボールと衝突したときです。ロケットは破壊されますが、ボールは2つの大きなボールなどに分けられません。

私はちょうどこれに気付きましたが、このコード文を== "最小のボール"にすると問題が解決するかどうかは疑問です。

if (target.tag == "Rocket") 
    { 
     if (gameObject.tag != "Smallest Ball") 
     { 
      InstantializeBallsonoff(); 
     } 
     else { 
      AudioSource.PlayClipAtPoint(popsounds[Random.Range(0, popsounds.Length)], transform.position); 
      //play random audio in the popsounds array at current position of ball 
      gameObject.SetActive(false); //deactivate the gameobject 
     } 
    } 
}//ontriggerenter 

これは私のボールスクリプト

using UnityEngine; 
using System.Collections; 

public class Ball : MonoBehaviour { 

private float forceX, forceY; 
private Rigidbody2D ball; 

[SerializeField] 
private bool moveLeft, moveRight; 

[SerializeField] 
private GameObject originalBall; 

private GameObject ball1, ball2; 
private Ball ball1script, ball2script; 

[SerializeField] 
private AudioClip[] popsounds; //array 

// Use this for initialization 
void Awake() { 
    ball = GetComponent<Rigidbody2D>(); 
    ballspeed(); 
} 

// Update is called once per frame 
void Update() { 
    ballmovement(); 
} 

void InstantiatingBalls() 
{ 
    if (this.gameObject.tag != "Smallest Ball") 
    { 
     ball1 = Instantiate(originalBall); //create copy of originalball into ball1 
     ball2 = Instantiate(originalBall); 

     ball1.name = originalBall.name; 
     ball2.name = originalBall.name; 

     ball1script = ball1.GetComponent<Ball>(); //get the ball script 
     ball2script = ball2.GetComponent<Ball>(); 

    } 
}//InstantiatingBalls 

void InstantializeBallsonoff() { 
    InstantiatingBalls(); 

    Vector3 temp = transform.position; //start from current ball location 
    ball1.transform.position = temp; 
    ball1script.setmoveLeft(true); 
    ball2.transform.position = temp; 
    ball2script.setmoveRight(true); 

    ball1.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 2.5f); //x,y 
    ball2.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 2.5f); //x,y 

    AudioSource.PlayClipAtPoint(popsounds[Random.Range(0, popsounds.Length)], transform.position); 
    //play random audio in the popsounds array at current position of ball 
    gameObject.SetActive(false); //deactivate the gameobject 

}//InstantializeBallsonoff 

public void setmoveLeft(bool moveLeft) { //canMoveLeft 
    this.moveLeft = moveLeft; 
    this.moveRight = !moveLeft; //moveRight is now false b/c we set moveLeft to true 
} 

public void setmoveRight(bool moveRight) {//canMoveRight 
    this.moveRight = moveRight; 
    this.moveLeft = !moveRight; 
} 

void ballmovement() { 
    if (moveLeft) { 
     Vector3 temp = transform.position; //current position of ball 
     temp.x -= Time.deltaTime; // represent time per frame 
     transform.position = temp; 
    } 

    if (moveRight) { 
     Vector3 temp = transform.position; //current position of ball 
     temp.x += Time.deltaTime; // represent time per frame 
     transform.position = temp; 
    } 
} 

void ballspeed() { 
    forceX = 2.5f; 

    switch (this.gameObject.tag) { 
     //this refers to gameobject that holds this script 

     case "Largest Ball": 
      forceY = 11.5f; 
      break; 
     case "Large Ball": 
      forceY = 10.5f; 
      break; 
     case "Medium Ball": 
      forceY = 9f; 
      break; 
     case "Small Ball": 
      forceY = 8f; 
      break; 
     case "Smallest Ball": 
      forceY = 7f; 
      break; 
    }//switch 

}//ballspeed 

void OnTriggerEnter2D (Collider2D target) { 
    if (target.tag == "Ground") { 
     ball.velocity = new Vector2(0, forceY); 
    } 

    if (target.tag == "Right Wall") { 
     setmoveLeft(true); 
     /*moveRight = false; 
     moveLeft = true;*/ 
    } 

    if (target.tag == "Left Wall") 
    { 
     setmoveRight(true); 
     /*moveRight = true; 
     moveLeft = false;*/ 
    } 

    if (target.tag == "Rocket") 
    { 
     if (gameObject.tag != "Smallest Ball") 
     { 
      InstantializeBallsonoff(); 
     } 
     else { 
      AudioSource.PlayClipAtPoint(popsounds[Random.Range(0, popsounds.Length)], transform.position); 
      //play random audio in the popsounds array at current position of ball 
      gameObject.SetActive(false); //deactivate the gameobject 
     } 
    } 
}//ontriggerenter 


}//ball 

それは大きなボール&トップに衝突した際のロケットが破壊ますここは私のコードの一部であるため、完全なコードです。これは私が問題を抱えている部分です。

void OnTriggerEnter2D(Collider2D target) { 
    if (target.tag == "Top") { 
     Destroy(gameObject); 
    } 

    string[] ballhit = target.name.Split(); 
    /*array ballhit 
    split = deletes the space between two words and make it so it takes 2 spaces in the array*/ 

    for (int s = 0; s < ballhit.Length; s++) { 
     Debug.Log("The array contains: " +ballhit [s]); 

     if (ballhit.Length > 1) 
     { //ball names will always be more than 1 length "Largest Ball" 
      if (ballhit[1] == "Ball") 
      { 
       Destroy(gameObject); 
      }//destroy object 
     }//ballhit name length 
    }// name increments 

}//triggerCollider 

これは私の完全なロケットスクリプト

using UnityEngine; 
using System.Collections; 

public class Rocket : MonoBehaviour { 

private Rigidbody2D rocket; 
private float speed = 5f; 


// Use this for initialization 
void Awake() { 
    rocket = GetComponent<Rigidbody2D>(); 
} 

// Update is called once per frame 
void Update() { 
    rocket.velocity = new Vector2(0, speed); //x, y rocket movement 
} 

void OnTriggerEnter2D(Collider2D target) { 
    if (target.tag == "Top") { 
     Destroy(gameObject); 
    } 

    string[] ballhit = target.name.Split(); 
    /*array ballhit 
    split = deletes the space between two words and make it so it takes 2 spaces in the array*/ 

    for (int s = 0; s < ballhit.Length; s++) { 
     Debug.Log("The array contains: " +ballhit [s]); 

     if (ballhit.Length > 1) 
     { //ball names will always be more than 1 length "Largest Ball" 
      if (ballhit[1] == "Ball") 
      { 
       Destroy(gameObject); 
      }//destroy object 
     }//ballhit name length 
    }// name increments 

}//triggerCollider 

}//rocket 

答えて

0

あなたのコードは、それがため、実際のエラーを見つけるのは困難であるであることが必要であるよりも、はるかに複雑です。

まず、moveLeftmoveRightのboolは互いに排他的です。それらのうちの1つだけが必要です。私はイベントを両方ともpublic int currentDirectionに置き換えることを好みます。これは右に1、左に-1と設定します。
新しいballMovement方法は、単純に次のようになります。あなたが衝突しているボールのタイプとあなたがチェック

void MoveBall() // C# methods are upper-case by convention 
{ 
    transform.position += Vector3.right * currentDirection * Time.deltaTime; 
} 

の方法は、非常に安全ではありません。私はボールのサイズを区別するために列挙型を使用することをお勧めします。

public enum BallSizes { Largest, Large, Medium, Small, Smallest }; // The different possible values 
public BallSize size = BallSizes.Largest;        // The balls current size, the biggest size by default 

これも、あなたは、一致する配列にあなたのy軸力値を保存し、スイッチを使用せずに簡単にアクセスできるようにするか、他-IF:

private float[] forcesY = new float[]{ 11.5f, 10.5f, 9f, 8f, 7f }; 

void SetBallSpeed() 
{ 
    forceX = 2.5f; 
    forceY = forcesY[(int)size]; 
} 

私はこの問題を考えますあなたはボールが分割されていなかったので、これに接続されています。
衝突時に、衝突したボールの種類を、そのタグを調べて検出しました。しかし、あなたは常に同じプレハブを使って新しいボールをインスタンシエートし、あなたはタグを変更するのを見たことはありません。どのようなタイプのボールを作成していますか?
上記の方法を使用する場合は、一般的なタグ「ボール」を割り当て、残りの部分をBallSizes-enumで処理するだけです。新しいボールを作成するときに次のことができます。

[SerializedField]   // The SerializedField property makes it show up in the inspector, even though it is private 
private Ball ballPrefab;  // Attention: Type "Ball" 

public void IsHit()   // Method to execute upon rocket collision 
{ 
    if(ball.size != BallSizes.Smallest) 
    { 
     Ball leftBall = Instantiate(ballPrefab). // Notice that, when you assign you prefab as Type "Ball", you directly get the Ball-Component as the return value. 
     leftball.direction = -1; 
     leftball.size = (BallSizes)(size + 1); // Add one to size, to get get the next enum value, which is the next smaller size. 

     Ball rightBall = ....      // Do same stuff for the right ball 
    } 

    Destroy(this.gameObject); 
} 

私はあなたがボールの種類を視覚化する計画方法を知りませんが、あなたはボールの実際を縮小するために使用され、float[] ballScalesを追加したい場合がありますサイズは、leftBall.transform.localScale = Vector3.one * ballScales[(int)size]のようになります。

最後に、あなたの衝突がうまくいかない別の理由は、あなたが2つの異なる場所でそれを処理している可能性があります。ロケットがボールとの衝突を検出した後にロケットを破壊すると、まだボールに何も起こっていません。その後ボールが衝突をチェックしている場合、あなたはすでにそれを破壊しているため、ロケットを見つけることはほとんどないでしょう。

void OnTriggerEnter2D(Collider2D target) 
{ 
    if(target.tag == "Top") 
     Destroy(gameObject); 
    else if(target.tag == "Ball") 
    { 
     target.GetComponent<Ball>().IsHit(); // We know this component should exist when the object is tagged "Ball" 
     Destroy(gameobject); 
    } 
} 

あなたは、あなたのボールの衝突からということを削除し、これに、それを短縮することができます:
これを解決するためのクリーンな方法は、ロケットは衝突のボールを通知できるようになり

void OnTriggerEnter2D (Collider2D target) 
{ 
    if(target.tag == "Ground")  
     ball.velocity = new Vector2(0, forceY); 

    if(target.tag == "Right Wall" || target.tag == "Left Wall") 
     direction *= -1; // Inverts the direction, + <-> - 
} 

Phew、それはたくさんあった。
これは依然として関連性があり、より多くの質問に答えてくれることを願っています。
ハッピーコーディング!

関連する問題