简体   繁体   English

Unity:无法找到所有带有标签的对象

[英]Unity: can't find all objects with a tag

I'm working on a TD game, and there's an option to change volume during gameplay.我正在开发一款 TD 游戏,可以选择在游戏过程中更改音量。 It worked fine when I first wrote it, but now it doesn't, and I'm pretty sure no one changed the relevant parts.我第一次写的时候它运行良好,但现在不行了,而且我很确定没有人改变相关部分。

There are several components that I'm using.我正在使用几个组件。

First, there's a small script attached to the turrets that sets the AudioSource volume to the value set in PlayerPrefs .首先,有一个附加到炮塔的小脚本,用于将AudioSource音量设置为PlayerPrefs设置的值。 It's pretty straightforward.这很简单。

void Start () {
    SetVolume();
}

public void SetVolume() {
    if (gameObject.GetComponent<AudioSource> () == null) {
        gameObject.AddComponent<AudioSource> ();
    }
    gameObject.GetComponent<AudioSource>().volume = PlayerPrefs.GetFloat ("SFXVolume");
}

Then there's the script that's called from the volume settings.然后是从音量设置调用的脚本。 When the user slides the volume slider, the value is saved in PlayerPrefs , then I search for objects with the Turret tag and change their volume in a loop.当用户滑动音量滑块时,该值保存在PlayerPrefs ,然后我搜索带有Turret标签的对象并循环更改它们的音量。

void Start () {
    musSlider = GameObject.Find ("MusicSlider");
    sfxSlider = GameObject.Find ("SFXSlider");
    if (!(PlayerPrefs.HasKey ("MusicVolume"))) {
        PlayerPrefs.SetFloat ("MusicVolume", 1.0f);
        PlayerPrefs.SetFloat ("SFXVolume", 1.0f);
    }
    musSlider.GetComponent <Slider> ().value = PlayerPrefs.GetFloat ("MusicVolume");
    sfxSlider.GetComponent <Slider> ().value = PlayerPrefs.GetFloat ("SFXVolume");
}

public void SetSFXVolume() {
    PlayerPrefs.SetFloat ("SFXVolume", sfxSlider.GetComponent <Slider> ().normalizedValue);
    if (!(String.Equals (SceneManager.GetActiveScene ().name, "VietrixMainMenuScene"))) {
        GameObject[] turrets = GameObject.FindGameObjectsWithTag("Turret");
        for (int i = 0; i < turrets.Length; i++) {
            if (String.Equals (turrets [i].name, "Turret")) {
                Debug.Log ("Turret name: " + turrets [i].transform.parent.gameObject.name);
            } else {
                Debug.Log ("Turret name: " + turrets [i].name);
            }
            turrets[i].GetComponent<AudioSource> ().volume = PlayerPrefs.GetFloat ("SFXVolume");
        }
    }
}

And here the things go wrong.而这里出了问题。 I currently have 6 Turrets in the scene, and only 4 of them show up in the log, and their volume changes.我目前在场景中有 6 个炮塔,其中只有 4 个出现在日志中,并且它们的体积发生了变化。 All of the tags are in place, I've just checked it for the umpteenth time.所有标签都已就位,我刚刚检查了无数次。 Out of the 4 that show up, 3 have tags on the turrets themselves, and 1 has tags on both the turret and its parent object.在出现的 4 个中,3 个在炮塔本身上有标签,1 个在炮塔及其父对象上都有标签。 Out of the 2 that don't show up, 1 has the tag on the turret itself, and the other has tags on both the turret and the parent object.在没有出现的 2 个中,1 个在炮塔本身上有标签,另一个在炮塔和父对象上都有标签。

What could have happened?可能发生了什么? I'm not the only one working on this game, but the others swear they haven't touched the tags or the volume scripts.我不是唯一在做这个游戏的人,但其他人发誓他们没有触及标签或音量脚本。

Instead of manually changing the volume of each audio source, it is probably better to look into the AudioMixer which already does what you are trying to do.与其手动更改每个音频源的音量,不如查看已经执行您正在尝试执行的操作的AudioMixer Here's a tutorial on it.这是一个关于它的教程。

Using the names of GameObjects to try and find the right one isn't a great idea, since names can change (eg when they are instantiated, they will be Turret (Clone)).使用 GameObjects 的名称来尝试找到正确的名称并不是一个好主意,因为名称可以更改(例如,当它们被实例化时,它们将是 Turret (Clone))。

If you're really set on your solution, why not just do this in your VolumeSettings script in SetSFXVolume (assuming that the small script on your turrets is named AudioSourceBuddy):如果您真的对解决方案感兴趣,为什么不直接在 SetSFXVolume 的 VolumeSettings 脚本中执行此操作(假设炮塔上的小脚本名为 AudioSourceBuddy):

public void SetSFXVolume() {
    PlayerPrefs.SetFloat ("SFXVolume", sfxSlider.GetComponent <Slider> ().normalizedValue);
    if (!(String.Equals (SceneManager.GetActiveScene ().name, "VietrixMainMenuScene"))) {
        foreach(AudioSourceBuddy buddy in GameObject.FindObjectsOfType<AudioSourceBuddy >()) { 
            buddy.SetVolume();
        }
    }
}

That way you don't have to worry about looping through tags, checking names, etc. You can just find all of the sources directly.这样您就不必担心遍历标签、检查名称等。您可以直接找到所有来源。

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

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