Search Unity

Asset Store: how to publish asset that has additional files for newer Unity versions

Discussion in 'Editor & General Support' started by Demigiant, Sep 29, 2014.

  1. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    Hello,

    I would like to place my new tween engine, DOTween (HOTween V2), on the Asset Store (here's the current forum thread and the official website). Problem is, while it's compatible with Unity 3.5, there are 2 additional DLLs which add tween shortcuts for, respectively, Unity 4.3 and Unity 4.6 (sprites and the new UI). When downloading from DOTween's website I simply tell users that they just have to delete those DLLs if they're on older Unity versions. I'd like to do the same with the Asset Store, but I can't unless I publish from Unity 4.6, and that would mean the subtitle would forcefully say "Requires Unity 4.6 or higher", while instead I put effort to allow DOTween to work with Unity 3.5 or higher.

    So, the question: is there a way to publish from Unity 4.6 while specifying which version is truly required? And if not, any official workarounds?
     
  2. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,263
    Good evening! Aaah that Unity version requirement thingy...

    An unofficial (but allowed) workaround is to include your DLLs in separate unitypackages, so users can import them on demand - contrary to including them by default, which would indeed throw errors on older Unity versions. I'm doing the same to support PlayMaker actions in Simple Waypoint System, where PlayMaker users just have to extract one extra unitypackage. In addition, you could also write an ordinary editor window where your users are able to select the appropriate version and then import your DLLs automagically.
     
  3. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    You may have to rip out the tween shortcut functionality and include them as source files rather than a DLL. Then you can wrap the entire contents of each file in the proper directives:

    #if UNITY_3 || UNITY_4 && !UNITY_4_6

    And

    #if !UNITY_3 && !UNITY_4 || UNITY_4_6

    You'd need to double check those as they may not be exact but are close. I had to do something similar to work around an AOT bug... every version of Unity from 3.5 to but not including 4.5 use a workaround on iOS while Unity fixed the bug, so everything else just does a normal enumeration without the workaround.
     
  4. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    @Dustin Horne That would be nice and thanks for the suggestion, but I don't want to mess up my project by converting some parts to lose code. I actually thought I'd make DOTween as direct source files, but in the end I was missing internals too much so I moved back to DLLs :p

    @Baroni I like that! I was almost thinking I would simply ZIP the additional DLLs and ask users to unzip what they needed, but the package + editor system is much nicer, thanks! :)
     
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    I actually prefer the zip approach. UAS reviewers have been known to reject packages with .unitypackages in them too, FYI. Just include text meta files in the zip so the GUIDs don't get regenerated. The Unitypackage approach requires you build the package with the lowest supported version of unity because the format can and does change. Either way, you can have an installer editor script always running that detects their version and unpacks the right one (do this for upgrades too) with no user interaction required.

    As for version-specific code in a DLL, you have to do a bit of hoop jumping. Either use Application.unityVersion if that provides enough info or have a script "on the outside" that has a bunch of #If statements to detect versions and other stuff you can't get from your DLL. Make sure this script always runs first by setting the script execution order. Set some static vars in the DLL side or use reflection from your DLL to get this information and determine your version. If you need to use classes that aren't available in a particular version, create version specific DLL's as .bytes files in your project and load them dynamically based on your current platform. (Easiest way is with a Resources folder.) Yes, it's a mess, but it works and gets around all of Unity's version and cross-platform issues. Be careful with Webplayer though as loading DLLs dynamically in there has a lot of gotchas.
     
    Last edited: Oct 4, 2014
  6. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    Hey @guavaman, thanks a lot for the additional info. I used a different approach in the end:
    1. I added an ".addon" extension to all additional files (similar to your .bytes approach), so Unity won't try to load them and there are no issues with older Unity versions
    2. Then I added a "Setup DOTween" menu item which will need to be used each time my package is updated. The editor script determines the current Unity version and A) removes the ".addon" extension from the compatible assemblies, eventually overwriting older existing versions, B) deletes the ones that are not compatible. Then refreshes the assets and voilà, it finally works :)
    I don't need to load anything dynamically at runtime, but just to activate them once in the editor, so no problems with Webplayer and such.
     
  7. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    Okay, cool. But be careful if you're just renaming the files. If your renamed .dll file ends up with the same meta GUID as the .addon it came from, the next time your user installs an update, the .dll file will probably be replaced with the .addon file but it will still be named .dll. That may be desirable as long as the .addon is nothing but a renamed .dll. If it's compressed or anything, that would be a problem. This is because of how Unity does file matching when extracting a Unity package. It matches by GUID first without regard to name or location in the project. If it finds a GUID match, it will try to replace it even if it's not the same type.

    This may ultimately not be an issue though since I remembered you can only change a file extension via System.IO and not through the Asset Database. By changing the extension that way, the meta file is probably lost and Unity will have to generate a new GUID for the renamed file. Still, I prefer the zip approach because it allows me to include the meta file for the final .dll as well, so I'll always know the meta for it in case I want to delete it or do other changes without having to rely on the relative path. Or if they move the file, I can sort of do the same thing a unitypackage does by finding that file's location by GUID, then extracting the zip over it wherever it now resides.
     
  8. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    Addons are nothing but renamed assemblies, so I should be good, but I had no idea of the possible GUID conflicts that could happen in other cases, so thanks once again for the insight. Actually, I ended scrapping ZIP files because I would've needed an external library to unzip (unless I created my own), and I didn't want that. How did you tackle that problem?

    P.S. on a side note, just saw Rewired: it looks amazing! Will probably grab it when I'll deal with my next game.
     
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,627
    NP. You can read a bit more how the Asset Database works with guids in the documentation of my Sprite Factory asset here. Look under "The all-important GUID." I discovered all this by trial and error when trying to do an importer/exporter.

    I just used the DotNetZip library. The Ms-PL license means it's okay to use in a commercial product. Just include attribution and a copy of the license. I modified it so it's internal in my editor DLL within my namespace and doesn't clutter up the public API. FYI, it does have some issues on OSX, so it needs to be modified to work properly there. (A bunch of hard-coded treatment assuming a Windows file system.)

    Thanks! :) I really enjoyed developing Rewired and I hope everyone gets a lot of use out of it. Input just shouldn't be as insanely hard as it is in Unity at present.
     
    Last edited: Oct 4, 2014