1

I have a struct that has a string, Boolean, and a Transform. Part of my code loops through every object in my scene that has a relevant tag and stores the information of each singular object in a struct. The struct is then placed in a Dictionary that has the object's ID as the Key. So my dictionary (in pseudocode) looks like Dictionary positions = new Dictionary(int ID, Positions pos) where "Positions pos" is the struct that has the string, Boolean, and Transform of the object. It is a dictionary of structs, with each entry representing an object in my scene.

So when I store an object's informational struct in the Dictionary at chronology point A, it should store the string, Boolen, and Tranform AT THAT POINT IN TIME. Thus, later, at chronology point B, when I loop through the Dictionary, I can retrieve the correct string and Boolean of the correct object ID when I want them.

At point B, the Transform that I retrieve from the Dictionary's stored struct, on the other hand, has apparently been updated to point B's current Transform value. So when I try to move the object in question to point A's transform value, the Debug.Log's I get tell me that point A's and B's Transform values are the same, and the object is moved to its current location (the net effect being = nothing happens)!

Here's how I store the struct's value:

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;
        }
    }
}

Here's how I store the struct in the Dictionary:

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);
            }
        }
    }

Later, on retrieval, I use this:

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));
            }
        }

And finally, the function that is supposed to display two DIFFERENT transforms as well as make the current object's transform be equal to the passed-in transform value:

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;
}

The Debug.Log output I get is False for if the passed-in transform is false, and then two Debug lines that equals the same Transform value.

The only thing I can possibly think of is that when the Transform is stored in the struct, it's passed by reference and therefore the Dictionary's struct just looks at the current value for its value?

Jon M
  • 21
  • 4
  • That makes sense. Should have seen that before. Do you have a fix for this? Is there a "shortcut" for storing the actual value of the Transform instead of the reference? – Jon M Apr 27 '17 at 16:03
  • I found this. http://stackoverflow.com/questions/32172312/c-sharp-unity-pass-reference-by-value I will test to see if this works! – Jon M Apr 27 '17 at 16:11

1 Answers1

1

In this case, the OP is answering his own question!

Thanks to 31eee384's point about that fact that I was using a class and therefore the reference is passed instead of a copy of the actual Transform, it lead me here: C# & Unity : Pass reference by value?

The answer to that post suggested I break down the Transform into a Vector3 Position field in my struct and just store that, and that works!

Thanks, 31eee384! I'd vote your answer up, but I don't think I can.

Community
  • 1
  • 1
Jon M
  • 21
  • 4