当场景变化为统一时,保持两个游戏对象之间的链接

时间:2017-05-24 16:54:30

标签: c# button audio unity3d gameobject

我正在玩游戏,我想创建一个静音按钮。所以我为此编写了一个脚本,并将此脚本附加到一个不会在加载时销毁的游戏对象中。

我将脚本链接到主菜单中的UI按钮。当我改变场景时,这个UI按钮就会被破坏。

当我开始游戏时,我点击按钮,音频关闭,当我点击后,它会打开。

但是当我换到另一个场景,然后我回到主菜单时,我的脚本没有附加UI按钮。所以当我触摸按钮时,音频不会改变是行为

我想知道是否可以维护UI按钮和脚本之间的链接(附加到普通的GameObject),即使UI按钮被销毁了?

我试过这个:

from collections import OrderedDict
D= OrderedDict()

for elem in doubleL:
    if (elem[0], elem[1]) in D.keys():
        D[(elem[0], elem[1])].append(elem[-1])
    else:
        D[(elem[0], elem[1])] = [elem[-1]]

print(list(D.values()))

但它没有用。

我该如何解决?

非常感谢。

2 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题,但这里有一个:

步骤1:如果您还没有这样做,请在静音脚本上实现弱单例模式(现在我们称之为MuteScript.cs)。

private static MuteScript singleton {get; private set;}
private void Awake() {
    if (singleton == null) singleton = this;
    [whatever other stuff you were already doing in Awake()]
}
public static void ToggleMute(Graphic graphic)
{
    singleton._ToggleMute(graphic);
}
private void _ToggleMute(Graphic graphic)
{
    [whatever code you were running in your original mute method]
}

第2步:将简单脚本附加到UI按钮:

public class MuteButton: MonoBehaviour
{
    Graphic myGraphic;
    private void Awake() {
        myGraphic = GetComponent<Graphic>();
    }

    public void OnClick() {
        MuteScript.ToggleMute(myGraphic);
        //I assume you want to do something like change the colour of the button when
        //the player toggles it. Passing the Graphic to the MuteScript is the easiest 
        //way of doing this. If you really want to keep your code clean, though,
        //I recommend expanding the MuteButton class with methods to take care of
        //the UI side of things.
    }
}

步骤3:在Unity Editor中,设置按钮以调用自己的OnClick()方法,而不是MuteScript方法。

-

现在,当您单击该按钮时,它将调用静态MuteScript.ToggleMute(),它访问静态缓存的单例引用,该引用又指向原始对象。

Singletons和静态访问器在Unity中非常有效,因为它们可以让您不必调用像FindObjectsOfType()这样的昂贵搜索功能。唯一的问题是你必须要小心不要有单个类对象的多个副本,特别是在使用DontDestroyOnLoad()时。

答案 1 :(得分:0)

因此,更好的方法是使用Unity中的PlayerPrefs类,而不是使用脚本搜索并获取组件。从本质上讲,它将保留游戏的所有重要方面和自动填充信息。

这是一个很好的工具,适用于游戏的许多用户自定义方面。使用它时,有一个脚本(sceneController将是一个好名字)将在场景开始时运行(在0,0,0创建一个空白对象)然后在void Start()下有脚本抓取静音/取消静音按钮:GameObject.Find("MuteButton")或(我最喜欢的)为其指定一个名为MuteButton的标记并运行:GameOject.FindWithTag("MuteButton")。此外,一旦获得按钮的链接,在按下按钮时为其添加一个监听器。

还将声音管理器存储在将在整个游戏中传递的gameController中。这将控制soundManager并可以访问它。因此sceneManager还需要引用gameManager

使用仅适用于玩家偏好的脚本(如果愿意,可以使用控制器)是组织和包含用户偏好的更好方法。只是更好的清晰度和分离。

实施例

SceneController对象脚本

class SceneController {
    GameObject muteButton;

    void Start() {
        muteButton = GameObject.FindWithTag("muteButton");
        muteButton.AddListener(muteButtonCheck);
    }

    void muteButtonClick() {
        if (PlayerPrefs.GetInt("playerMute")) {
            // If 1 (on)
            // Set sound off
            PlayerPref.SetInt("playerMute", 0);
        } else {
            // It's 0 (off)
            // Set sound on
            PlayerPrefs.SetInt("playerMute", 1);
        }
    }
}