2017-02-07 1 views
0

Die Art, wie dieses Spiel funktioniert, ist, dass das Spiel mit einem Größten Ball beginnt. Wenn die Rakete die große Kugel trifft, teilt sie sich in zwei mittlere Kugeln und dann in zwei kleine Kugeln auf. Wenn die Rakete die kleinste Kugel trifft, wird sie zerstört.Unity 2D C# gameObject aktiviert keine anderen gameObjects if-Anweisungen, wenn sie miteinander kollidieren. Warum?

Das Problem, das ich habe, ist, dass wenn die Rakete mit dem Ball kollidiert. Die Rakete wird zerstört, aber der Ball teilt sich nicht in zwei große Bälle und so weiter.

Ich habe das gerade bemerkt und ich frage mich, ob mein Problem behoben wird, wenn ich diese Code-Anweisung auf == "kleinste Kugel" anstelle von! =.

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 

Dies ist der vollständige Code für meinen Ball Script

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 

Dies ist teilweise von meinem Code, wo die Rakete zerstört wird, wenn es mit der großen Kugel kollidiert & die Spitze. Dies ist der andere Teil, mit dem ich Probleme habe.

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 

Das ist mein voller Rocket-Script

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 

Antwort

0

Ihr Code ist viel komplizierter, als es eine damit die tatsächlichen Fehler schwierig sein muss, sind zu finden.

Zunächst einmal schließen sich Ihre moveLeft und moveRight Bools gegenseitig aus. Du brauchst nur einen von ihnen. Ich würde Ereignis bevorzugen, beide mit einem public int currentDirection zu ersetzen, den Sie auf 1 für Recht und -1 für gelassen setzen.
Ihre neue ballMovement Methode könnte dann einfach:

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

Die Art und Weisen Sie mit überprüfen, welcher Art von Ball Sie ist kollidieren nicht sehr sicher. Ich würde vorschlagen, dass Sie ein Enum verwenden, um die Ballgrößen zu unterscheiden.

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 

auch diese Weise können Sie Ihre y-Achsen-Kraftwerte in einem passenden Array speichern und sie ohne die Verwendung eines Schalters leicht zugänglich machen oder else-if:

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

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

denke ich, das Problem du hast mit dem ball nicht gespalten is ist mit diesem verbunden.
Bei einer Kollision haben Sie den Typ des Balls erkannt, mit dem Sie kollidiert sind, indem Sie dessen Tag untersucht haben. Aber du initiierst immer die neuen Bälle mit demselben Prefab, und ich habe nie gesehen, wie du das Tag änderst. Welche Art von Ball kreierst du?
Wenn Sie die oben beschriebene Methode verwenden, können Sie einfach einen allgemeinen Tag "Ball" zuweisen und den Rest mit dem BallSizes-Enum behandeln. Wenn die neuen Bälle erstellen, können Sie wie folgt vorgehen:

[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); 
} 

Ich weiß nicht, wie Sie die Art der Ball sichtbar zu machen möchten, aber Sie könnten eine float[] ballScales hinzufügen möchten, die Sie tatsächlich der Ball schrumpfen verwenden Größe, etwas wie: leftBall.transform.localScale = Vector3.one * ballScales[(int)size].

Schließlich ein anderer Grund, warum Ihre Kollision nicht funktioniert, könnte sein, dass Sie an zwei verschiedenen Stellen damit umgehen.Wenn du die Rakete zerstörst, nachdem sie eine Kollision mit dem Ball erkannt hat, ist dem Ball noch nichts passiert. Wenn der Ball danach auf Kollision prüft, wird er höchstwahrscheinlich die Rakete nicht finden, weil Sie sie bereits zerstört haben.
Eine saubere Art und Weise, dies zu lösen, wäre die Rakete den Ball von der Kollision benachrichtigen zu lassen:

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); 
    } 
} 

Anschließend können Sie das Entfernen von Ihnen Ball Kollision und verkürzen sie dies:

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, + <-> - 
} 

Puh, das war eine Menge.
Ich hoffe, dass dies noch relevant ist und mehr Fragen beantwortet, als es aufwirft.
Glückliche Codierung!

Verwandte Themen