【问题标题】:Unity C# how to share data across classes?Unity C#如何跨类共享数据?
【发布时间】:2015-03-02 16:04:16
【问题描述】:

我正在尝试开发一个统一游戏,用户可以根据输入到 texbox 的数据移动对象。但我无法将文本框中的数据应用于我想要移动的对象。 这是文本框的 C# 脚本:

using UnityEngine;
using System.Collections;

public class ButtonText : MonoBehaviour
{

private bool defineModel = false;
    string beta = "";
    public float number ;
    bool res ;

    void OnGUI()
    {
        if (!defineModel) {
                if (GUI.Button (new Rect (0, 0, 150, 20), "Define a shift"))
                                defineModel = true;
              } else {  
                        beta = GUI.TextField (new Rect (250, 157, 250, 25), beta, 40);
                         res = float.TryParse(beta, out number); 
                         if (res == false) { print("String is not a number");  }
                         else { number = float.Parse(beta);  }

                    if (GUI.Button (new Rect (300, 250, 100, 30), "OK")) {
                            if(!res) return;
                else { Debug.Log (" number = "  + number);
                                defineModel = false;
                                return; }

                        }
                }

    }

这里是创建一个在游戏中移动的球体的脚本

using UnityEngine;
using System.Collections;

public class CloneSphere : MonoBehaviour 
{
    public GameObject sphere;
    void Start() 
    {
        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); // Make a new sphere
        sphere.name = "Sphere"; // give it a name
        sphere.transform.position = new Vector3(0, 0, 0); // position the sphere
        }
    float number;

    void Update () {
    sphere = GameObject.Find("Sphere");
        float location = GetComponent<ButtonText>().number ;
        sphere.transform.Translate(0, location ,0, Space.World); 
    }
}

后一个脚本的最后两行产生错误(即,如果我将这两行注释掉,则没有错误): NullReferenceException:对象引用未设置为对象的实例。 CloneSphere.Update () (在 Assets/CloneSphere.cs:20)

这里有什么问题?我怎样才能使这个数字“位置”适用于球体的垂直移动?

【问题讨论】:

  • SO 中的 Unity 标签不适用于 Unity3d 游戏引擎。请使用 unity3d 标签。

标签: c# unity3d


【解决方案1】:

看起来您的两个脚本未附加到同一个对象:当ScriptA 调用GetComponent&lt;ScriptB&gt;() 时,假定它们已附加到同一个对象,否则它将永远无法工作。一个适用于整个加载场景(仅限活动对象)的解决方案是FindObjectOfType&lt;ScriptB&gt;()

虽然FindObjectOfType&lt;T&gt;() 不是一个很快的函数。它更适合编写玩具/测试代码,以及真正无法以任何其他方式工作的代码。 (特别是单例更快,这是一个只有一个实例的类,以及一个引用该实例的静态访问器。)

【讨论】:

  • 谢谢;这有帮助。你说得对,我将文本框和 shpere 设置为不同的游戏对象。刚才我删除了球体,然后将 CloneShpere 脚本添加到 ButtonText 对象(使用“添加组件”按钮)。球体现在移动。
  • 很高兴为您提供帮助。顺便说一句,您可以单击答案旁边的“检查”图标,将答案视为正确答案。
  • 将相同的文本框脚本附加到每个对象(例如球体)是唯一的解决方案吗?我的目标是单击文本框“确定”来定义位置的“数据集”,为许多对象中的每一个(例如可能数千个)定义一个位置。每个特定对象只需要访问其特定位置即可重新定位。因此,将整个文本框对象附加到每个球体对我来说似乎效率低下!
  • 哦,不。就像我说的,您可以使用 FindObjectOfType 而不是 GetComponent。这仍然是低效的,因此另一种选择是将数字设为静态(尽管我建议将其设为本地写入,全球读取):public static float yInput { get; private set; },然后圈子可以通过检查ButtonText.yInput 来访问它。
  • 但是这些静态变量可能会变得草率,所以如果你需要访问多个数据,最好将那个类变成一个单例:所以ButtonText.Instance 将是一个静态变量,它引用给唯一的ButtonText。在Awake 中,ButtonText 应该设置值(Instance = this;)。在这种情况下,球体会将值查询为ButtonText.Instance.yInput
猜你喜欢
  • 2012-02-01
  • 2021-11-30
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多