Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to Make Better Code Assets for the Asset Store?

Discussion in 'Scripting' started by TonyLi, Nov 6, 2015.

  1. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @longroadhwy asked if the Asset Store had a "Design for sales and success: making integration easy with extensible unity assets" type of document. Since I'm not aware of any, I thought it might be helpful to crowdsource some unofficial suggestions.

    I'm particularly interested in your thoughts on the Extensibility section. Frankly the rest is mostly window dressing, but extensibility is a fundamental design factor that has a big impact on how easily customers can integrate your code assets into their projects.


    To kick it off:

    Follow Unity's Submission Guidelines for code assets. [hpjohn]


    Documentation
    Comment your code for automatic documentation generation using a tool such as Doxygen. MonoDevelop and Visual Studio make it easy. Just type "///" above a declaration, and the editor will paste in a template to fill in.

    At the very least, declare each class in a separate file, and document the purpose of each one. Ideally, also add comments for each public class, property, and variable declaration.

    If the purpose of a serialized variable is not obvious or has caveats, use the [tooltip] attribute for MonoBehaviours and ScriptableObjects that use the default inspector.

    Document changes when updating. [hpjohn] Keep a running change log from the very first release of the product. API changes and feature deprecations in particular are critical. [longroadhwy] If upgrading requires the customer to take special steps, point those out in an upgrading document (e.g., upgrading.txt). [syscrusher]

    Provide documentation in an open format such as PDF or text that customers can open easily on any platform. [syscrusher]

    Offer local installation of documentation. Online documentation is useful but usually only reflects the most current version. If a customer's project is locked to a particular version of product, the customer should have documentation that matches that version. [longroadhwy]

    Explicitly list which platforms were tested with the code asset (e.g., tested with Windows, Mac OS/X, iOS, Android and Linux). Also include appropriate OS version numbers if required. [longroadhwy]

    This post also has a good discussion on code asset documentation.


    Folders & Files
    Put your code asset entirely under one folder when possible. Some exceptions, such as gizmo icons and plugin DLLs, must be in other special folders. Consider putting your scripts in Plugins, or at least make sure they work correct if the user moves them intno Plugins. See Where to Install Your Assets for a comprehensive answer. [based on tips from hippocoder, guavaman, SonicBloomEric, makeshiftwings]

    Avoid hard-coded paths whenever possible.

    Keep your file metadata consistent. Avoid deleting files and re-adding them by dropping them into the Projects view; this will generate new metadata files.

    Put example and supplemental files in a separate folder that customers can delete if they want to strip down their project. Don't intersperse them with files that are necessary for your product to operate.

    If providing precompiled DLLs with the option to import source code from a separate package, bear in mind that MonoBehaviour and ScriptableObject declarations will have different GUIDs in the DLL versus source code. Consider insulating the customer from these GUIDs with wrapper scripts so they can switch between DLL and source without losing script references.


    Code Organization
    Don't Repeat Yourself. If you do the same thing twice or more, consider making a static method or class to do it for you. [LaneFox]

    Use namespaces! [everyone :)]

    Prevent other scripts from breaking your code asset by specifying namespaces explicitly when using common class names. Assume that the customer or another code asset may define a common class name in the global namespace. For example, your code may have a "using UnityEngine.UI" statement and then declare a Button variable that's implicitly in the UnityEngine.UI namespace. However, if the customer defines a Button class in the global namespace, your code will break if it tries to reference the wrong Button type. New Unity users will often define their own classes with these names in the global namespace, which will break your asset unless you specify the correct namespace: Text, Button, Camera, Action.

    If you don't want to litter your code with explicit UnityEngine.UI.Button's, declare it explicitly in your using section: "using Button = UnityEngine.UI.Button;". [flaminghairball] Or put your using statements inside your namespace declaration. This will override any classes of the same name in the global namespace: [guavaman]
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. namespace MyNamespace {
    4.     // These will take precedence over any global classes or any classes inside using statements that are outside the namespace declaration.
    5.     using MyOtherNamespace;
    6.     using UnityEngine.UI;
    7.     ...
    Consider providing helper classes to simplify the customer's access to the API.

    Don't use shader keywords in shaders or materials unless you really, really need them, due to Unity's hardcoded limit. [makeshiftwings]

    And fix all compiler warnings. [makeshiftwings] Your asset should compile in all supported versions of Unity without any warnings.


    Extensibility
    Support extensibility without requiring the customer to directly modify source code, since changes will be lost when the customer updates to a new version of the code asset. (It can also be a support nightmare to provide technical support for scripts that customers have been forced to modify and possibly add unintentional side effects.)

    Use UnityEvents or the Unity event system, virtual members, C# interfaces, and/or C# events and delegates to make your product extensible.

    Consider making Awake, Start, OnEnable, OnDisable, and OnDestroy methods virtual so subclasses can do extra things in them.

    Try to make modules as self-sustaining as possible. [LaneFox] This allows customers to re-use modules or use them in new ways without impacting other modules in your code asset.

    Build your asset so it can handle alternative input systems (e.g. InControl, Rewired, etc.). [longroadhwy] It doesn't have to provide support for these input systems; just don't make it hard for customers to add support. For example, use a delegate or other kind of abstraction instead of calling Unity's Input class directly.


    Third Party Integration
    If your code asset integrates with another product, specify which party maintains the integration and which versions of each are supported by the integration. [longroadhwy]


    Debugging, Console, & Error Handling
    Do not submit a product to the Asset Store that generates compile-time warnings.

    Check Debug.isDebugBuild before logging any debug messages.

    Provide an object reference as the second parameter to Debug.Log* methods to make it easier for the customer to identify the source of the message.

    Consider adding ample verbose logging to help the customer debug issues and know what's going on under the hood.

    Consider providing an option to turn debug messages on and off, or to specify a desired verbosity level. Don't clutter the console with info-level messages unless the customer has requested them.

    Catch exceptions and handle or report them gracefully. [LaneFox]

    Consider using unit testing. [LaneFox]


    Coding Style
    In the interest of avoiding a religious war, let's tread lightly on this topic if at all. Please just be consistent within your own code, and be aware of the different styles adopted by Unity and Microsoft -- e.g., Unity uses camelCase for public properties, Microsoft uses PascalCase.


    Asset Store
    As of June 20, 2016, the Asset Store no longer allows duplicate product names. Before submitting to the Asset Store, make sure your chosen name isn't already taken.

    Submit your asset in the right category. If you require a per-seat license, make sure it's in Editor Extensions.

    Only attach asset labels to assets in your package if you think they'll be helpful to customers using your product. Asset labels are no longer used for searches in the Asset Store. Instead, set the product's meta data on the publisher page. Here are notes about searches and meta data:
    • You do not need to include plurals. They are automatically added to the extent that they are dictionary words.
    • Package name is included as keywords.
    • Package description is included as keywords.
    • Category is included as keyword.
    Make sure your support email and web page URL work.
     
    Last edited: Oct 26, 2016
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks for the Like, @zombiegorilla. I'm surprised no one's actually posted any more suggestions yet. Maybe I would've had more takers if I'd titled the thread something like "Pet Peeves With Code-Based Asset Store Plugins". The items above are my complaint/wish list as an Asset Store customer, things like:
    • Comment your code
    • Don't leave in compiler warnings
    • Don't use hard-coded paths, etc.
    Does anyone else have anything they wish more Asset Store developers would do?
     
    BackwoodsGaming likes this.
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Or "You won't believe these 10 things that developers forget to do!"

    Obviously, make sure you're following Unitys guidelines at the very least
    https://unity3d.com/asset-store/sell-assets/submission-guidelines

    Documenting changes when updating
     
    TonyLi likes this.
  4. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,462
    Well, you did a good job highlighting the majority of issues really.

    I'm no expert, but I agree with extendability being a high priority. When you have something easily extensible then you have a good easy to read and use product. It depends greatly on your asset type but you want people to be able to get in and add things painlessly, and arbitrary (and/or undocumented) dependencies inside your code make that difficult.
    • Try to make modules inside your code as self sustaining as possible.
    • Reduce the possibility of failure everywhere, use Unit testing if you can. Catch exceptions.
    • If you do the same thing twice or more, consider making a static method or class to do it for you.
     
  5. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    What are the "best" ways to make it extensible? I put that in quotes because every situation is going to be different, but perhaps some general ideas? These might be useful:
    • Virtual Awake and Start methods. This would make it easier to create a subclass that does a little extra work in Awake or Start.
    • Virtual public accessors for tweakable properties.
    • Liberal use of UnityEvent? Unless you're invoking those UnityEvents every frame, it shouldn't be a performance concern.

    I think for the most part those fall under general "good coding practice." We can only hope that all of us developers are striving to follow good coding practice. I strongly agree that a module shouldn't fail internally. For example, if a method expects a non-null argument and you pass it null, the module itself shouldn't break. But should it entirely mask the exception (possibly logging a warning), or is there ever a case where it should it handle it gracefully internally and then rethrow it?

    EDIT: Scratch that thought about rethrowing. The submission guidelines state:

    Graceful handling of errors: Your asset must provide useful warnings to the user if he or she does something wrong. Under no circumstances should your extension throw null reference exceptions, unclear error messages or warnings. Remember that your code will be included in other people's project and too many warnings from 3rd party contributors may clutter up important errors or warnings in their own code. Error messages must be in the form of a message / dialog or inline warning and explain how to fix the problem.​
     
  6. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks to both contributors so far! I put your additions into the first post.

    I also added this one, which can be a real pain:

    Specify namespaces explicitly with common class names. Assume that the customer or another product may define a common class name in the global namespace. For example, your code may have a "using UnityEngine.UI" statement and then declare a Button variable that's implicitly in the UnityEngine.UI namespace. However, if the customer defines a Button class in the global namespace, your code will break if it tries to reference the wrong Button type.​

    There are some awesome, highly-reviewed, and otherwise nicely-written code assets that fail to compile because a different code asset defined Button, Text, Editor, or other common names in the global namespace. There's no easier way to get a 1 star review than for a customer to import an asset and no longer be able to play their scenes because Unity can't finish compilation. Even though it's "not your fault," you'll still get angry, off-the-cuff reviews saying, "Don't buy this! It will break your project!"

    I would love to get more thoughts on the best ways to make code assets extensible.
     
    LaneFox likes this.
  7. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    (1) Running change log.

    Basically keep a running change log from the very first release of the product. If changes are only from release to release (via unity asset store) it is easy to miss important changes. In particular related to API changes this is critical.

    FeatureX has been deprecated. API additions or deletions.

    (2) Local installation of the documentation.

    On-line documentation is useful but usually only reflects the most current version of the software. If you project is locked to particular version of the software it nice to have the documentation that matches the current state.

    (3) Platforms Supported/Tested against

    "Asset XYZ works with Unity!" Is not very helpful. It is nice to be explicit what platforms were tested with the particular asset. For example This asset was tested with Windows, Mac OS/X, iOS, Android and Linux. Also appropriate versions of the OS if required.
     
    syscrusher, hopeful and TonyLi like this.
  8. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,760
    I posted a thread about a month regarding ridiculous amount of compiler warnings generated by asset store scripts:
    http://forum.unity3d.com/threads/so-many-asset-store-items-so-many-compiler-warnings.362732/
    I agree strongly with what you say in this thread: "Do not submit a product to the Asset Store that generates compile-time warnings."

    Also another thing that keeps happening is asset store items are including the standard assets scripts along with the asset store item. For example: I've downloaded numerous asset store items that contain the "MouseLook.cs" or "FPSInputController.js". This is part of the standard assets. This poses problems when installing the asset because the n Unity will complain that there are duplicate files with the same name. I suggest to add a rule to require the asset store seller to rename these to something different, or not include them in the asset. (Normally they are included in the demo folder of the asset)

    Not to name any assets, but here is what happens:
    error.png
    The asset store item can't compile. You have to have the know-how to go into the asset folder and fix it yourself. This has happened a few times to me.
     
    Last edited: Nov 9, 2015
    TaleOf4Gamers, hopeful and TonyLi like this.
  9. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    This problem seems to be less common nowadays, but it's an annoyance of mine, too.

    I'd prefer if developers kept these scripts in their original locations (e.g., Standard Assets) with their original metadata. This way they won't be duplicated.

    Does anyone else have any insight into this problem? Before I add this to the first post, I'd like to see if we can get a consensus on the best way to handle it.
     
    ArachnidAnimal and hopeful like this.
  10. flaminghairball

    flaminghairball

    Joined:
    Jun 12, 2008
    Posts:
    868
    A sidenote on this - if you hate the idea of cluttering up your code with UnityEngine.UI.Button everywhere, you can also force the namespace reference like so:

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. //etc
    5. using Button = UnityEngine.UI.Button;
    6.  
    That way you're still explicitly advertising which button class you're referencing, but you still get nice compact code.
     
  11. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Integration:

    Officially supported integrations.

    If asset Y says it is integrated with assets A, B, and C. I would expect the asset Y is responsible for maintaining the integration. Of course it could be that asset C could be responsible for maintaining the integration with asset Y.

    It would be nice to have a clear indication of which asset is responsible for maintaining the integration.

    There are many one time integrations that are used as examples of what can be done integrating asset Y with asset K for example. But that is not officially supported.
     
    syscrusher, hopeful and TonyLi like this.
  12. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,760
    Personally, I feel the best way is for every single script which is included with the asset, be assigned a unique name which relates to the asset. Here is an example of how MeshBaker names their scripts:
    MB2_TextureBakeResults.cs.

    This does two good things: It relates the script to MB, which stands for MeshBaker.
    It also includes the version, so if you update the asset, you can clearly see the version of the script. In this example the version of the script is 2. If they had a version 3 of the asset, the file name would be MB3_TextureBakeResults.cs.

    I don't think this can be enforced, but I think this is very good practice.
     
  13. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Sounds nasty. I don't want to break my entire project by changing script names every time its updated. Better to simply include everything in a asset inside its own namespace. Using something related to the brand name is great. How many people are going to have a name collision with BoredMormonGames.AwesomeAsset.Button?
     
    TonyLi likes this.
  14. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I just want people to learn2love Plugins folder. Final IK does this. Means I get source without bloated compile times.
     
    TonyLi, Kiwasi and hopeful like this.
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    I have to admit I'm in BoredMormon's camp on this one. I definitely agree with you that developers should make their names unique. To me, namespaces seem like the best approach. Anyone else want to weigh in?

    I've been thinking about this recently. If I could go back in time three years, I would probably put the Dialogue System's huge amount of editor code in Plugins rather than providing precompiled DLLs and the source code in a separate unitypackage.

    How would you recommend structuring the product? Everything inside a subfolder of Plugins?

    Plugins
    BoredMormonGames
    AwesomeAsset
    ExampleScenes
    Prefabs
    Scripts

    Editor
    Textures

    Or only code in Plugins?

    BoredMormonGames
    AwesomeAsset
    ExampleScenes
    Prefabs
    Textures
    Plugins
    BoredMormonGames
    AwesomeAsset
    Scripts
    Editor

    I don't really see any value in splitting it up like the latter example, but maybe I'm missing something.

    Are there any arguments against Plugins?
     
    Last edited: Nov 9, 2015
  16. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I don't have a comment on structure so long as it works and asset authors can agree. Regarding naming scripts, I don't see how that helps but namespaces definitely 100% do. There's a number of really sloppy developers that just piss me off. All assets you buy that contain code really, really need namespaces!

    I think its a bit like getting a tv service and all it does is dominate your own choices. That would be annoying!
     
    syscrusher likes this.
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @hippocoder - Do you (or anyone else) have any suggestions on the following?

    My tidiness impulse wants me to put the entire code asset under Plugins.

    The problem is supporting third party applications such as providing PlayMaker action scripts. Since PlayMaker isn't in Plugins, I'd have to keep these scripts outside of Plugins so they'll compile in the correct phase.

    Any suggestions on how to handle this?
     
  18. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Exhuming this thread to add clarifications on searching that we just received from the Asset Store staff:


    Asset Store
    Submit your asset in the right category. If you require a per-seat license, make sure it's in Editor Extensions.

    Only attach asset labels to the assets in your package if you think they'll be helpful to customers using your product. Asset labels are no longer used for searches in the Asset Store. Instead, set the product's meta data on the publisher page. Here are notes about searches and meta data:
    • You do not need to include plurals. They are automatically added to the extent that they are dictionary words.
    • Package name is included as keywords.
    • Package description is included as keywords.
    • Category is included as keyword.
    Make sure your support email and web page URL work.

    (This is also now in the first post.)
     
  19. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    This is a nice addition from the asset store!

    Another one is build your asset so it can handle alternative input systems (e.g. incontrol, rewired, etc.). Not sure how I missed this originally.
     
    TonyLi likes this.
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,605
    The following behavior appears to have been changed as of Unity 5.2.2 (according to this), but it's still worth noting as many assets will want to support back to versions prior to 5.2.2.

    In Unity 4.x - 5.2.1, "Editor" folders placed in any subfolder underneath Plugins deeper than Plugins/Editor will not compile in the editor assembly and instead will be compiled in the main assembly throwing errors and preventing compilation. Because of this behavior, it makes having your whole project under one folder impossible if you also need editor scripts. If you do, they'd have to be stored in a separate location, either outside plugins or in Plugins/Editor.
    Another way of dealing with this problem is to put your using statements inside your namespace declaration. This will override any classes of the same name in the global namespace. It's a lot cleaner than typing the fully qualified name every time, and personally I like it better than declaring each class individually.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. namespace MyNamespace {
    4.  
    5.     // These will take precedence over any global classes or any classes inside using statements that are outside the namespace declaration.
    6.     using MyOtherNamespace;
    7.     using UnityEngine.UI;
    8.  
    9.     public class MyClass : MonoBehaviour {
    10.  
    11.         Player myPlayer; // exists in MyOtherNamespace
    12.  
    13.         void SomeFunction() {
    14.             myPlayer.DoSomething(); // will not cause a compiler error if the user creates a Player class in the global or any other namespace.
    15.             Button button = GetComponent<Button>(); // will not cause a compiler error if the user creates a Button class in the global or any other namespace.
    16.         }
    17.     }
    18. }
     
    Last edited: Feb 6, 2016
    TonyLi likes this.
  21. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Good point! I'll replace the text in the original post with a link to SonicBloomEric's Where to Install Your Assets sticky.

    Very nice. This is definitely going up in the first post.
     
    guavaman likes this.
  22. syscrusher

    syscrusher

    Joined:
    Jul 4, 2015
    Posts:
    1,104
    Thanks, everyone, for this thread!

    I've been working on a small but broadly applicable set of scripts that I need for my own project, and they are sufficiently generic that I realized I might have something that I could either sell or give away on the Asset Store. I'm an experience developer in non-Unity context, so I'm already doing many of the suggested things -- but I certainly learned some new things here. I'll be reviewing and improving my code based on this thread.

    It occurs to me that quite a few of these tips are not just good advice for the Store, but also good advice for one's own project code. Reusability is reusability, regardless of whether it's a customer reusing, or you in your own next project! :)

    A big +1 from me on CHANGELOG.txt files! Anyone who is contemplating upgrading versions really needs to know what change. Especially important: new features (you worked hard to create it -- do you want your most tenured customers to overlook it because they "already know" how to use your asset?), and deprecated features (if I upgrade your asset, suddenly parts of my project stop working...I'd kind of like to be able to prepare for that).

    When I share code with others, I also tend to include an UPGRADING.txt file that gives instructions on how to upgrade from (at least) the most recent previous version. Sometimes the upgrade instructions are trivial (install and it will just work), but sometimes not.

    One final thought, from a customer perspective: Please use standard formats for that locally-available documentation. Not everyone runs Windows, and not everyone has Office, and especially not everyone has Visio. If you want to offer proprietary formats, that's nice, but please also include text, HTML, or PDF as appropriate so the docs are accessible across platforms. Open file formats are also important for archival purposes -- I can more easily read a 10 year old PDF than a 10 year old Visio file. :)
     
  23. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    @syscrusher - Good point on UPGRADING.txt.

    Regarding documentation, I think the Asset Store reviewers require an open format, preferring PDF and text, but I've also seen RTF and a few others. It's possible some assets may have slipped by with a proprietary format. I'll point this out in the first post, too.
     
    syscrusher likes this.
  24. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    I just added another sentence to the blurb on namespaces:

    New Unity users will often define their own classes with these names in the global namespace, which will break your asset unless you specify the correct namespace: Text, Button, Camera, Action.​

    If anyone has run into other names like these, let me know and I'll add them to the original post. As unfair as it may be, an unfortunate way to get a gut-reaction one-star review is to include seemingly innocent code like this:

    Code (csharp):
    1. using UnityEngine;
    2. ...
    3. var myCamera = Camera.main;
    If your customer has already defined a Camera class in the global namespace, they'll complain that your asset is broken and won't compile.

    I also added this:

    The Asset Store currently allows duplicate product names if the names are generic, such as "Mesh Painter" or "Barbarian Model". Try to choose a unique name for your asset (e.g., "Gaia" and "PlayMaker"), to prevent confusion and also avoid customers contacting you for support on someone else's asset with the same name.
    EDIT: The Asset Store's new position is: "As of June 20th, 2016 we will not accept submissions that are attempting to use a duplicate name of a pre existing, published asset."
     
    Last edited: May 27, 2016
  25. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
  26. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks! That's another good topic for designing code assets -- providing an easy way for customers to use third party input managers without having to directly modify your asset's source code. There are a lot of options for this -- C# interfaces, delegates, etc.
     
  27. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    Developer of NatCam here. I definitely suggest creating abstractions or helper classes to get as close to drag and drop as you can. NatCam was my first asset so I learnt a lot really quickly. Quite frankly, not a lot of developers have time to peruse the documentation so making the API easy to use is most important.

    A side note when developing API's with native interop: Log everything. In NatCam, just about every line is followed by a corresponding log and a lot of null checks. If not for this, NatCam would have been complete crap.
     
  28. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Can you elaborate please? Do you mean a helper class that customers can use to simplify the way they access the API?

    Null checks are just basic good coding practice. I think we can get away with covering it under the "handle exceptions" sentence in the original post.

    Good point about verbose logging. I'll add a note to the post.
     
  29. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    Hi Tony. I'll give an example with NatCam. When performing unit testing, I needed to be able to quickly run a camera preview. To do this with NatCam, several steps have to be taken including initializing NatCam and setting a camera to be used and starting the preview. Instead of redoing this for every test script, I created a component that could either be used independently or be subclassed. This makes it effortless to get going--as easy as adding a component in the editor.

    Another example was adding a component to automatically intercept UI events and detect touch gestures for focusing and zooming. If a NatCam Dev decided to implement this manually, they would have to spend about an hour perusing Unity's documentation on the events system and implementing it themselves. Doing this greatly slices development and iteration times.

    NatCam has tons of helpers and abstractions like this. The goal is to make the API as easy as it can, but also allow it to be as detailed and customizable as it needs to be. It made life so much easier for me because I myself am using it in some of my projects.
     
  30. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks! Added.
     
  31. syscrusher

    syscrusher

    Joined:
    Jul 4, 2015
    Posts:
    1,104
    The only thing better than handling an exception is coding defensively so it can never happen in the first place. :)
     
  32. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    Sometimes it's not so easy. If you're polling an external API that might return null for something, you have no choice but to null check.
     
  33. syscrusher

    syscrusher

    Joined:
    Jul 4, 2015
    Posts:
    1,104
    Oh, I quite agree. I consider a null check in *my* code, checking an API return, to be part of defensive coding. :)
     
    Lanre likes this.
  34. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Does Unity have any plans for requiring namespaces for all assets (that have code) in the asset store? That seems like it would be a good requirement for the Unity v.Next (March 2017 timeframe) is to fix all of the namespace issues.

    It seems like if Unity at least started requiring namespaces for all new assets in the store that would be a good place to start.
     
    Lanre, guavaman and Kiwasi like this.
  35. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    A good place to start would be is a namespace is added by default when making a new Monobehaviour from the editor :) Currently I use a custom c# template that includes one, though it's limited to the default "assets.scripts" namespace (eg. Assets.Scripts.Character). So next step for that custom template would be to include the solution name.
     
  36. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Not a bad idea. On the other hand it moves Unity backwards on the new dev usability curve.
     
  37. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    No real need for it to be a requirement, and while a template would be useful for several reasons (being able to change default usings and defines too), you could also just make a Default Namespace option in the Project Settings which would do the same thing, but without all of the customization options or confusion (one step at a time, right?). Visual Studio does this, iirc.
     
  38. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    Not really, considering all the new dependencies Unity itself uses (e.g. UnityEngine UI and SceneManager)
     
  39. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Does Unity use namespaces in their standard assets and their examples/tutorials?
     
  40. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Sometimes. A lot of the newer features are wrapped in namespaces. But many of the older ones aren't.
     
  41. longroadhwy

    longroadhwy

    Joined:
    May 4, 2014
    Posts:
    1,551
    Thanks for the clarification.
     
  42. AdamGoodrich

    AdamGoodrich

    Joined:
    Feb 12, 2013
    Posts:
    3,780
    +1 to namespaces - basic requirement.
     
  43. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    (If anyone new to this thread hasn't had a chance to read the first post yet, it contains the accumulated contributions of all the posters. It's well worth the time to look over.)

    Everyone seems to be in agreement that namespaces are a basic requirement. The top post also has some good comments about making sure your properly-namespaced asset plays nicely with other namespaces, such as:

    "Prevent other scripts from breaking your code asset by specifying namespaces explicitly when using common class names.... New Unity users will often define their own classes with these names in the global namespace, which will break your asset unless you specify the correct namespace: Text, Button, Camera, Action."
     
  44. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Want to voice strong agreement with those above; the code should be placed in Plugins or at least work correctly if the user moves it into Plugins, which means no hardcoded paths and no dependencies on code in the non-Plugins folder. Also, don't use shader keywords in shaders or materials unless you really, really need them, due to Unity's hardcoded limit. If your asset has 20 new shader keywords there is no way I can possibly get it to work in my project.

    And fix all compiler warnings. Yes, even the one about ParticleSystem.emission being deprecated. Google how to fix it; I know you can. :p
     
    Kiwasi and TonyLi like this.
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    Thanks! Added to the first post.
     
  46. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    A clean way to do this is using:
    Code (CSharp):
    1. #pragma warning disable [WARNING_CODE]
    Also add a warning restore at the end of the file because not doing so is undefined in the C# spec.
     
  47. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    Also, try not to include extension methods except they are absolutely necessary (like System.LINQ.Enumerable). The confusion caused is why Java creators decided not to include it.
     
  48. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    I disagree with this statement. Don't try to not include extension methods, instead, try to use them where they make sense. A very good article about that can be found here: To extend or not to extend.

    Rules of thumb from the article:
     
  49. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,670
    If I may disagree, please fix compiler warnings, don't just hide them. Most compiler warnings are API deprecation warnings. Use platform-dependent compilation to compile the correct code for each version of Unity (e.g., SceneManager.LoadScene( in Unity 5.3+, Application.LoadLevel() in earlier versions).

    Regarding extension methods, good points from both posters. My thoughts: Use them where they make sense, but keep in mind that they may not make sense if you plan to support specific platforms. For example, WinRT (Windows Store/UWP/Windows Phone) is a very restricted environment. If your code uses extension methods that WinRT doesn't support, your asset won't compile for WinRT customers.
     
    Lanre, syscrusher and DonLoquacious like this.
  50. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,969
    I completely agree with you, but the pragma directive is very helpful for seemingly unused variables when using platform dependent compilation. For instance:
    Code (CSharp):
    1. //This causes CS0414 on every platform but iOS
    2. int number = 5;
    3.  
    4. void DoStuff () {
    5. #if UNITY_IOS
    6. number *= 2;
    7. #endif
    8. }