简体   繁体   English

如果发生了什么事怎么办 make number - 1

[英]How to do if something happened make number - 1

I am trying to do when i destroy all boxes something happen.当我销毁所有盒子时,我正在尝试做某事。 My code is;我的代码是;

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


public class destroy : MonoBehaviour
{

private string BALL_TAG = "ball";
public AudioClip coin;
public AudioSource src;
public float numBox = 120f;
public bool isDestroyed;




private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag(BALL_TAG))
    {
        src.clip = coin;
        src.Play();
        Destroy(gameObject);
        isDestroyed = true;

    }
}

private void Update()
{
    boxes();
}

public void boxes()
{
    if(isDestroyed == true)
        numBox -= 1f;

    if(numBox == 119)
        SceneManager.LoadScene("mainManu");
}

private IEnumerator Two()
{
    yield return new WaitForSeconds(1f);
    Destroy(gameObject);
}

} }

But it doesn't work.但它不起作用。 It is suppose to do when I broke 1 box it sends me to menu.假设当我打破 1 个盒子时它会将我发送到菜单。 I think its problem in "numBox -= 1f;"我认为它的问题在于“numBox -= 1f;” because I don't know hot to make this.因为我不知道做这个很热。

I don't understand your code completely.我不完全理解你的代码。 So, I need to make some assumptions.所以,我需要做一些假设。 I think the Script is attached to the box and every box has this Script.我认为脚本附在盒子上,每个盒子都有这个脚本。 I also think, that your player Shoots Ball.我也认为,你的球员投篮。 Those Balls have a collider with an ball tag.这些球有一个带有球标签的对撞机。

There are multiple problems with your code.您的代码存在多个问题。

The first one is, that your count variable, numBox, is saved in your destroy Script, which is placed on each box.第一个是,您的计数变量 numBox 保存在您的销毁脚本中,该脚本放置在每个盒子上。 this means, that every Box is counting for itself.这意味着,每个 Box 都在为自己计数。

You have to centralize this.你必须集中这个。 There are multiple ways for doing this.有多种方法可以做到这一点。 One way is to declare this variable as static( https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/static ) This is not best practice, but works.一种方法是将此变量声明为静态( https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/static )这不是最佳实践,但有效。

A Better way is to have a Script on Your Player, which holds this number and every Box searches for this Script and change this number if it is destroyed.一个更好的方法是在你的播放器上有一个脚本,它保存这个数字,每个盒子都会搜索这个脚本,如果它被破坏了就改变这个数字。

The second big Problem is, that your are doing some really weird thing in your Update and the collision handling第二个大问题是,您在更新和碰撞处理中做了一些非常奇怪的事情

First of all, you are setting isDestroyed to true.首先,您将isDestroyed设置为 true。 Then in your boxes method, which is called in every Frame, you are decrementing your numBox variable by one, if this is Destroyed is true.然后在每个 Frame 中调用的 box 方法中,如果这是 Destroyed 为真,则将numBox变量减一。

So if your Box gets hit, you are decrementing every frame.因此,如果您的 Box 被击中,您将减少每一帧。

After that you are checking every frame if your numBox is 119 If so, you change the Scene.之后,如果您的 numBox 为 119,您将检查每一帧。如果是,则更改场景。

This is the reason, why you are getting to your MainMenu after only one boy这就是为什么你只在一个男孩之后才进入 MainMenu 的原因

This behaviour is very weird, because it is totally unnecessary.这种行为很奇怪,因为它完全没有必要。 You can reduce your variable directly in in your OnCollisionEnter2D Method.您可以直接在 OnCollisionEnter2D 方法中减少变量。

There are some little things, which can be improved.有一些小事,可以改进。

  1. When you are trying to play a Sound, you don't have to specify the AudioClip in code.当您尝试播放声音时,您不必在代码中指定 AudioClip。 You can assign this directly in Unity on the AudioSource Component via drag and drop.您可以在 Unity 中通过拖放直接在 AudioSource 组件上分配它。 This makes your code simpler.这使您的代码更简单。
  2. You are not calling the Two Coroutine.你没有调用两个协程。 You've specified this Coroutine but don't call it.你已经指定了这个协程,但没有调用它。
    //Script on Player
    public class PlayerBoxDestroyManager:MonoBehaviour
    {
        public int StartBoxes = 120;
        private int Boxes;
    
        private void Start()
        {
            Boxes = StartBoxes;
        }
    
        public void DestroyBox()
        {
            //Reduce our Boxes count
            //This is equal to Boxes -= 1 
            //                 Boxes = Boxes -1
            Boxes--;
    
            // If we have less or zero Boxes left, we End call our EndGame methode
            if(Boxes <= 0)
            {
                EndGame();
            }
        }
    
        private void EndGame()
        {
            // We change the Scene to the mainMenu
            SceneManager.LoadScene("mainManu");
        }
    }
    ```
//Script on all Boxes
public class Box : MonoBehaviour
{
    public string Balltag = "ball";

    //Audio Source the Audio Clip has to be assigned in the Unity editor
    public AudioSource Coin;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        //Check it colliding Object has the right Tag
        if(collision.transform.tag == Balltag)
        {
            //Get the reference to the Player Script
            PlayerBoxDestroyManager PBDM = FindObjectOfType<PlayerBoxDestroyManager>();
            //We can now access the Destroy Box Methode
            PBDM.DestroyBox();

            //Play the sound
            Coin.Play();

            //If we destroy our Object now, the Sound would also be deletet. 
            //We want to hear the sound, so we have to wait, till the sound is finished.
            StartCoroutine(WaitTillAudioIsFinished());
        }
    }

    IEnumerator WaitTillAudioIsFinished()
    {
        //we wait till the sound is finished
        while (Coin.isPlaying)
        {
            yield return null;
        }
        //if finished, we destroy the Gameobject
        Destroy(gameObject);
    }
}

I hope I helped you. If you have questions, feel free to ask. 
And sorry for my English:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM