【问题标题】:Struct has Transform and is stored in Dictionary<int, Struct>Struct 具有 Transform 并存储在 Dictionary<int, Struct> 中
【发布时间】:2017-04-27 14:20:01
【问题描述】:

我有一个包含字符串、布尔值和转换的结构。我的部分代码循环遍历场景中具有相关标签的每个对象,并将每个奇异对象的信息存储在一个结构中。然后将该结构放入以对象 ID 作为键的字典中。所以我的字典(在伪代码中)看起来像 Dictionary position = new Dictionary(int ID, Positions pos) 其中“Positions pos”是具有对象的字符串、布尔值和变换的结构。它是一个结构字典,每个条目代表我场景中的一个对象。

因此,当我在字典中的年表点 A 处存储对象的信息结构时,它应该在那个时间点存储字符串、布尔值和转换。因此,稍后,在年表点 B,当我遍历字典时,我可以在需要时检索正确的字符串和正确对象 ID 的布尔值。

另一方面,在 B 点,我从 Dictionary 的存储结构中检索到的 Transform 显然已更新为 B 点的当前 Transform 值。因此,当我尝试将有问题的对象移动到点 A 的变换值时,我得到的 Debug.Log 告诉我点 A 和 B 的变换值相同,并且对象被移动到其当前位置(净效果为 =什么都没有发生)!

这是我存储结构值的方式:

using UnityEngine;
using UnityEngine.SceneManagement;
namespace ExtensionMethods
{

    public static class GameObjectExtensions
    {
        public static Positions GetPositionsData(this GameObject obj)
        {
            var pos = new Positions();
            pos.transform = obj.transform;
            pos.sceneName = SceneManager.GetActiveScene().name;
            var rigid = obj.GetComponent<Rigidbody>();
            if (rigid != null)
            {
                pos.isRigid = true;
            }
            else
            {
                pos.isRigid = false;
            }

            return pos;
        }
    }
}

这是我在字典中存储结构的方式:

public class SaveSceneState : Singleton(SaveSceneState) {
    public Dictionary<int, Positions> positions;

    void Awake()
    {
        positions = new Dictionary<int, Positions>();
    }

    /// <summary>
    /// When the the scene is changed, add the ID and Position struct
    /// of the objects to the Dictionary.
    /// </summary>
    public void OnSceneChange()
    {
        var objs = GameObject.FindGameObjectsWithTag("Remember");
        foreach (GameObject obj in objs)
        {
            var pos = obj.GetPositionsData();
            var id = obj.GetInstanceID();
            if (!positions.ContainsKey(id))
            {
                positions.Add(id, pos);
            }
        }
    }

后来,在检索时,我使用这个:

var objs = GameObject.FindGameObjectsWithTag("Remember");

        foreach (GameObject obj in objs)
        {
            // Look up the ID of the object.
            var id = obj.GetInstanceID();
            Positions pos;

            // If the object is in the dictionary, display its stuff.
            if (SaveSceneState.Instance.positions.TryGetValue(id, out pos))
            {
                // Call the Transform method on just the focused object.
                obj.SendMessage("OnTransform", (pos.transform));
            }
        }

最后,应该显示两个不同的变换以及使当前对象的变换等于传入的变换值的函数:

void OnTransform(Transform trans)

{
    Debug.Log(trans.position.Equals(null));
    Debug.Log(trans.position.ToString());
    Debug.Log(this.transform.position.ToString());
    this.transform.position = trans.position;
}

如果传入的变换为假,我得到的 Debug.Log 输出为假,然后两个调试行等于相同的变换值。

我唯一能想到的是,当 Transform 存储在 struct 中时,它是通过引用传递的,因此 Dictionary 的 struct 只查看当前值的值?

【问题讨论】:

  • 这是有道理的。以前应该看到的。你有解决这个问题吗?是否有“快捷方式”来存储 Transform 的实际值而不是引用?
  • 我找到了这个。 stackoverflow.com/questions/32172312/…我会测试看看这是否有效!

标签: c# unity5


【解决方案1】:

在这种情况下,OP 正在回答他自己的问题!

感谢 31eee384 的观点,即我使用了一个类,因此传递了引用而不是实际 Transform 的副本,它把我带到了这里: C# & Unity : Pass reference by value?

该帖子的答案建议我将 Transform 分解为我的结构中的 Vector3 Position 字段并存储它,这样就可以了!

谢谢,31eee384!我会投票赞成你的答案,但我认为我不能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2011-11-14
    相关资源
    最近更新 更多