如果语句相互冲突,Unity 2D C#gameObject不会激活其他gameObjects。为什么呢?

时间:2017-02-07 07:52:09

标签: c# unity5 unity3d-2dtools

这款游戏的运作方式是游戏以最大的球开始。当火箭击中大球时,它会分成两个中球,然后分成两个小球。当火箭击中最小的球时,它会被摧毁。

我遇到的问题是当火箭与球发生碰撞时。火箭被摧毁,但球“不”分成两个大球等等。

我刚注意到这一点,我想知道如果我把这个代码语句转换为==“最小的球”而不是!=。

我的问题是否会得到修复
    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

1 个答案:

答案 0 :(得分:0)

您的代码比它需要的复杂得多,因此很难找到实际的错误。

首先,您的moveLeftmoveRight布尔是互斥的。你只需要其中一个。我更喜欢用public int currentDirection替换它们,你设置为1表示右键,-1表示左键。
您的新球运动方法可以简单地为:

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轴力值存储在匹配的数组中,并且无需使用开关即可轻松访问它们,否则 - 如果:

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

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

我认为球不分裂的问题与此有关 碰撞时,您通过检查其标记来检测您碰撞的球的类型。但是你总是使用相同的预制件实例化新球,我从未见过你改变标签。那你在创造什么类型的球? 如果你使用我上面描述的方法,你可以简单地指定一般标签&#34; Ball&#34;并使用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]

最后,你的碰撞不起作用的另一个原因可能是你在两个不同的地方处理它。如果你在发现与球发生碰撞后摧毁火箭,那么球还没有发生任何事情。如果球在之后检查碰撞,它很可能找不到火箭,因为你已经将它摧毁了。
一个干净的方法来解决这个问题,就是让火箭通知碰撞球:

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, + <-> -
}
P,嗯,这很多 我希望这仍然具有相关性,并且回答的问题多于提出的问题 快乐的编码!