【问题标题】:Keep Links between two gameObjects when scenes change in unity当场景统一变化时保持两个游戏对象之间的链接
【发布时间】:2017-05-24 16:54:30
【问题描述】:

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

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

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

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

我想知道即使 UI Button 被破坏,是否可以保持 UI Button 和脚本之间的链接(附加到普通 GameObject)?

我试过这个:

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

但它不起作用。

我该如何解决这个问题?

非常感谢。

【问题讨论】:

  • 已经讨论过好几次了。使用DontDestroyOnLoad
  • 你想在关闭游戏后保持静音吗?还是只是在应用运行期间?

标签: c# button audio unity3d gameobject


【解决方案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 编辑器中,设置您的按钮以调用其自己的 OnClick() 方法,而不是 MuteScript 方法。

-

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

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

【讨论】:

    【解决方案2】:

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

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

    还将声音管理器存储在将在整个游戏中传递的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);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-04
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多