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

Coherent UI - HTML5-based User Interface middleware

Discussion in 'Assets and Asset Store' started by stoyannk, Oct 30, 2012.

  1. Molt

    Molt

    Joined:
    Sep 6, 2011
    Posts:
    103
    This would be perfect for a project I'm beginning which needs a complex UI, and since I'm currently doing scary things with WebGL and HTML5 at the dayjob it's really appealing to me.

    I do have a few questions though before I actually spend the time and money moving my Unity UI from nGUI over to this.

    I know you don't yet support iOS at the moment but is this something you're working on, and if you are how's progress? If you do get the iOS version working will existing license holders get the iOS version without extra cost?
     
  2. MartinZhel

    MartinZhel

    Joined:
    Nov 25, 2012
    Posts:
    18
    Hello Molt,

    Yes, we are working on the iOS and soon enough we are going to support it. However, I still can't give you information about the license. As soon as it gets clear I will let you know.
     
  3. Molt

    Molt

    Joined:
    Sep 6, 2011
    Posts:
    103
    Okay, that's good enough for me, I've just placed the order.

    Looking forward to playing with this.
     
  4. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Setting focus to a UI through API throws the below error.

    Code (csharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3.  
    My usage is as follows.

    Code (csharp):
    1.  
    2.             if ( viewObject.Value == null ) {
    3.                 var go = Fsm.GetOwnerDefaultTarget( viewGameObject );
    4.  
    5.                 if ( go == null ) {
    6.                     return;
    7.                 }
    8.  
    9.                 if ( go != previousGo ) {
    10.                     view = go.GetComponent<CoherentUIView>();
    11.                     previousGo = go;
    12.                 }
    13.             } else {
    14.                 if ( viewObject.Value != previousO ) {
    15.                     view = viewObject.Value as CoherentUIView;
    16.                     previousO = viewObject.Value;
    17.                 }
    18.             }
    19.  
    20.             if ( view == null ) {
    21.                 return;
    22.             }
    23.  
    24.             view.View.SetFocus();
    25.  
    The above is a PlayMaker action; I've written about 20 for CoherentUI. I want to give focus to my HUD immediately on game play so my button mouseovers work immediately and not have to rely on click to focus. Any suggestions as to why this won't work?

    Also I am confused about information on the site. For example directly below the licenses you have support options. The support option that comes with all licenses says "Updates with security and critical fixes" while the paid support option says "Monthly updates with all new features" does this mean without paid support you won't get monthly updates for CoherentUI? If not then this should be reworded to be more clear. Would seam silly to pay $350 for the current version and not receive feature updates, etc.. Maybe I'm just being extra cautious, but it is a lot of a cash to a self funded indie.
     
    Last edited: Apr 19, 2013
  5. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Seems that the Coherent.UI.View is not created yet - they are created asynchronously and you can access it after the ViewCreated event has fired.

    So to set the focus as early as possible you may do:

    Code (csharp):
    1.  
    2. viewComponent.Listener.ViewCreated += (view) {
    3.     view.SetFocus();
    4. };
    5.  
     
  6. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    That doesn't work. I'm also using C#. The below is an example, which errors too. Doesn't quite make since as I am following the API documentation and Unity documentation exactly as it shows yet this doesn't work. So either the documentation is wrong or the API is wrong or it doesn't work... Maybe I've an out of date release (I'm still using Free version as $350 is too much for right now and need to guarantee this will work first)?

    Code (csharp):
    1.  
    2. view.Listener.ViewCreated += HandleViewCreated;
    3.  
    Code (csharp):
    1.  
    2. void HandleViewCreated( CoherentUIView view ) {
    3.     view.SetFocus();
    4. }
    5.  
    When I use the above I get the below errors.

    Code (csharp):
    1.  
    2. error CS0123: A method or delegate `HutongGames.PlayMaker.Actions.CuiViewSetFocus.HandleViewCreated(CoherentUIView)' parameters do not match delegate `Coherent.UI.ViewListener.CoherentUI_OnViewCreated(Coherent.UI.View)' parameters
    3.  
    4. error CS0428: Cannot convert method group `HandleViewCreated' to non-delegate type `Coherent.UI.ViewListener.CoherentUI_OnViewCreated'. Consider using parentheses to invoke the method
    5.  
    If someone from CUI could also answer my other questions above would be greatful.

    Note the above usage works fine for ReadyForBindings and BindingsReleased.

    EDIT: Fixed the above errors by doing the below.

    Code (csharp):
    1.  
    2. void HandleViewCreated( Coherent.UI.View view ) {
    3.     view.SetFocus();
    4. }
    5.  
    Will see if this works, but still need my other questions answered whenever possible.

    EDIT: The above works, but it's not giving focus. I still have to click to give focus.

    EDIT: Is it not possible to just set a UI to have auto focus on create?
     
    Last edited: Apr 20, 2013
  7. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Hi,

    I am on the Coherent Labs team, I'm sorry I've forgotten to add a signature or state it clear in any way.

    And I am sorry for missing out the licensing question, didn't see it the first time.

    I have to apologize once more, because the information on our website is not clear enough. We are completely overhauling it, so this will be fixed.

    The licensing scheme is similar to the one used by Unity3D - if you buy version 1.2.0.0, you are going to receive updates and fixes including new features up to version 2.0.0.0. Coherent UI will reach version 2.0.0.0 when a major and significant new feature is added, just like Unity3D.
    Event when a new major version comes out, we'll continue to support the previous one for a certain period of time.

    I am not sure I completely understand what you want to achieve, but I'll assume you want all clicks and keyboard events to go to the HUD view.
    The input forwarding is a separate setting from the focus, so:

    Code (csharp):
    1.  
    2. void Start () {
    3.     var viewComponent = GetComponent<CoherentUIView>();
    4.     viewComponent.OnViewCreated += this.ViewCreated;
    5.     viewComponent.ReceivesInput = true;
    6. }
    7.  
    8. void ViewCreated(Coherent.UI.View view) {
    9.     view.SetFocus();
    10. }
    11.  
    Let me know whether this works for you.
     
  8. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Ok, so major releases will just be upgrade purchases? I assume upgrade purchases would be discounted in same way Unity does? If so that's fine and I understand.

    Yup, I have :hover CSS usage and it only works if the UI has focus so I want my HUD to immediately have focus.

    The focus part doesn't work, but the receive inputs does. So when I click it does cause an affect on the UI, but the UI still doesn't have focus. For example using this when I click a button it'll depress, but when I hover over a button it does nothing. However if I set "click to focus" and click anywhere on the UI then all my hover usages work fine from then forward. So seams the set focus just doesn't work.

    Could this be due to the version I am using? In the license file it says "Release 1.1.5. Build 1.1.5.0" so I assume that's my full version. Should I purchase now or request new free version as maybe this is working in new builds?

    EDIT: Ok, setting receive input seams to work but the positioning is way off (which is why it seamed like it did nothing). When I mouseover my menu it doesn't cause the hover affect on what I actually moused over. It instead does the mouseover effect on the menu item 2-3 below where my mouse actually is.

    EDIT: Ok, the receive input is off due to "FlipY". Once I turn that off it's accurate, but then my UI is completely upside down.

    EDIT: Below is a screenshot of the input reversed. My mouse is on the circle yet the rectangle is the one highlighted.



    EDIT: Hate to be a pest, but I have another unrelated question. When using view.View.BindCall( eventName.Value, EventCalled ) what is the variable supposed to be for EventCalled function in C#? I'm not finding any information on what it should be in the documentation. My current usage is void EventCalled( WHAT_AM_I options ) {. I would like "options" to be an array or C# list ideally.
     
    Last edited: Apr 20, 2013
  9. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    I cannot comment yet whether there will be discounts for the upgrades. Although we have planned several new features in the next weeks, there is not going to be a major new version soon.

    I suppose you are calling CoherentUIView.SetMousePosition. This method assumes that (0, 0) is the top left corner of the screen, while Unity3D uses (0, 0) as the bottom left corner of the screen. So you have to invert the Y axis.
    Code (csharp):
    1.  
    2. viewComponent.SetMousePosition((int)Input.mousePosition.x, viewComponent.Height - (int)Input.mousePosition.y);
    3.  
    It seems we haven't documented that, so we are going to add it to the documentation.

    You can get a newer free version, if you like.

    About Coherent.UI.View.BindCall(string name, System.Delegate handler) - handler can be (almost) arbitrary C# delegate.
    Coherent UI tries to convert the JavaScript value to an instance of your C# types.

    Say you have:
    Code (csharp):
    1.  
    2. view.BindCall("ComputeSum", (double[] numbers) => {
    3.      return numbers.Sum();
    4. });
    5.  
    In JavaScript you can call the lambda function using:
    Code (csharp):
    1.  
    2. engine.call('ComputeSum', [1, 2, 3, 4]).then(function (sum) {
    3.     console.log(sum);
    4. });
    5.  
    Arrays, List<>, Dictionary<> and primitive types should be working out of the box, in both directions - .Net to JavaScript and JavaScript to .Net.

    If you want to use user defined types, you have to set their type in JavaScript. Like
    Code (csharp):
    1.  
    2. namespace MyGame
    3. {
    4.     class EndGameData
    5.     {
    6.         public int DifficultyLevel;
    7.         public string PlayerName;
    8.         public double Score;
    9.     }
    10. }
    11. // ...
    12.  
    13. view.BindCall('endGame', (GameData data) => {
    14.     Console.WriteLine("{0} has achieved {1} at level {2}", data.PlayerName, data.Score, data.DifficultyLevel);
    15. });
    16.  
    To invoke the lambda from JavaScript, you have to set the '__Type' field of the JavaScript object to typeof(MyGame.EndGameData).AssemblyQualifiedName (in our 1.2.0 release this is relaxed to the FullName of the type, which is usually Namespace.ClassName). So it becomes:
    Code (csharp):
    1.  
    2. engine.call('endGame', {
    3.     __Type: 'MyGame.EndGameData, Assembly ... Culture ....',
    4.     DifficultyLevel: 2,
    5.     PlayerName: 'John Doe',
    6.     Score: 12345,
    7. });
    8.  
    There are more details about the binding between C# and JavaScript in the CoherentUI_Documentation.chm file, in the section "Detailed Guides -> Binding -> Binding for .Net" and the Binding Unity sample.
     
    Last edited: Apr 20, 2013
  10. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    No I'm not calling that. I simple set the UI to receive input using viewComponent.ReceivesInput = true; as instructed above and all the mouse coordinates appear to be off. So this issue is happening internally with however ReceivesInput works.

    I'm still not understanding the BindCall usage, sorry. As I understand the HTML JS would use engine.call and send whatever data it wants to the function. So how many is my usage supposed to know what that is? My problem is when I use the below I get an error, because I've no idea what the data is.

    Code (csharp):
    1.  
    2.         void ViewReady() {
    3.             view.View.BindCall( eventName.Value, EventCalled );
    4.         }
    5.  
    6.         void EventCalled( WHAT_AM_I? options ) {
    7.             Fsm.Event( eventCalled );
    8.  
    9.             Finish();
    10.         }
    11.  
    With the above I get the below errors, because my delegate "EventCalled" has no idea what "options" is and I can't figure out what it is either. Note C# is strict, I need to know what it is or it's not going to work as auto assignment like in UnityScript won't apply here.

    Code (csharp):
    1.  
    2. error CS1502: The best overloaded method match for `Coherent.UI.View.BindCall(string, System.Delegate)' has some invalid arguments
    3.  
    4. error CS1503: Argument `#2' cannot convert `method group' expression to type `System.Delegate'
    5.  
    What I am wanting is to call from HTML engine.call and provide with it a array of information. In C# using BindCall I want to handle that array (List) of data inside my delegate. I can't seam to understand how to accomplish this or use the function at all. Should I be sending the List of information with the delegate? Extremely confusing API, lol.

    EDIT: The below seams to stop throwing errors. I'm not sure if it's the correct usage or not, but looks like the way this works is I use engine.call from HTML which executes my delegate and gives it the value returned by the delegate in HTML. so I think I was just misunderstanding the usage.

    Code (csharp):
    1.  
    2.         void ViewReady() {
    3.             view.View.BindCall( eventName.Value, (System.Func<string>)EventCalled );
    4.         }
    5.  
    6.         string EventCalled() {
    7.             return "pass";
    8.         }
    9.  
    EDIT: Awesome, I got BindCall working; thank you, the above was very helpful! Still having problems giving the UI focus though.
     
    Last edited: Apr 20, 2013
  11. nikxio

    nikxio

    Joined:
    Oct 30, 2012
    Posts:
    69
    Looks like you're having this issue with the input. Basically, with 1.1.5 you need to call CoherentUIView.SetMousePosition every frame with the inverted Y coordinate.

    This was reported by a lot of users as confusing so we changed it in 1.2.0 and HUD view input works out of the box. You only need to call the method for views placed on objects in the world now.
     
  12. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Ok, am I able to request a new free build with 1.2.0 or is it not out yet? So far I've got my pause and score screen basically done and looks very nice.
     
  13. nikxio

    nikxio

    Joined:
    Oct 30, 2012
    Posts:
    69
    It's out and you can request it. You'll find the custom file handler sample there, out of the box HUD input, JS binding of user defined types without having to use the assembly qualified name and various other improvements.
     
  14. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Awesome, thank you; new download requested. Everything seams to be working as desired for the most part so is definitely a purchase I will be making. I swear people are shooting themselves in the foot by not using CUI or similar solutions for UI. Using traditional methods like UnityUI or NGUI is a absolute nightmare compared to this.

    As for updating I assume I just import the new Unity package then tell it to install CUI again?
     
  15. nikxio

    nikxio

    Joined:
    Oct 30, 2012
    Posts:
    69
    It's likely that you'll get multiple definition errors if you just import the package and the install option will be unavailable.

    You'll have to delete any CoherentUI resources beforehand and then import install the new version of Coherent UI. Deleting Assets/Standard Assets/Scripts/CoherentUI might be enough but should that give you any trouble you can delete the following:
    • Assets/CoherentUI
    • Assets/Plugins/Coherent*
    • Assets/Standard Assets/Scripts/CoherentUI
    • Assets/Streaming Assets/Coherent*
    and then your project will be cleaned up from Coherent UI resources so you can import the updated package.
     
  16. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Updated to latest very smoothly and is working perfectly fine now. Mouseovers and everything are working fine, thank you!
     
  17. stoyannk

    stoyannk

    Joined:
    Oct 30, 2012
    Posts:
    35
    Take a look at our new version- Coherent UI 1.2.1. We have exciting new features:
    - .Net/Unity3D Method binding - now it's possible to trivially export entire classes between C# and JavaScript. This new feature greatly simplifies communication between your Unity3D code and the UI script.
    - Download support
    - Increased performance for on-demand views

    We are also very proud that Planetary Annihilation, a great RTS game in development from Uber Entertainment will use Coherent UI for it's interface.

    Read all the details on our blog.
     
    Last edited: Oct 8, 2013
  18. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    How do I send a generic array of data back to Unity in C#? The below doesn't seam to work an errors out.

    Javascript in UI HTML:
    Code (csharp):
    1.  
    2.                 var options = {};
    3.                 options.__Type = 'List<object>';
    4.                 options[0] = 456;
    5.                 engine.call( 'TEST', options ).then( function( o ) {
    6.                     $( 'body').html( 'pass' );
    7.                 });
    8.  
    9.  
    C# in Unity:
    Code (csharp):
    1.  
    2.                 view.View.BindCall( eventName.Value, (System.Func<List<object>, List<object>>) EventCalled );
    3.             }
    4.         }
    5.  
    6.         List<object> EventCalled( List<object> opts ) {
    7.  
    The above results in the below.

    Code (csharp):
    1.  
    2. Non matching Profiler.EndSample (BeginSample and EndSample count must match)
    3. Coherent.UI.CoherentUI_NativePINVOKE:UISystem_Update(HandleRef)
    4. Coherent.UI.UISystem:Update()
    5. CoherentUISystem:Update() (at Assets/Standard Assets/Scripts/CoherentUI/CoherentUISystem.cs:477)
    6.  
    Any idea why I can't send a generic array back, but can send a generic array to CUI? I'm developing generic actions to be used by PlayMaker so I can't use specific classes/functions.

    EDIT: I know the binding works, because using INT or STRING for example it works fine. I just can't get it to work with a generic array.
     
    Last edited: Apr 28, 2013
  19. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Currently Coherent UI doesn't support sending an instance of type "object" to .Net. It seems that it can be implemented, so we'll try to include that in the next release.

    I don't know the PlayMaker API, so I do not know whether this workarounds would work, but you may try to use one of them until we implement this feature.

    1. Use List<Coherent.UI.Binding.Value> instead of List<object>
    Coherent.UI.Binding.Value represents generic JavaScript values, it may be bool, string, int, double, array of values and dictionary of values with string keys. You can query its type and cast it to the corresponding .Net type. In JavaScript, you'll have to use [] instead of object with __Type property for the options collection.
    In JavaScript:
    Code (csharp):
    1.  
    2.                 var options = [456, "some string"];
    3.                 engine.call( 'TEST', options ).then( function( o ) {
    4.                     $( 'body').html( 'pass' );
    5.                 });
    6.  
    In C#:
    Code (csharp):
    1.  
    2.                 view.View.BindCall( eventName.Value, (System.Func<List<object>, List<Coherent.UI.Binding.Value>>) EventCalled );
    3.             }
    4.         }
    5.  
    6.         List<object> EventCalled( List<Coherent.UI.Binding.Value> opts ) {
    7.  
    2. Use a family of generic, but user defined classes
    Code (csharp):
    1.  
    2. namespace MyGame
    3. {
    4.     abstract class ViewObjectBase
    5.     {
    6.         public abstract object ToObject();
    7.     }
    8.    
    9.     class ViewObject<T> : ViewObjectBase
    10.     {
    11.         public T Value;
    12.        
    13.         public ViewObject()
    14.         {
    15.         }
    16.        
    17.         public ViewObject(T x)
    18.         {
    19.             Value = x;
    20.         }
    21.        
    22.         public override object ToObject()
    23.         {
    24.             return Value;
    25.         }
    26.     }
    27. }
    28.  
    Code (csharp):
    1.  
    2. /// ....
    3.                 view.View.BindCall( eventName.Value, (System.Func<List<object>, List<MyGame.ViewObjectBase>>) EventCalled );
    4.             }
    5.         }
    6.  
    7.         List<object> EventCalled( List<MyGame.ViewObjectBase> opts ) {
    8.  
    Code (csharp):
    1.  
    2.                 function CreateObject(x) {
    3.                       // dotNetType is mapping from JavaScript type names to
    4.                       // assembly qualified type names of the corresponding ViewObject Instance.
    5.                       return { __Type: dotNetType[typeof x], Value : x }
    6.                 }
    7.                 var options = [CreateObject(456), CreateObject("some string")];
    8.                 engine.call( 'TEST', options ).then( function( o ) {
    9.                     $( 'body').html( 'pass' );
    10.                 });
    11.  
    I hope that one of the workarounds works for you and I am going to keep you updated with the implementation of sending 'object' value to .Net.
     
  20. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    #1 method works perfectly for what I need. The only problem I am seeing is all Integers are being passed as UInteger. For example 123 is being sent as UInteger. Any idea how to send Integer or convert UInteger to Integer properly? I've tried int.Parse( option.ToString() ), but says the string is of the wrong format. String, Bool, and Float are all working fine.
     
  21. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    We are trying to match JavaScript types to the most strict .Net types, therefore non-negative integers are mapped to UInteger.
    Unfortunately we have missed to implement all the standard casts between the primitive .Net types and that is quite uncomfortable. We have already fixed that in the development branch so it will be in the next release for sure.

    Meanwhile you can use add an extension method for proper casting to int

    Code (csharp):
    1.  
    2. namespace Coherent.UI.Binding
    3. {
    4.     static class ValueExtension
    5.     {
    6.         public static int ToInt(this Value value)
    7.         {
    8.             switch (value.Type)
    9.             {
    10.                 case ValueType.Integer: return (int)value;
    11.                 case ValueType.UInteger: return (int)(uint)value;
    12.                 case ValueType.Number: return (int)(double)value;
    13.             }
    14.             throw new System.Exception("not a number");
    15.         }
    16.     }
    17. }
    18.  
    19.  
    And use it like this:
    Code (csharp):
    1.  
    2. int x = value.ToInt();
    3.  
     
  22. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Wow, I feel dumb, lol; didn't realize I could double cast. I just double casted the UInteger case in my code to int and it works fine. Thanks again for your awesome support! It looks like I've confirmed CUI will cover all my usages and the API is solid, should be purchasing this month. :)
     
  23. stoyannk

    stoyannk

    Joined:
    Oct 30, 2012
    Posts:
    35
    Last edited: Oct 8, 2013
  24. Molt

    Molt

    Joined:
    Sep 6, 2011
    Posts:
    103
    On your site I see that the non-Unity version of Coherent U works on Linux, are there any plans to add Linux support into the Unity version too?
     
  25. Tinus

    Tinus

    Joined:
    Apr 6, 2009
    Posts:
    437
    +1 Request for Linux support. I'd love to work with Coherent UI, but I've committed to support Linux for all my games. :)
     
    Last edited: May 15, 2013
  26. stoyannk

    stoyannk

    Joined:
    Oct 30, 2012
    Posts:
    35
    On the Linux Unity support:

    Yes, there definitely will be.
    Actually at the moment the issue stopping us is linked to Unity's support for plugins with native rendering on Linux. As soon as we have sorted this out a version will be made available.
     
  27. freejack

    freejack

    Joined:
    Mar 14, 2013
    Posts:
    3
    Hi. In the youtube tutorial there's a UserScript.cs script that enables raycasting so that mouse clicks on the CoherentUIView can be detected. I can't find this script anywhere and am unable to get clicks to register in the browser. Can someone provide this 'simple' script? I'm a unity newb so nothing is really simple at this point :(
    Also, how can I enable transparency on some items in the browser so that you can see through parts of the page?

    Thanks!
     
  28. nikxio

    nikxio

    Joined:
    Oct 30, 2012
    Posts:
    69
    Hi freejack,

    the UserScript.cs file was renamed to ObjectPicker.cs (you can find it in the Menu and HUD sample). Make sure you have a Mesh Collider component if you placed the Coherent UI View on a 3D object (and not a camera) so the click coordinates are correct. You can also try the "Click to focus" feature (available as a checkbox in the Coherent UI View component) which allows you to forward input to a view if you click on it and stop forwarding it if you click anywhere else.

    As for the transparency, you should enable the "Is Transparent" property of the Coherent UI View and control the transparency for the objects in the HTML code. For the most part, you can do that using CSS. As an example, you can use "rgba(200, 54, 54, 0.25);" to make something 1/4 opaque.
     
  29. freejack

    freejack

    Joined:
    Mar 14, 2013
    Posts:
    3
    Thanks that worked perfectly!
     
  30. Gatu

    Gatu

    Joined:
    May 20, 2013
    Posts:
    9
    Hello i just downloaded CoherentUI 1.2.2 and would like to know if there is a way to control the sound level of a View. And to push it a bit further...whether i can have 3D sound from a View!. Thanks in advance.
     
    Last edited: May 28, 2013
  31. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    We have planned to add API for full control of the audio, but we haven't done it yet.
    You can control the sound level of the view by changing the volume of the audio elements in the view, for example
    Code (csharp):
    1.  
    2. engine.on('setVolume', function (volume) {
    3.     var audioSource = document.getElementById('myAudio');
    4.    audioSource.volume = volume; // volume must between 0.0 and 1.0
    5. });
    6.  
    Code (csharp):
    1.  
    2. using Coherent.UI.Binding;
    3.  
    4. public void SetVolume(Coherent.UI.View view)
    5. {
    6.     view.TriggerEvent("setVolume", 0.5);
    7. }
    8.  
    And yes, you can have 3D sound in your view - here is a tutorial on using positional audio http://www.html5rocks.com/en/tutorials/webaudio/positional_audio/
     
  32. Gatu

    Gatu

    Joined:
    May 20, 2013
    Posts:
    9
    Thanks for the immediate answer. So if i get it correctly i cant do it using the View but have to mess with the html code.
    But what if the page is a website (playing a track) on which i have no control over the code? Can i use the same approach??
     
  33. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Yes you can do that in almost the same way. Here is a pseudo-component for that:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using Coherent.UI.Binding;
    4.  
    5. public class VolumeSetter : MonoBehaviour {
    6.     Coherent.UI.View m_View;
    7.     // Use this for initialization
    8.     void Start () {
    9.         var viewComponent = GetComponent<CoherentUIView>();
    10.        
    11.         viewComponent.Listener.ViewCreated += (view) => {
    12.             m_View = view;
    13.         };
    14.        
    15.         viewComponent.Listener.FinishLoad += (frameId, validatedPath, isMainFrame) => {
    16.             m_View.ExecuteScript(@"SOURCE OF coherent.js");
    17.             m_View.ExecuteScript(@"
    18. engine.on('setVolume', function (volume) {
    19.   var audioSource = document.getElementById('myAudio'); // or get all audio nodes with document.querySelectorAll('audio')
    20.   audioSource.volume = volume; // volume must between 0.0 and 1.0
    21. });");
    22.         };
    23.     }
    24.    
    25.     // Update is called once per frame
    26.     void SetVolume (float volume) {
    27.         m_View.TriggerEvent("setVolume", volume);
    28.     }
    29. }
    30.  
    There is one caveat though - if the webpage is playing audio through some 3rd party plugin like flash, this probably won't work. Depending on the actual plugin there still might be a solution.
     
  34. Gatu

    Gatu

    Joined:
    May 20, 2013
    Posts:
    9
    Thanks again! This is really close to what i need, though I ll be eagerly waiting for your audio API. Keep up the good work!
     
  35. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    Hello,

    We are trying to integrate our game with facebook. What we want is for the user to log in to facebook in the beginning and then to be able to post on his wall etc. My question is how do we keep the player logged in to facebook for the duration of the game? It seems that whenever we destroy a CoherentUIView the "session" is destroyed and the player has to login to facebook again.

    Thank you
     
  36. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Hi,

    To keep the Facebook session for the user the session cookies must be saved to a file on the disk and loaded later. By default in Unity3D this is done automatically after 1 minute, if there are modifications of the persistent cookies.

    Here are the relevant bits, in case you are not using the default CoherentUISystem component:

    Code (csharp):
    1.  
    2. SystemSettings settings = new SystemSettings();
    3. settings.AllowCookies = true;
    4. settings.CookiesResources = "file:///" + Application.persistentDataPath + "/cookies.dat"; // place full path to cookies store
    5.  
    Saving the cookies is performed by the WriteFile method of UnityFileHandler, which writes them to the file specified by settings.CookiesResources.

    You can see that if you leave our Facebook sample running for more than a minute and start it again it doesn't ask again for username and password.
     
  37. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    I see, ok I'll give that a shot, thank you. I have another question, see below...
     
  38. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    What is the best way to show a CoherentUIView as a UI dialog somewhere in our screen? For example we want to click an object which will then activate an HTML dialog in the center of the screen ( or somewhere else ). I know we can do that using a RenderTexture but the catch is that we want that dialog to be able to capture input.
     
  39. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    If you are using Coherent UI for HUD the easiest way is to show that dialog as part of that view - most JavaScript UI libraries have functionality for dialogues and modal dialogues and the input will be working out of the box.

    If you don't use Coherent UI for HUD then add a CoherentUIView to the main camera - it will be fullscreen, but you can leave it transparent so that only the dialog will be drawn on top of the 3D world. To make the input work properly, the "Is Transparent" and "Support Click Through" properties of the CoherentUIView must be checked in the Inspector - this way when the user clicks on the dialog it will get the input otherwise the input will go to Unity3D.

    You can use a texture for that, but you'll have to draw it yourself as an overlay and manage the input.
    What is more, you are going to have to implement a lot of window management functionality like moving and resizing.
     
    Last edited: May 31, 2013
  40. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    Let me be a bit more specific. What we want to do is display an HTML page on another surface using a RenderTexture ( this is an NGUI surface). When we click on that surface which has a collider attached, we get the normalized coordinates of the hit ( [0,1] range ) and we want to issue that click to the CoherentUIView. So our setup is this:

    - A camera with a RenderTexture and a CoherentUIView component
    - An NGUI plane which is rendered using a material that references the RenderTexture above
    - A box collider on the NGUI plane

    Then we click on the NGUI plane -> get the normalized hit coordinates -> pass them to the CoherentUIView using SetMousePosition.

    The problem is that this doesn't work and I'm not sure why. After we get the normalized coordinates we convert them to mouse coordinates by multiplying them with View.Width and View.Height respectively. We also tried using Screen.width and Screen.height to no avail.

    What is the correct way to issue a click on a CoherentUIView via code?
     
  41. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    SendMousePosition takes coordinates in the range (0..ViewWidth, 0..ViewHeight) and (0,0) it the top left corner of the screen.
    I suspect that you're giving coordinates that assume (0,0) is the bottom left corner of the screen.
    Your code should be something like:
    Code (csharp):
    1.  
    2. view.SendMousePosition((int)(x * view.Width), view.Height - (int)(y * view.Height));
    3.  
     
  42. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    I have tried both height conversions and it doesn't seem to work...
     
  43. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Sorry, I have misread your previous post.
    SendMousePosition is used to update the mouse position in the view, but doesn't make a click in it.

    To send a click event use the Coherent.UI.View.MouseEvent method with the proper MouseEventData instance.

    You can see how to fill MouseEventData in Assets/Standard Assets/Scripts/CoherentUI/Detail/InputManager.cs
     
  44. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    What's the best way to get an associative array with generic values from the UI? I'm able to send a generic associative array to the UI and it maintains key => value pairs perfectly. I want the same in reverse now basically. Example as follows.

    JS
    Code (csharp):
    1.  
    2.                 var a = [];
    3.                 a['Test3'] = 'PASS';
    4.                 engine.call( 'TEST', a ).then( function( options ) {
    5.                     $( '#hud' ).html( options['Test2'] );
    6.                 });
    7.  
    C#
    Code (csharp):
    1.  
    2. view.View.BindCall( eventName.Value, (System.Func<Dictionary<string, Coherent.UI.Binding.ValueObject>, Dictionary<string, object>>) setEventCalled );
    3.  
    Code (csharp):
    1.  
    2. Dictionary<string, object> setEventCalled( Dictionary<string, Coherent.UI.Binding.ValueObject> options ) {
    3.  
    This results in the below thrown.

    Code (csharp):
    1.  
    2. Non matching Profiler.EndSample (BeginSample and EndSample count must match)
    3. Coherent.UI.CoherentUI_NativePINVOKE:UISystem_Update(HandleRef)
    4. Coherent.UI.UISystem:Update()
    5. CoherentUISystem:Update() (at Assets/Standard Assets/Scripts/CoherentUI/CoherentUISystem.cs:477)
    6.  
    Any ideas?

    Edit: Nevermind, I figured it out. The issue was on the JS end. The below JS works with the above C# perfectly.

    Code (csharp):
    1.  
    2.                 var a = { Test3: "PASS" };
    3.                 engine.call( 'TEST', a ).then( function( options ) {
    4.                     $( '#hud' ).html( options['Test2'] );
    5.                 });
    6.  
     
    Last edited: Jun 4, 2013
  45. Gatu

    Gatu

    Joined:
    May 20, 2013
    Posts:
    9
    Hello I added a game object with a CoherentUIView on one of its sides to my game(using your trial version). The game runs at 110 fps with the CoherentUIView displaying a "static" webpage but when I load a youtube video the framerate drops under 40 fps. Only by setting the quality of the video to 140p(unacceptable quality) i get back the previous framerate.
    I even tried setting the target framerate for the view to 10...but nothing changed. Should I do anything else for the target framerate to work? Maybe there is another way to handle this?
    Thanks.
     
    Last edited: Jun 5, 2013
  46. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Hi,

    We need more information in order to be sure why the framerate drops. It is normal static page to have much higher framerate, because it is not rendered any more and all resources on the system are available for Unity3D. Playing a video consumes resources of the system - video decoding, and compositing the new frame to be drawn in Unity3D.
    On what system - OS and hardware you are experiencing this behavior?
     
  47. Gatu

    Gatu

    Joined:
    May 20, 2013
    Posts:
    9
    The problem was graphics card drivers. I updated and everything is ok !
    But now i have another question. When i built and ran the project unity didnt seem to include the folder UIResources in the build(i have an html file and some javascript files in there). Should i put the folder somewhere else?(when i put it inside Assets coherentUIView doesnt "see" it - plus unity tries to compile my scripts which i dont want)
    Any help with this?
     
  48. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    To make Coherent UI copy the UIResources folder you have to tell it where the folder is using the Edit -> Project Settings -> Coherent UI -> Select UI folder menu entry.
     
  49. sirival

    sirival

    Joined:
    Sep 14, 2011
    Posts:
    146
    Hi there - we have a build server that is running Unity in headless mode. The machine that the build server is running on does not have a compatible graphics card, so we cannot open the Unity Editor, it's just there for building. Is there a file that we can edit that describes where the UIResources folder is located? As I said we cannot open the Unity Editor and select it manually.

    Also it is very inconvenient to have to select the UIResources folder AND also have to Install Coherent UI, in every machine that uses it. All the developers in the team are syncing the project using Mercurial and you will agree that the ideal thing would be that this is all that is needed for Coherent UI to work. We have checked in Coherent UI but every time a developer pulls the repository, they have to go install it again AND pick the UIResources foilder.

    In any case the most important thing for us is to somehow set the UIResources folder without having to open Unity, because we cannot change our build server...
     
  50. DimitarT

    DimitarT

    Joined:
    Apr 8, 2013
    Posts:
    99
    Starting from version 1.2.2 you can set the UIResources folder on the build server by adding a static string member ProjectUIResources to our CoherentPostProcessor class
    Code (csharp):
    1.  
    2. public partial class CoherentPostProcess
    3. {
    4.     public static string ProjectUIResources =  "path to UI resources folder";
    5. }
    6.  
    The ProjectUIResources member is used by our post build step to copy the UI resources to the game when there is not player preference "CoherentUIResources".

    To avoid setting the folder when using the editor, you can pragmatically set the "CoherentUIResources" player preference
    Code (csharp):
    1.  
    2. public partial class CoherentPostProcess
    3. {
    4.     public static string ProjectUIResources =  GetUIResourcesFolder();
    5.  
    6.     private static string GetUIResourcesFolder()
    7.     {
    8.         string folder = "path to UI Resources";
    9.         #if UNITY_EDITOR
    10.             PlayerPrefs.SetString("CoherentUIResources", folder);
    11.         #endif
    12.         return folder;
    13.     }
    14. }
    15.  

    I am wondering why do you have to run "Install Coherent UI" in new checkouts of your project?
    If you import the package, run the "Install Coherent UI" script and commit the installed files in the source control system, there shouldn't be a reason for running "Install Coherent UI" in a new checkout after that. Can you describe what is the behavior that forces you to run the install step again?