Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Is this a copy or a pointer?

Discussion in 'Scripting' started by Eistee, Jan 5, 2016.

  1. Eistee

    Eistee

    Joined:
    Nov 9, 2015
    Posts:
    16
    My question is, is "spriteArray" in class ChunkScript an complete copy of the array in class TileMapScript or only an "fast and no memory usage" pointer to the original sprite array?

    The object with this script attached has the tag: "obj_TileMap"

    Code (CSharp):
    1. public class TileMapScript : MonoBehaviour {
    2.     public List<GameObject> chunks = new List<GameObject>();
    3.     public Sprite[] Sprites;
    4.  
    5.     //Generate
    6.    GameObject chunk = new GameObject();
    7.    chunk.AddComponent<ChunkScript>();
    8.    chunk.GetComponent<ChunkScript>().Build();
    9.    chunks.Add(chunk);
    10. }
    Code (CSharp):
    1. public class ChunkScript : MonoBehaviour
    2. {
    3. void Build()
    4.     {
    5.         GameObject reference = GameObject.Find("obj_TileMap");
    6.         Sprite[] spriteArray = reference.GetComponent<TileMapScript>().blockSprites;
    7.     }
    8. }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    Arrays are always pointers unless you explicitly tell them to be otherwise.
     
  3. kietus

    kietus

    Joined:
    Jun 4, 2013
    Posts:
    54
    !!!
    :)
     
    Mycroft likes this.
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Technically C# does not support pointers unless you place it in 'unsafe' mode.
    https://msdn.microsoft.com/en-us/library/y31yhkeb.aspx

    These are 'reference types'. Which means that when you pass the object from variable to variable, the reference is moved. This is more like a half-pointer. The variable takes a copy of the handle to the object in managed memory... thing is a reference might move around in managed memory, so it's not exactly a pointer. A pointer is a copy of a byte address in memory, a pointer can point at any point in memory.


    In your case, an array is a referenced object, not a value.

    You can know if you have a reference if it is a 'class'. A really quick way to decipher this is if you can set the variable to 'null'.

    You can tell it's a value type if it's a struct, enum, or other primitive type. A really quick way to decipher this is if you can NOT set the variable to null.
     
    Mycroft likes this.
  5. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    Code (csharp):
    1. Nullable<int> example = null;
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Yes, there are exceptions.

    Although this is technically a hack on the part of the language. The underlying fields of 'Nullable<T>' are the value you want to store, and a bool. 'null' is converted to the bool as false, denoting the value should be ignored.
     
  7. Eistee

    Eistee

    Joined:
    Nov 9, 2015
    Posts:
    16
    @kietus & @StarManta
    Have one or both of you an better solution to get this spriteArray?
    I hate GameObject.Find too!

    And thank you all for your explanation.
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    ;) I would probably use a singleton in this case:
    Code (csharp):
    1. public class TileMapSprite : MonoBehaviour {
    2. public static TileMapSprite instance;
    3. void Awake() {
    4. instance = this;
    5. }
    6. // rest of the script
    7. ...
    8.  
    9. //in your other script
    10.         Sprite[] spriteArray = TileMapScript.instance.blockSprites;
    11.  
     
    Eistee likes this.
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Static variables which only get initialised once can also be useful for your use case.
     
    Eistee likes this.
  10. Eistee

    Eistee

    Joined:
    Nov 9, 2015
    Posts:
    16
    I don't get it up to work, it is driving me insane :eek:o_O
    I got an NullReferenceException

    I debug with VS and everything works fine, I can follow the code with the singlestep until the "debug-line" finish my script (TileMapChunk.cs:128!).

    If I press again F11 (singlestep) the known yellow line is gone, 22 more singlesteps (I do not know where the dubugger is), it throws an NullReferenceException:

    But the info "TileMapChunk.cs:128" can't be corrrect, beause the error happens exact 22 singlesteps later.

    Can someone tell me how to find the real NullReference?
     
  11. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    Please start a new thread about it
     
  12. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    This actually makes me wonder that what's the point of pointers. I mean references in C# are much safer and like pointers. You can make it reference it to something else make it null and GC is already deleting them. I wonder why would someone use them in C#? Is there something performance related?
     
  13. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
  14. Eistee

    Eistee

    Joined:
    Nov 9, 2015
    Posts:
    16
    @Yash987654321 I found the problem while testing/fooling around :(

    I will open a new topic, in hope someone can explain (or link) this "debug"-problem.
    ---------------------------------------------------------------------------------
    I create an empty game obj at runtime:
    Code (CSharp):
    1. GameObject xyz = new GameObject()
    2. xyz.Init(); <== (Code below)
    Fill it with componets to draw something into the scene:
    Code (CSharp):
    1.         this.gameObject.AddComponent<MeshFilter>();
    2.         this.gameObject.AddComponent<MeshCollider>();
    3.         this.gameObject.AddComponent<MeshRenderer>();
    4.         ...
    5.         MeshRenderer mesh_renderer = this.GetComponent<MeshRenderer>();
    6.         ...
    7.         mesh_renderer.sharedMaterial.mainTexture = texture; // <== KILL'S IT!
    8.         mesh_renderer.material.mainTexture = texture; // FIX IT!
    But my "Fix" is the next problem, it seems that I need an external Material or something like that, because the Unity (compiler?) grouses with me, that the material will be copied into the scene. :(
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Pointers are faster. Pointing directly to physical memory allows you to do some insane things too.

    We used pointers a lot in older scanning PLCs. The only data structures that exist are bits and ints. Ints are just 16 bits in sequence. You can do some surprising things with just this level of data. Most of it revolves around pointers.