【问题标题】:Public Dictionary in UnityUnity 中的公共词典
【发布时间】:2016-06-18 21:27:24
【问题描述】:

我如何制作公共字典,我在 Unity 的其他脚本和对象中使用什么?我在对象和脚本 A 中有字典,我想使用脚本/对象 B 中的命令向此字典添加值。

*例如A对象中的A脚本:*

public Dictionary<string, GameObject> dictio  = new Dictionary<string, GameObject>();

*例如B对象中的B脚本:*

答:

public Dictionary<string, GameObject> obstacleDictionary;

GameObject gob;

void Start()
{
    obstacleDictionary = new Dictionary<string, GameObject>();
    pos = transform.position;

}

乙:

Vector3 pos;
    public string openSide;
    GameObject player;
    string posString;
void Start ()
{
    player = GameObject.FindGameObjectWithTag("Player");
    pos = transform.position;
    posString = pos.x + "_" + pos.y;


    player.GetComponent<PlayerMove>().obstacleDictionary.Add(posString, gameObject); //warning

    //print(player.GetComponent<PlayerMove>().obstacleDictionary.ContainsKey("3_0"));
}

A.GetComponent<AScript>().dictio.Add("aaa", gameObject);

你能帮帮我吗?谢谢 :)

【问题讨论】:

  • 那么,有什么问题?
  • 代码无法编译或任何运行时错误?
  • 是的,我的完整项目有错误1drv.ms/u/s!AsCxyl5DQ6LHnXch-oX8HW2OaIx9
  • 能否请您在问题中发布代码和问题,谢谢
  • @Valentin 好的,我添加了代码,但是当你下载统一项目时,你会更好地理解我的意思:)

标签: c# dictionary unity3d unityscript


【解决方案1】:

我不知道什么不适合你,因为你没有提到什么可行或不可行。这是一个完整的例子:

您的ScriptA 与公共词典:

public class ScriptA : MonoBehaviour{
    public Dictionary<string, GameObject> dictio = new Dictionary<string, GameObject>();
}

您可以通过ScriptB 访问它:

public class ScriptB : MonoBehaviour{

    ScriptA scriptInstance = null;  

    void Start()
    {
      GameObject tempObj = GameObject.Find("NameOfGameObjectScriptAIsAttachedTo");
      scriptInstance = tempObj.GetComponent<ScriptA>();

      //Access dictio  variable from ScriptA
      scriptInstance.dictio.Add("aaa", gameObject);
    }
}

确保将 NameOfGameObjectScriptAIsAttachedTo 替换为附加的游戏对象名称 ScriptA

编辑

查看了您的项目并发现了问题。 obstacleDictionaryStart() 函数中初始化之前正在从另一个脚本中使用..

解决此问题的三种方法:

在您的 PlayerMove.cs 中,

1.替换public Dictionary&lt;string, GameObject&gt; obstacleDictionary;

public Dictionary&lt;string, GameObject&gt; obstacleDictionary = new Dictionary&lt;string, GameObject&gt;();

然后从Start() 函数中删除obstacleDictionary = new Dictionary&lt;string, GameObject&gt;();

如果您按照我最初的回答进行操作,但您没有这样做,它应该会起作用。您所要做的就是在 Start() 函数之外创建新实例。

2。您可以将obstacleDictionary = new Dictionary&lt;string, GameObject&gt;();Start() 函数移动到Awake() 函数,它仍然可以工作。

您的新代码:

public class PlayerMove : MonoBehaviour
{

    Vector3 pos;
    public float speed;
    public static bool inside;
    public Dictionary<string, GameObject> obstacleDictionary;

    GameObject gob;

    void Awake()
    {
        obstacleDictionary = new Dictionary<string, GameObject>();
    }

    void Start()
    {
        pos = transform.position;
    }

    void Update()
    {
        gob = GetObjectAt(transform.position);
        if (gob == null) inside = false;
        else inside = true;
        print(inside);


        #region Control
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            GameObject go = GetObjectAt(transform.position - new Vector3(speed, 0, 0));
            if (go == null || go.GetComponent<ObstacleMove>().openSide == "right")
            {
                if (inside && gob.GetComponent<ObstacleMove>().openSide == "left") inside = false;
                /*if(inside && gob.CompareTag("BigRed") && go.CompareTag("BigRed")) { }
                else */
                pos.x -= speed;
            }
        }

        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            GameObject go = GetObjectAt(transform.position + new Vector3(speed, 0, 0));
            if (go == null || go.GetComponent<ObstacleMove>().openSide == "left")
            {
                if (inside && gob.GetComponent<ObstacleMove>().openSide == "right") inside = false;
                pos.x += speed;
            }
        }

        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            GameObject go = GetObjectAt(transform.position - new Vector3(0, speed, 0));
            if (go == null || go.GetComponent<ObstacleMove>().openSide == "up")
            {
                if (inside && gob.GetComponent<ObstacleMove>().openSide == "down") inside = false;
                pos.y -= speed;
            }
        }

        else if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            GameObject go = GetObjectAt(transform.position + new Vector3(0, speed, 0));
            if (go == null || go.GetComponent<ObstacleMove>().openSide == "down")
            {
                if (inside && gob.GetComponent<ObstacleMove>().openSide == "up") inside = false;
                pos.y += speed;
            }
        }
        #endregion

        transform.position = pos;

        if (inside && gob.transform.position != transform.position)
        {
            print("change");
            ChangeObstacleDictionary(gob.transform.position, transform.position);
            gob.transform.position = transform.position;

        }
    }

    public GameObject GetObjectAt(Vector3 position)
    {
        string pos = position.x + "_" + position.y;
        if (obstacleDictionary.ContainsKey(pos) == true)
        {
            print(obstacleDictionary[pos]);
            return obstacleDictionary[pos];
        }

        else return null;
    }

    public void ChangeObstacleDictionary(Vector3 lastPosition, Vector3 newPos)
    {

        string lastPosString = lastPosition.x + "_" + lastPosition.y;
        string newPosString = newPos.x + "_" + newPos.y;

        //print("test" + lastPosString + " " + newPosString);
        if (lastPosString != newPosString)
        {
            obstacleDictionary.Remove(lastPosString);
            obstacleDictionary.Add(newPosString, gob);
        }
    }

}

3.更改脚本的执行顺序,让PlayerMove 先执行。

然后

【讨论】:

  • 这个不行,有我的项目,请查收1drv.ms/u/s!AsCxyl5DQ6LHnXch-oX8HW2OaIx9
  • @Adam 您在 1 分钟内尝试了我的解决方案?伟大的!付出一些努力以获得进一步的帮助。试试看!
  • 因为我在你之前尝试过。一切都在我的项目中
  • @Adam 看看我的编辑。你没有按照我最初的回答。提供了 2 种可能的方法来解决此问题。
  • 首先我要道歉,我没有回答。我睡在键盘上。 :D 非常感谢您对我的耐心等待,它有效。哪种方式最好?有什么区别吗?非常感谢:)
猜你喜欢
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多