8
\$\begingroup\$

Hey I've just learned about pointers recently and am wondering how I can use them in c# (I just learned about them in c++) in unity. I do have some questions though.

  1. Pointers use low level programming to find positions of different values on the computer so does that mean that you can just access a the value of a variable from any script?
  2. If so how do I just call upon a location of a variable with just its location code?
  3. Are there any discernible differences between pointers in C# and C++ that I should know?
  4. How can I use pointers with the variable types in Unity (Vector3s, Transforms, GameObjects, etc...)?

There are so many more questions I probably should and would like to ask so if you have any additional info or sources.

\$\endgroup\$

2 Answers 2

7
\$\begingroup\$

In general for C# and specifically for Unity I would advise against it... but if you really wanted to, or had good reason, you could.

In C# you would need to familiarize yourself with what is called unsafe code. Scared yet?

In Unity you would need to enable unsafe compilation mode so you will not be able to use the web player if you planned on that. You can read more here or here.

So basically C# was designed with a Garbage Collector as many scripting languages are. The general idea is to try and abstract the notion of memory management to simplify development. You can still end up with resource leaks if you don't nullify your objects. I'm honestly not a huge supporter of GCs and would prefer RAII methods instead, but this is the world we live in.

Most C++ developers would also, however, agree that you shouldn't use pointers directly anyway and should prefer to use an RAII designed type aka smart pointers. If you are in C land then likely pointers are second nature to you, but even then it helps to abstract them to some degree.

If you do use them in C# just be aware that there is a very real potential you could add security vulnerabilities or really nasty and hard to track down bugs. You will also need to keep in mind that you must be careful not to reference objects that can be moved by the GC. Note the use of the fixed statement here.

You can also use Pointers in Unity by writing a native plugin. This again will rule out webplayer builds, but the new HTML5 feature works based on emscripten so if you planned on using that you likely could if you are careful. Native plugins allow you to extend Unity on a per platform basis. I wrote a native plugin to communicate with some microcontrollers via a serial connection for example.

So to summarize you should definitely ask yourself why do I want to use pointers in C# in Unity. If you just want to do it for fun... Knock yourself out.

Edit: I'm sorry if I had offended anyone as I know my thoughts on GC are not of the popular opinion right now.

If you really read my answer you will note that I do not call C# a scripting language. I compare it to "many scripting languages", however, in the context of Unity it is very much so used as a scripting language. It is somewhat of a DSL to Unity if you will. Often times you will see it even referred to as Unity Script in this context (this is mostly in reference to Unity's Javascript alternative to C#). If you put LLVM in your pipeline you can just compile it to native code for the platform directly... then what would you call it? So really I didn't want to split hairs here.

Many great references to software engineering are filled with opinion:

Effective C++, More Effective C++, C++ FAQ, Effective C#, Modern C++ Design, Design Patterns ... And countless others. I don't feel this makes the arguments any less credible if they are followed by thoughtful explanation.

I was not really all out saying "Don't use pointers ever!!". In fact I still use them naked on occasion. I said "in general" as in "prefer using safe code to unsafe code in C#". There are situations where it can be beneficial, and that is one of the really powerful features of C# to pick and choose your tools. C# even allows you to have transparency in the GC process to some degree, languages like Dart do not and can lead to resource leaks very easily. Sure if you are the sole developer of a small project it isn't likely a problem. If you are on a team of say 10+ with hundreds of thousands of lines of code then it can get tricky.

I simply wanted the reader to exercise caution when using naked pointers. It is akin to saying be very careful when working with mains electricity. I'm not saying don't be an electrician, just that if you make the wrong move and don't treat it with respect you are dead.

