roguish

Unity3D with C# for ActionScript Developers

I’ve been doing ActionScript 3.0 development for over 10 years, making games and applications for mobile devices and Mac/Win desktops. I’ve recently been expanding my skills and learning Unity3D with C#. This post lists some of my discoveries and the resources that I’ve encountered along the way. These notes may be especially interesting to other ActionScript developers as they also begin to dabble in Unity3D and look for areas of similarity and difference between these 2 great development platforms.

  • Other resources like this one to help you get started
  • Tutorials
  • Transform
    • Unity’s GameObject.transform does more than store an object’s basic position, rotation, scale, skew, etc. All GameObjects have a transform object and they are also used for maintaining a hierarchy of parent/child GameObjects. Use a for loop to get all the children of the transform. e.g.:
      for(var child:Transform in transform { child.Translate( 0, 0.1, 0 ); }
    • Game Objects can be referenced by a string name or by a tag. A Game Object can have more than one tag (grouping) and multiple game objects can have the same tag. e GameObject.FindWithTag or GameObject.Find (or transform.Find).
  • CharacterController
  • Complex (compound) collider shapes
    • You can construct colliders for an object out of multiple primitives – this gives you the ability to simulate quite complex objects. Attach multiple child game objects to the object that you want to collide with. Give that object a rigidbody. Attach 1 primitive collider to each child game object and size and scale them accordingly – the compound shape of them will comprise your new collider.
  • Gizmos
    • temporary elements that only appear during debugging. e.g., Debug.drawLine. The debug player allows enabling/disabling of specific types of gizmos.
  • GUI
    • The nGUI package is a common alternative to the built-in Unity GUI feature.
    • If you use the built-in GUI system, the OnGUI implementation might be called several times per frame if several events trigger it.
    • If the MonoBehaviour’s enabled property is set to false, OnGUI() will not be called.
  • Application.LoadLevel
    • change which scene is displayed
    • MonoBehaviour.OnLevelWasLoaded
      • called on all active game objects after the level has been loaded.
  • Lifecycle of a GO
    • Some have tried to document the order methods are called. None really seem to be complete. TODO: combine several of the attempts out there into one test including destructor calls, etc.
    • Use of the constructor seems to be widely discouraged. Use Awake instead. It’s called on all GOs before Start.
    • active/inactive vs. enabled/disabled.
      • MonoBehavior.enabled: Enabled Behaviours are Updated, disabled Behaviours are not.
      • GameObject.activeSelf: will return true even if parent’s active setting is false, in which case this object would be treated as inactive even though activeSelf may return true.
      • GameObject.activeInHierarchy: Whether the object will be treated as actibve (return value is affected by parent active setting)
      • Effect of deactivating a GO: "A GameObject can be temporarily removed from the scene by marking it as inactive." I’m not sure exactly what it means when an object is inactive… It won’t be destroyed, because its activeSelf/activeInHierarchy properies can still be checked when it’s inactive.
      • (confirm) GameObject.Find will not see deactivated objects
      • renderer.enabled = false; used to hide an object.
      • (conirm) enabled (false) will continue to consider physics on your invisible object. Active (false) will stop physics calculations
      • (confirm) inactive game object not drawn to the screen.
      • Stops the object from receiving update events so it’s necessary to reactivate it without reliance on the game object’s own update method.
      • http://docs.unity3d.com/Documentation/ScriptReference/GameObject.SetActive.html
  • FixedUpdate
    • You cannot use Input functions in FixedUpdate. If you must get user input, you will need to get it in Update and apply it in FixedUpdate.
    • (TODO) which is called first, update or fixedUpdate? Need to know for handling Input.
  • Object.Instantiate used to clone Objects
    • active/inactive of original object is inherited by clone
    • " If you are cloning a Component then the GameObject is is attached to will also be cloned, again with an optional position and rotation." That’s unexpected.
    • (confirm) No explicit method is called to add a cloned GO it to the stage. It seems that it is added to the stage by default. different than AS3.
    • (TODO) How can an object be instantiated but not added to the hierarchy? use GO.SetActive after instantiating it?
  • Components:
    • "your code will never directly create a Component. Instead, you write script code, and attach the script to a GameObject." 
  • ScriptableObject
    • A way of creating scripts that can be edited in the Inspector. Advantages: changes made to settings are applied to GameObjects in the Scene in real time and values are saved, even if changes are made while in Play mode. Also, they’re *reference*-type, meaning when you change values in one instance of a ScriptableObject, all other instances of the ScriptableObject adopt the change as well.
    • https://github.com/RivelloMultimediaConsulting/ScriptableObjectDemo
  • Collision messages are sent to each object that was part of the collision (for trigger and collider type collisions).
  • Object.Destroy(Object,time);
    • time param is a delay before the object will be destroyed
    • can be used on GameObjects and Components because it is a member of Object, the base class for both.
    • destruction occurs after the update loop completes and before rendering.
    • MonoBehaviour.OnDestroy() will be called on MonoBehaviors before the destructor (Finalize).
  • Transform.TransformDirection & Transform.InverseTransformDirection
    • Unity’s equivalent to AS3′s LocalToGlobal/GlobalToLocal
    • Transform.TransformDirection converts a Vector3 from local to world space.
    • Transform.InverseTransformDirection converts from world to local.
  • AddComponentMenu
  • 2 primary ways to move a Game Object. Don’t use them simultaneously or you’ll create conflicts.
    • gameObject.rigidbody.AddForce() to push it and let the physics engine create the movement
    • Adjust the Transform object to place it in a new position (if using kinematic/non-physics based control)
  • Material
    • transform.renderer.material
      • For referencing a model’s material. Useful for something like changing the costume on a character at runtime.
    • transform.renderer.material.mainTextureOffset
      • For scrolling the art across the mesh face. Good for creating frames of an animation.
  • Layers
    • Objects placed into layers are grouped. This is not a visual metaphor, just for grouping objects.
      • use cases
        • limiting the objects a raycast interacts with.
        • selective rendering.
        • culling masks: used to select which Layers are rendered by the camera.
    • http://docs.unity3d.com/Documentation/Components/Layers.html
  • determining if an object is within the view of a camera:
  • placing a camera into a game object pointing towards the game object’s content causes the camera to track the game object. Seems odd at first, but makes sense.
  • Using multiple cameras to render the scene is good for 2D platformers. Arrange objects in layers and render layers per camera. e.g., bg rendered with a perspective camera and fg with an orthographic camera. Good for creating parallax.
  • rigid body constraints includes freeze position for locking z movement or rotations (good for 2D games)
  • Gizmos can be un-scaled or scaled within the 3D scene. set it in the Gizmos combo box of the game window.
    • OnDrawGizmos()
    • place gizmo indicators into game window for debugging.
  • For invisible (or tiny) game objects attach a button so the object can be selected from the scene by clicking the button.
  • Handles
    • Custom GUI controls and drawing in the scene view. for debugging only?
  • Physics.IgnoreCollision
  • SendMessage
    • calls method by string name on every MonoBehavior script in the game object
    • not for communication between game objects, only for communication between components in a single game object.
    • Can require at-least 1 receiver.
    • Receiving methods can have a signature with no parameters and method will discard any parameters that are passed to it.
  • AddExplosionForce
  • edit > project settings > physics settings > for configuring what layers have physics contact testing against one another (Layer Collision Matrix).
  • OOP Scripting in Unity:
  • Unity3D Interface
    • press spacebar to expand the currently-active Unity panel to fullscreen.
  • C# language
    • Time
      • Time.timeScale
        • Changing it affects the Time.realTime value. So, Time.realTime is not always a true measurement of time since the game launched (like Actionscript’s getTimer()). Instead of using Time.realTime, use Time.realtimeSinceStartup, for a better equivalent of getTimer() that won’t change if there have been changes to Time.timeScale.
        • Depending on the platform and the hardware, Time information may report the same time even in several consecutive frames. If you’re dividing something by time difference from frame to frame, take this into account (it may become zero, causing a division-by-zero error).
    • Fractional Digits
      • [float].ToString("f2") returns the first 2 fractional digits. other parameters like r/g/n in place of the f also seem to do something according to comment posts I came across. Another, probably better and more formal, way to specify fractional digits
        • myValue.ToString("000.0"); // adds up-to 3 leading zeros and one fractional-digit
    • Delegates
    • Coroutine
      • Must have a return type of IEnumerator and a yield return statement included somewhere in the body.
      • C# syntax is different than JavaScript. If samples and tutorials don’t work, check that yield statement syntax matches the following C# example with "return new" syntax and verify that the return value of the method is IEnumerator:
        • yield return new WaitForSeconds( 1.0f );
      • If using JavaScript/UnityScript "a coroutine can be started in UnityScript by calling it as if it were a normal function". The same doesn’t work with C#.
      • http://docs.unity3d.com/Documentation/Manual/Coroutines.html
    • InvokeRepeating
      • ActionScript equivalent of Timer (a method called on an interval).
      • It includes a built-in delay before it fires for the first time.
      • Note error with InvokeRepeating when triggering it immediately. Requires a tiny delay or first call will happen twice.
      • Invoke is similar, without the inadvertent repetition. It delays a call for a specified time.
    • Collections
      • Built in arrays, like int[100], are the fastest and most efficient collections, but unlike ActionScript arrays, you can’t change the number of objects in them. Use them if you don’t need your array to change its size.
      • Lists can have items added or removed at runtime, they contain a specific type (or a subclass of that type), they can also be sorted easily and turned into arrays when necessary. Pretty much like AS3 Vectors.
      • List<SomeClass> anotherList = new List<SomeClass>();
      • The List<T> class has many more methods, like Contains, etc.
      • http://csharp-station.com/Tutorial/CSharp/Lesson20
      • Dictionary is faster than Hashtable:
    • Math Utilities
      • Mathf.clamp
      • Mathf.Repeat is similar to modulo (%). Actually, testing shows that % also works (including floats). I’m not sure what difference, if any, there is.
    • You can use the var keyword and C# will try to infer the variable type.
    • delegates, lambda (=>), inline functions, anonymous methods
    • method parameters
      • http://msdn.microsoft.com/en-us/library/8f1hz171.aspx
      • pass params by reference instead of by value by using *ref* or *out*. Both the method definition and the calling method must explicitly use the ref or out keywords.
        • ref
          • An argument that is passed to a ref parameter must be initialized before it is passed.
        • out
          • Arguments do not have to be initialized before they are passed.
          • The called method is required to assign a value before the method returns.
      • (confirm) It seems like you can reference parameters from within a method body with notation like this: {0}. Used in many Debug.Log statements in C# documentation.
    • attributes
      • [ ] above method declaration
      • http://csharp-station.com/Tutorial/CSharp/Lesson16
    • subclassing syntax
    • properties via *auto implemented* shorthand for get/set syntax:
      • public int Age { get; set; }
    • Inheritance
      • http://unity3d.com/learn/tutorials/modules/intermediate/scripting/inheritance
      • Classes can have more than one constructor. whoa.
      • http://msdn.microsoft.com/en-us/library/ms228387(v=vs.90).aspx
      • Base class objects are always constructed before any deriving class. Thus the constructor for the base class is executed before the constructor of the derived class. If the base class has more than one constructor, the derived class can decide the constructor to be called.
        (TODO) overridden subclasses can have a different number of arguments from the superclass. I suspect this is because of the multiple-constructor behavior. If you instantiate a subclass using a constructor signature of the base class not shared by the subclass, what will happen? Will any of the subclass’ constructors be called?
      • sublasses can pass parameters to the base class’ constructor
        • public ColorCoOrds(int x, int y) : base (x, y)
      • *base*: the keyword for calling methods on a super class
      • subclassing a base class that receives a parameter in its constructor:
    • extension methods
    • casting looks like this:
      • (Apple)myFruit;
    • events work like signals, with += and -= used to add/remove methods to a signal dispatcher (properties of type event):
    • primitives
      • value type vs reference type: All of the primitive types (int, char, double, etc.), except for string, are value types. The following types are value types: enum, struct
      • enums and structs (not available in AS3)
        • both are value types not object types
        • enums can only be public
        • structs are private by default but can be given an other modifier type
        • struct is a value type (where a class is a reference type). If you copy a struct, C# creates a new copy of the object and assigns the copy of the object to a separate struct instance.
        • "Unlike classes, structs can be instantiated without using the New operator. If you do not use New, the fields will remain unassigned and the object cannot be used until all the fields are initialized."
        • http://csharp-station.com/Tutorial/CSharp/Lesson12
        • "object initialization" sets values for struct properties when the struct is instantiated.
      • http://msdn.microsoft.com/en-us/library/ya5y69ds%28v=VS.80%29.aspx
    • nullable types
      • ever tried to set an int to null? nullable types allow primitive typed variables to hold null values.
        • syntax: int? unitsInStock = null;
      • An explicit conversion is required when assigning from nullable to non-nullable types
          • availableUnits = (int)unitsInStock; // when availableUnits is non-nullable while unitsInStock is nullable
      • ?? coalesce operator: int availableUnits = unitsInStock ?? 0;
    • String.Empty
      • Represents an empty string. could be handy.
      • Also, String.IsNullOrEmpty method.
    • class member modifiers
      • access modifiers (declare which code may access class members at runtime. e.g., what other objects are allowed to call a method.):
        • public, protected, private — all the same as AS3
        • internal, protected internal – access limited to others in the same or inherited *assembly* (I assume this works similarly to an AS package where multiple classes can be defined in a single document and members marked as internal in classes of the document can be shared by the other classes in the document.)
      • additional modifiers (declare other rules about the member. i.e., what other classes may override a method.)
      • virtual vs. abstract
        • virtual: *can* be overridden in subclass.
        • abstract: it *must* be overridden in subclass. Use the abstract modifier in a class declaration to indicate that a class is intended only to be a base class of other classes. Members marked as abstract, or included in an abstract class, must be implemented by classes that derive from the abstract class.
        • http://msdn.microsoft.com/en-us/library/sf985hc5(v=vs.110).aspx
      • Overriding
        • The overridden base member must be virtual, abstract, or override.
        • An override declaration cannot change the accessibility of the overridden member.
      • sealed (like AS3 final)
      • readonly vs. const.
        • A const can only be initialized at the declaration." A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants".
    • verbatim literal string
    • Memory Management: Dispose, Destructor, Finalize
    • is vs. typeof
      • if (obj is ClassA) {} // tells you if the object implements ClassA anywhere in its its inheritance hierarchy. presumably multiple types could return true
      • (confirm) if (obj.GetType() == typeof(ClassA)) {} // checks the most-derived type. more precise than *is*. presumably only one type will return true.
      • http://stackoverflow.com/questions/184681/is-vs-typeof
    • You like Penner’s AS3 Signals? It was inspired by C# events. :)
    • Singleton
  • Asset Store Utilities
    • nGUI is the preferred GUI over the internal GUI system. Unity hired the guy who wrote it.
    • PlayMaker is a common state machine creator
    • 2DToolkit for 2D (prior to Unity 4.3. Will it survive and continue to provide unique features?)
  • Advanced topics
  • Architecture Frameworks
    • StrangeIoC. A Robotlegs/PureMVC-like MVC architecture with dependency injection/inversion of control, mediator and command patterns, etc.
    • http://strangeioc.wordpress.com/

3 ResponsesLeave one →

  1. Nice – a very exhaustive list. Thanks for the link-back.

    Reply
  2. Daniel

     /  April 17, 2015

    Thanks!

    Reply
  3. hi) Thanks for such a detailed guide, really a good stuff!

    Reply

Leave a Reply