如何访问另一个场景中存在的游戏对象[重复]

Posted

技术标签:

【中文标题】如何访问另一个场景中存在的游戏对象[重复]【英文标题】:How to access gameobject present in another scene [duplicate] 【发布时间】:2018-04-03 18:57:07 【问题描述】:

我正在 unity3d 中创建一个简单的猜数字游戏。

我想在按钮单击时打开一个新场景,并从当前场景更改加载场景中存在的文本元素的文本。

我已经能够在按钮单击时打开新场景,但是我如何访问其他场景中的文本元素,以便我可以从当前场景更改其文本。 这是我到目前为止所拥有的,但它显然会抛出NullReferenceException,因为我无法从当前场景访问另一个场景中的文本元素。

SceneManager.LoadScene("End Scene");
gameResultText.text = "You Won!!";        //<-------this line throws the exception
gameResultText.color = Color.green;

【问题讨论】:

【参考方案1】:

我想出了更好的解决方案:

制作一个设置静态字符串变量的脚本。此脚本必须在您的游戏场景中,并且会保存结果。

public class ResultTextScript : MonoBehaviour

    public static string ResultText;

    void EndGame()
    if (won) //if won game
            ResultText = "You won!"
       
       else //if lost game
       
            ResultText = "You lost, try again another time!"
       
       //Change scene with SceneManager.LoadScene("");
    


将此脚本放在最终场景的结果文本中。此脚本将检索结果并显示它。

Using UnityEngine.UI;

public class EndGameDisplayResult

   Text text; 
   OnEnable()
   Text.text = ResultTextScript.ResultText
   

这样一加载新场景就会设置文本。





以前/替代方法:

如果您已经打开了场景,一种选择是在“您赢了!”中添加一个脚本。包含引用自身的静态变量的文本。

就这样吧。

public class ResultTextScript : MonoBehaviour

    public static ResultTextScript Instance;

    void Awake()
        if (Instance == null)
            Instance = this;
    

然后您可以从其他脚本中的任何位置(包括场景之间)调用对该游戏对象的引用。

点赞ResultTextScript.Instance

请注意,虽然您不能在 Awake 方法中调用引用,因为这是初始化变量的地方,但您可以在调用 Awake 方法后使用它。

基本上

    将 ResultTextScript 添加到“结束场景”中的 Text 对象中 从“游戏场景”中打开“结束场景”,例如使用您已经执行的 SceneManager 方法。 确保已加载结束场景,然后在脚本中说出您希望更改文本gameObject go = ResultTextScript.Instance.gameObject

【讨论】:

把'!='改成'==',第一个写错了。 End Scene 是包含我要更改的文本元素的场景,目前我在Game SceneEnd Scene 尚未打开。我想从Game Scene 访问End Scene 中的文本元素,以便在加载时更改其文本。 您已经使用 SceneManager 打开了场景。请看一下我现在在回答中提出的更好的解决方案。旧答案在其下方,但请查看最高答案。【参考方案2】:

我不相信有办法修改当前未打开的场景的上下文或对象。

public class GameResults 
   public static string finalText = "";

在加载场景的函数中,在调用加载场景之前,您可以像这样访问该文本:

GameResults.finalText = "You Win!"; 要么 GameResults.finalText = "You Lose!";

加载你的场景,然后在你的文本对象上给它一个这样的脚本:

using UnityEngine;
using UnityEngine.UI;
public class ResultTextScript : MonoBehaviour

    public Text textResults;
    void Start() 
        textResults = getComponent<Text>();
        if(textResults != null) 
            textResults.text = GameResults.finalText;
        
    

您还可以使用其他东西,将游戏结果存储在PlayerPrefs 中,并在结束场景开始时加载您存储在PlayerPrefs 首选项中的字符串或整数。这将帮助您避免创建不必要的类或静态变量。

所以喜欢之前你可以这样做:

PlayerPrefs.SetString("GameResults", "You Win!"); 要么 PlayerPrefs.SetString("GameResults", "You Lose!");

加载你的场景,然后在你的文本对象上给它一个这样的脚本:

using UnityEngine;
using UnityEngine.UI;
public class ResultTextScript : MonoBehaviour

    public Text textResults;
    void Start() 
        textResults = getComponent<Text>();
        if(textResults != null) 
            textResults.text = PlayerPrefs.GetString("GameResults", "");
        
    

【讨论】:

我建议的参考不会被破坏,因为它是在他正在移动的场景中,而不是在他要离开的场景中。 你能保证在调用该函数的下一行时,场景已经完全加载并且所有对象都已经开始调用了吗?另外,您的静态对象所在的实例将在他的文本对象之前完全初始化吗?你不能,因为你不知道他的层次结构是如何布置的。 @Doh09 根据他的代码,他确实卸载了旧场景。他没有覆盖默认的辅助参数LoadSceneMode.Single,它会卸载当前场景。 docs.unity3d.com/ScriptReference/… 直接引用文档When using this SceneManager.LoadScene, the loading **does not happen immediately**, it completes in the next frame. 不能保证在原始帖子中的该行运行之前调用了starts。 恐怕我以某种方式将加载误认为是附加场景加载,而不是常规场景加载。在这种情况下,您是对的,对象方法可能无法像我最初提出的那样工作。但是,新的字符串方法仍然有效。 @Doh09 是的,您的新方法将起作用,您没有存储单一行为的实例,它是一个静态字符串,在场景转换中不会变为 null。

以上是关于如何访问另一个场景中存在的游戏对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个视图控制器中访问 SpriteKit 场景的变量?

如何通过 GetComponent 从另一个游戏对象中的另一个脚本访问变量?

访问另一个场景中的变量

如何在python中从一个日期访问另一个日期的csv数据[重复]

(统一)销毁当前场景中的游戏对象并在加载当前场景后使其永久销毁?

从另一个脚本C#访问变量[重复]