I do like the example given by Lasse in which performance may have dictated the need.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ C# is not a scripting language, altough it can be used for that. Java has a GC too and it's not a scripting language either. Answering with your own opinion what is best generally, is not the objective answer we are looking for on this site. For a spesific purpose something like unsafe code and pointers can be really efficient. \$\endgroup\$
    – Lasse
    Commented Oct 10, 2015 at 6:46
  • 1
    \$\begingroup\$ I dont understand why is this answer downvoted - it is very informative and shows a lot of research/knowledge and links to further reading. Especially to @Lasse what is scripting language? Of course it would be more precise to say "language that is used for scripting in unity", but I dont see much reason to downvote because Matthew omitted 7 obvious words and used one (over)simplified term. \$\endgroup\$
    – wondra
    Commented Oct 10, 2015 at 10:49
  • \$\begingroup\$ @wondra I donwnvoted because the answer is not making it obvious that there are places where pointers can very well be used in C#. It all depends on the purpose and target platform. In fact the answer is trying to scare everyone away from using pointers. \$\endgroup\$
    – Lasse
    Commented Oct 10, 2015 at 11:21
  • 1
    \$\begingroup\$ @wondra This answer is hardly answering the question. All it does is telling not to use pointers. This comment section is not proper place to discuss this. You can join the chat if you think you have more arguments. \$\endgroup\$
    – Lasse
    Commented Oct 10, 2015 at 12:02
  • 1
    \$\begingroup\$ @Lasse cant convince you and its not my fight, but seeing your answer - you wrote exactly the same as this answer(which was posted sooner), moreover you even included only subset(=less information) on the topic as this answer did. \$\endgroup\$
    – wondra
    Commented Oct 10, 2015 at 14:51
7
\$\begingroup\$

C# uses references to pass around objects that are not value-types. This means that everything is usually passed by reference. If you want to pass a value-type by reference you can use the ref keyword. The difference of a reference type and value-type is that depending on how large the value-type is, it usually requires more memory copied when it gets passed on to a function. A reference is just 32 bits or 64 bits, or 4 bytes or 8 bytes. You can get more performance out from your code in very tight loops if you use references instead of just copying all the data the value-typed variables contain, assuming they are larger than 4 or 8 bytes.

For example on Unity any MonoBehaviour (class) object is a reference type, and any Vector3 (struct) object is a Value-type.

There is also unsafe code blocks that will allow you to type code that lets you create and modify data unsafely. To use unsafe code you will have to set the compiler to allow unsafe code. Pointers can be used this way. By using unsafe code certain checks are not used that are there with safe code, which makes unsafe code harder to write error-free. There are very few places that can benefit from unsafe code on C#. On Unity unsafe code is not supported on all platforms. Usually using references instead of unsafe pointers are enough when working with Unity.

Here is an example (source) of using unsafe code pointers in C# with Unity:

public static class Rope
{
    // C# function declaration to match C++
    [DllImport(SlingshotImport.c_libName)]
    static unsafe extern void UpdateRopeParticlesUnsafe(
        Vector3* oldNew,
        Vector3* curr,
        int numParticles);

    // C# wrapper function for Unity C# script
    static void UpdateRopeParticles(
        Vector3[] oldNew,
        Vector3[] curr,
        int numParticles)
    {
        unsafe
        {
            fixed (Vector3* oldNewPtr = oldNew)
            fixed (Vector3* currPtr = curr)
            {
                UpdateRopeParticlesUnsafe(oldNewPtr, currPtr, numParticles);
            }
        }
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ I find it interesting that you criticize my answer and use the same arguments, minus other relevant info, and only include a brief discussion of value vs reference types. You could at least mention Boxing, JIT optimizations that could at times remove the value type copy overhead, how to avoid unsafe by marshalling, or perhaps that unsafe code is not always faster then safe \$\endgroup\$ Commented Oct 10, 2015 at 18:49
  • \$\begingroup\$ I'm sorry if you feel attacked or offended. It was not my intention. I criticized your answer for that it seemed to me very opinion based instead of fact based. I provided anwers for the questions asked along with some example code. From your answer I was not able to understand the things I explained in my answer, which I felt were more relevant to the question asked. I don't see how GC has anything to do with "how do I use pointers?" or I didn't see you mention how references work on C# since the question seemed to assume variables worked the same way in C# and C++. \$\endgroup\$
    – Lasse
    Commented Oct 10, 2015 at 19:11
  • 1
    \$\begingroup\$ No worries. Thank you for your apology. I mentioned the GC as you do need to be aware that passing pointers to managed types can cause issues if the GC suddenly moved the object. I did assume the reader was aware of the C# type system and how reference vs value types are used. \$\endgroup\$ Commented Oct 10, 2015 at 19:35
  • \$\begingroup\$ You guys really make it hard to accept an answer. You both provided me with plenty of information that was needed so I'm going to up vote both of you and am going to accept the one that came first. I don't mean anything by it. I just have a hard time choosing and as for scaring me off from from "unsafe code" don't worry. I've never been the one to back away from a challenge anyways. Although now I know that working with pointers is impractical as it pertains to multi platform development. I want to thank you all for your time and opinions. and Im sorry i started WWIII didn't meen to do that. \$\endgroup\$
    – Ryan Henry
    Commented Oct 11, 2015 at 3:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .