Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

[RELEASED] IUnified - C# Interfaces for Unity!

Discussion in 'Assets and Asset Store' started by Roland1234, Oct 25, 2013.

  1. Hacky

    Hacky

    Joined:
    Mar 22, 2013
    Posts:
    28
    Hi Roland,

    sry for uploading your files. I'm very sorry.
    And thank you very much for help. May be you stressed this fact in your read me or give an example scene with your asset.

    Best regards,
    David
     
  2. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    No worries, I managed to get a moderator's help to remove the upload in good time - I think hardly anybody noticed and there wasn't much damage done. An example scene sounds like a good idea, I'll have to think of something interesting for that so it might take a while.

    Let me know if you continue having trouble with the missing characters, I may have a potential work-around/solution for that but since I can't replicate the issue I'm a bit hesitant to include it in an official release and would need your help to verify that it does actually address the problem. Send me an e-mail (in the readme) if you're interested.

    Good coding to you!
     
  3. Game-Whiz

    Game-Whiz

    Joined:
    Nov 10, 2011
    Posts:
    100
    Just bought your plugin. Whenever I click "Select from list" Unity crashes with an out of memory error. This is happening in 4.5.2. Any idea on what's going on?
     
  4. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    I may have an idea, yes - it's possible this may be occurring if you have enough large assets included in the project that could make Unity crash should they all be loaded into memory at once. Could you verify if this is happening in a new empty project?
     
  5. Game-Whiz

    Game-Whiz

    Joined:
    Nov 10, 2011
    Posts:
    100
    That's probably it. It doesn't crash on an empty project.
     
  6. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Thanks for checking that, it gives me a lead to try for a solution. I have a possible fix that I would like to be able to test in your case, could I impose on you to send me an e-mail to try it out?
     
  7. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,361
    Bought it because I'm always interested...

    Just to be clear, you don't save interfaces; you only wrap a generic type around the only polymorphic serializable type; UnityEngine.Object. I was hoping you found a way around that polymorphic issue, oh well.

    Would have been nice if you could expose the property that uses the interface to the Inspector.
     
  8. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Correct - all IUnified does is bridge the gap to allow code design that depends on interfaces for abstraction (at the cost of introducing a generic type for each interface), but it still depends on Unity's limitations regarding what can be serialized and what can't. The implementation still needs to be a UnityEngine.Object, most likely an existing instance of a MonoBehaviour or ScriptableObject. Anything can be assigned to the container during runtime, regardless of it's type, but that's runtime only.

    You probably know that there are alot of caveats when working with Unity's serialization system, and adding references via interfaces just complicates the issue since it can be implemented by just about anything (including structs, which Unity doesn't really support if I remember). I thought it was a good compromise to depend on Unity's serialization system and simply allow for their referencing via interfaces to allow for more managed abstractions in code.

    I've toyed with the idea of handling the serialization/deserialization myself, but that's a really broad topic and goes fairly deep. May I ask, in more detail, what sort of functionality would you find useful that you were maybe expecting to see? I may be able to figure out a good compromise to make the asset about 20% cooler.

    Brohoof,
    Roland
     
  9. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    265
    Hi,

    Have found this tool very useful so thanks for the great work. One thing I'm having a problem with is drawing my Interface in a custom editor.

    I have a class 'Row' that holds a list of my interface class:

    Code (CSharp):
    1.  
    2.  
    3. public class Row : MonoBehaviour {
    4.  
    5. [SerializeField]
    6.     public List<Field> fields;
    7.  
    8.  
    The fields class is where I have my Validator Interface

    Code (CSharp):
    1.  
    2. [System.Serializable]
    3. public class Field
    4. {
    5.       // Validator
    6.     [SerializeField]
    7.     public AssetViewer_IValidateProperty myValidator
    8.     {
    9.         get { return validator.Result; }
    10.         set { validator.Result = value; }
    11.     }
    12.  
    13.     [SerializeField]
    14.     private AssetViewer_IValidatePropertyContainer validator;
    15. }
    16.  
    Now I want to draw a custom inspector, which allows me to make many fields each with a different validator. If I make the 'fields' variable NOT a list I can call:

    Code (CSharp):
    1. serializedObject.Update();
    2.                 EditorGUILayout.PropertyField(serializedObject.FindProperty("fields"), true);
    3.                 serializedObject.ApplyModifiedProperties();
    No problem! However, as soon as I make 'fields' a list I'm completely shot. Any ideas on this one?

    Thanks!
     
  10. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Hello silentslack!
    Sorry I'm just replying now, I haven't had any support issues in quite some time. As far as I can tell everything should be working properly, the only thing that looks vaguely suspicious is your decorating your Field.myValidator property with the [SerializeField] attribute - not that it should be doing any harm, as far as I know it's just superfluous.
    I'll have to try and replicate the issue as soon as I have a chance, in the meantime: does the field show up as a list in the default inspector (i.e. not defining your own custom inspector)?
     
  11. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    265
    Hey man, no problem :)

    Removing the custom editor doesn't solve things. If the field is a single variable your custom property drawer shows up, as soon as it's a list it goes.

    I've kinda hacked together a workaround by making the 'Field' class a Monobehaviour, not ideal but by adding it as a component I get the property drawers in the inspector and can still populate the 'fields' list.

    If you do find a solution it would be grand but I have something working so all is good. Thanks for the great plugin, slowly getting my head around interfaces!
     
  12. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    I've tried recreating your scenario and everything I see indicates that it should be working properly. Would it be possible for you to e-mail me a project showcasing the weirdness (my address is in the .pdf readme)? It'd really help me out - I'd hate to leave a potential bug lying around and having to make an object a MonoBehaviour when you shouldn't have to is a bit of a pain, eh?

    Oh and thanks for the compliments, that's always in demand : D - if you are still getting the hang of language features like interfaces don't hesitate to ask, I like going over that type of thing with others. Interfaces themselves are pretty simple, but can be powerful abstractions.
     
  13. sohojoe

    sohojoe

    Joined:
    Feb 13, 2015
    Posts:
    5
    Hey man, sounds great - but does it play nice with Unity5; I get the following when I click the download button:

    Possible incompatibility with Unity 5
    This package was published using Unity 4 and contains asset types which may not upgrade cleanly to Unity 5:
    • Scripts
    While Unity will generally attempt to upgrade assets to work, problems may still occur.For more information about upgrading projects to Unity 5, please refer to the Unity 5.0 Upgrade Guide.
    For more information about the compatibility of this specific package, please contact the publisher directly.
     
  14. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Hello sohojoe,
    Yes, the latest version (1.3.4) should work just fine in Unity 5. If you do discover an issue then please let me know, but everything should be completely functional.
     
  15. ESG-Steven

    ESG-Steven

    Joined:
    Mar 18, 2015
    Posts:
    38
    Hey Roland,

    Love the idea of the asset. Does it work with classes instead of interfaces? I have multiple situations where I require default functionality and variables which remove the ability to use an interface without awkward structure, so I use an abstract class instead.

    EDIT:
    To elaborate, I keep getting "No assets implement or derive from MovementController" every time I open the custom editor thing you have. I tried it with an interface but I still get the text. Not sure what I did wrong.

    Code (CSharp):
    1. public interface MovementController
    2. {
    3.     void initialize(Action<Coord> onComplete);
    4.  
    5.     void start();
    6.  
    7.     void end();
    8. }
    9.  
    10. [Serializable]
    11. public class MovementControllerContainer : IUnifiedContainer<MovementController> { }
    12.  
    13. //NEW FILE:
    14.  
    15. public class DerivedClass : MovementController
    16. {
    17.     //Some Implementation
    18. }
    In my object I just have:
    [SerializeField]
    protected MovementControllerContainer _movementController;

    Thanks,
    Steven
     
    Last edited: Jul 22, 2015
  16. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Hello Steven!
    The idea of the asset is that it will basically serialize any reference that Unity normally would, except it allows for access to that reference as the type specified by the container. What this means is that it will not, by itself, instantiate objects or expose their properties but simply hold a reference to it like any other Unity component.

    The message you are seeing indicates that there are no instances of Unity components of the type specified in your container either in the scene (as MonoBehaviours) or in the project assets (prefabs, etc). Try adding an object and attaching a component that implements your interface and it should show up in the selection list. Make a prefab out of it and it should show up in the "Project Assets" tab of that list as well.

    Finally, it should indeed work with containers that specify a class type instead of an interface if you follow the same rules as you would with interfaces i.e. you have instances that are of a type that Unity can serialize. So the container will be able to hold a reference to an abstract class that derives from MonoBehaviour, but at that point you are dealing with a type that Unity can serialize and expose natively (Unity does handle abstract classes as expected) and are honestly better off not using the asset in that case. In my opinion. Unless you've found some interesting use for my container that I hadn't considered.

    Let me know if you still can't get things working or have any other questions.
    Good coding!
     
  17. ntszar

    ntszar

    Joined:
    Aug 9, 2015
    Posts:
    1
    Hmm, Is there something that I am missing? Altogether it seems pretty simple (And Great!) But no Matter what I cannot achieve the functionality to drag and drop Implementation onto the Inspector.
    my code:

    Code (CSharp):
    1.  
    2. public interface DetectionMethod
    3. {
    4.     bool Detects(GameObject detectedObject);
    5. }
    6.  
    7. [Serializable]
    8. public class SightDetection : DetectionMethod
    9. {
    10.     public bool Detects(GameObject detectedObject)
    11.     {
    12.         return true;
    13.     }
    14. }
    15.  
    16. [Serializable]
    17. public class DetectionMethodContainer : IUnifiedContainer<DetectionMethod>
    18. {
    19. }
    20.  
    21. public class DetectionMethodComponent : MonoBehaviour
    22. {
    23.     [SerializeField] public List<DetectionMethodContainer> DetectionMethods = new List<DetectionMethodContainer>();
    24.  
    25.     public void Start()
    26.     {
    27.         var s = new DetectionMethodContainer();
    28.         s.Result = new SightDetection();
    29.         DetectionMethods.Add(s);
    30.     }
    31. }
    32.  
    33.  
    Using the code below I attached the Detection Method Component Script to my Object.
    Thanks to my Start function in the DetectionMethodComponent after running 'Play' in Unity, I get 1 entry in the list "SightDetection". so It works I guess.

    However when i try to add elements using the Unity UI nothing happens (the element row is grayed out).

    Also when using your GUI functionality to try to add the item from the list i am getting:
    'No assets found that implement or derive from DetectionMethod'

    Any hint as to what I am doing wrong?


    Update:
    It seems that it start to working after SightDetection inherits from MonoBehavior... And Put an instance of SightDetection somewhere in the code, It probably shwos that I am beginner with Unity now but =). Is there a way not to instantiate the object in the Scene at all and just Drag and drop from the Script directory?
     

    Attached Files:

    Last edited: Aug 13, 2015
  18. Roland1234

    Roland1234

    Joined:
    Nov 21, 2012
    Posts:
    186
    Due to the way Unity serializes objects, there is no straightforward way to get the functionality you want. You'd have to integrate some custom serialization into Unity to do that, which is what I've seen some other assets do. I haven't really tried any of them so I can't recommend a particular one.

    While IUnified allows you to reference things via an interface, you still have to follow the basic rules of Unity's serialization system. Although Unity can serialize objects decorated by the [Serializable] attribute: be careful. They are handled differently. They will be rooted in their parent component and deserialized as unique instances, even if you set them to the same object. They will function as expected while in the editor until you go through a serialization/deserialization phase and then bam you'll lose the common reference without error until things start acting wonky depending on what you're doing with your code (still bites me from time to time).

    But I digress.Your implementation needs to be of a type that Unity can already serialize references of: anything inheriting from UnityEngine.Object should work, which will most commonly be MonoBehaviours and ScriptableObjects. You won't be able to hold references to other objects, even [Serializable] ones, just as you wouldn't be able to do if you had a field of an abstract type that didn't inherit from UnityEngine.Object - Unity wouldn't know what to instantiate for it. Once your game is actually running though, you can set the container's Result property to anything implementing the interface, since you won't be dealing with serialization/deserialization issues any more.

    I realize this can be confusing to people, especially if you're new to Unity because it has its own way of doing things that isn't always what you'd expect. Let me know if you have any questions and I'll try to clarify things better. If I know the answer, of course.

    Good coding, and thanks for the support!