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

Keep Links between two gameObjects when scenes change in unity

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

我 link 主菜单中带有 UI 按钮的脚本。当我改变场景时,这个 UI 按钮被破坏了。

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

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

我想知道是否可以在 UI 按钮和脚本(附加到普通游戏对象)之间保持 link,即使 UI 按钮是销毁?

我试过这个:

ButtonGameObject = GameObject.Find("UI Button");

但是没用。

我该如何解决?

非常感谢。

因此,比使用脚本搜索和获取组件更好的方法是使用来自 Unity 的 PlayerPrefs class。本质上,它将保存游戏的所有重要方面和自动填充信息。

对于游戏的许多用户自定义方面来说,这是一个很棒的工具。使用它时,有一个脚本(sceneController 会是一个好名字)当场景开始时将 运行(在 0,0,0 处创建一个空白对象)然后在 void Start() 下让脚本抓住 mute/unmute 按钮:GameObject.Find("MuteButton") 或(我最喜欢的)给它一个名为 MuteButton 和 运行 的标签:GameOject.FindWithTag("MuteButton")。此外,一旦您获得按钮的 link,请在按下按钮时为其添加一个侦听器。

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

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

例子

场景控制器对象脚本

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

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

第 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(),它访问静态缓存的单例引用,后者又指向您的原始对象。

单例和静态访问器对于 Unity 中的效率非常有用,因为它们使您不必调用昂贵的搜索函数,例如 FindObjectsOfType()。唯一的问题是你必须小心不要让一个单例对象的多个副本-class 到处都是,尤其是在使用 DontDestroyOnLoad() 时。