Skip to content
This repository has been archived by the owner on Dec 5, 2023. It is now read-only.

Latest commit

 

History

History
366 lines (288 loc) · 16.7 KB

File metadata and controls

366 lines (288 loc) · 16.7 KB

#Important points

##Binding

Binding C#, UnityScript and Boo handlers to JavaScript callbacks is the same as binding for the .Net platform. You have to register handlers when the UnityViewListener's ReadyForBindings event is fired. You can do that by using either Coherent.UI.View.BindCall (for single-cast delegates) and Coherent.UI.View.RegisterForEvent (when you have multiple subscribers for the event). For more details see the general reference documentation, chapter Binding for .Net.

private void RegisterBindings(int frame, string url, bool isMain)
{
	if (isMain)
	{
		var view = ViewComponent.View;
		if (view != null)
		{
			// When engine.call('NewGame') is executed in JavaScript,
			// the this.NewGame method will be called as well
			view.BindCall("NewGame", (System.Action)this.NewGame);
		}
	}
}

The Coherent.UI.View can be obtained using the View property of the CoherentUIView component.

To take advantage of the Unity3D component and message system each CoherentUIView has the InterceptAllEvents property. If intercepting of all events is enabled, any event triggered in JavaScript on the engine object is forwarded to the game object containing the view. This is done by using SendMessage with Coherent.UI.Binding.Value[] containing all the event arguments.

engine.trigger('Event', 42);
// will execute SendMessage('Event', [42])

Note: Using this method of handling triggered events has some additional overhead over the direct .Net Coherent.UI.View.RegisterForEvent method.

##CoherentMethod attribute for .NET scripts

Instead of handling the ReadyForBindings event and doing BindCall or RegisterForEvent by yourself, you can use the CoherentMethod attribute to decorate methods in components.

Warning: This attribute only works if the CoherentUIView's Enable Binding Attribute is set to true. By default it is false.

The decorated methods will be automatically bound to the View owned by the CoherentUIView component in the Game Object. If the Game Object has no CoherentUIView component, the attribute has no effect. The CoherentMethod attribute has a string property for the JavaScript event name, and an optional boolean parameter that specifies whether the method is a call or event handler (calls can have only a single handler, while events may have many). Here's an example component using the attribute:

public class BindingComponent : MonoBehaviour {

	[Coherent.UI.CoherentMethod("NewGame")]
	void MyCallHandler()
	{
		Debug.Log("MyCallHandler called in response to engine.call('NewGame')");
	}

	[Coherent.UI.CoherentMethod("EnemySpotted", true)]
	void MyEventHandler()
	{
		Debug.Log("MyEventHandler called in response to engine.trigger('EnemySpotted')");
	}
}

Warning: Binding methods using the CoherentMethod attribute is easier than doing it manually in ReadyForBindings, but presents possible performance penalties during game startup. When the CoherentUIView component is created, it searches all the other components in the host Game Object for methods marked with CoherentMethod using reflection. This can be a costly operation and to prevent undesirable slowdowns during startup the Enable Binding Attribute property for each CoherentUIView is set to false by default.

Warning: The CoherentMethod attribute currently does NOT support dynamically added components. Methods decorated with the attribute are only bound when the CoherentUIView component is created, which is usually when the Game Object it is part of is created.

##JavaScript and Unity3D

Briefly, Unity3D can call JavaScript using events; JavaScript can call Unity3D using events or calls.

  • Events

Events can be called by JavaScript

engine.trigger("MyEvent", args);

or Unity3D

coherentUIView.View.TriggerEvent("MyEvent", args);

The "MyEvent" will be handled by any registered method in JavaScript

engine.on("MyEvent", function() {...});

or Unity3D

coherentUIView.View.RegisterForEvent("MyEvent", handlerMethod);
  • Calls

Calls, unlike events, can have only one handler. The can also return values. To execute a call from JavaScript use

engine.call("MyCall", args);

It will be handled by a method registered using

coherentUIView.View.BindCall("MyCall", handlerMethod);

##Namespaces

Coherent UI classes are placed in the Coherent.UI.Mobile namespace for the Mobile version. You can check the Coherent UI files - for instance CoherentUIView and take a look at the beginning of the file at how the namespaces are imported depending on the Unity platform targeted. Exceptions to that rule are classes that cannot be in a namespace because Unity doesn't allow it, such as components that derive from MonoBehaviour.

##Subclassing CoherentUIView and UnityViewListener

The default CoherentUIView component and the UnityViewListener provide the most common functionality and are usually enough for normal usage of Coherent UI. If you need custom behavior, you need to subclass them.

The class you derive from UnityViewListener would usually subscribe to various events that aren't handled by default. It is recommended not to override the OnViewCreated callbacks since the UnityViewListener class contains important logic that you would have to implement yourself otherwise.

The class you derive from CoherentUIView would only need to create an instance of your custom View Listener. This can be done by copying the Update method of CoherentUIView and editing it appropriately.

Note that when subclassing CoherentUIView you will no longer be able to view or edit the properties in the Inspector. That's because we're using C# properties in our component instead of fields and they are not automatically shown. To show the properties of a given C# script we need to make a new Editor script (inside the Editor folder of your Assets) that shows the properties for a specific type. We've already done that for CoherentUIView, but you'll have to do it yourself for derived classes. The script contents should be the following:

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(<YourType>))]
public class <YourType>ViewEditor : Editor {

	private <YourType> m_Target;
	private CoherentPropertyField[] m_Fields;

	public void OnEnable() {
		m_Target = target as <YourType>;
		m_Fields = CoherentExposeProperties.GetProperties(m_Target);
	}

	public override void OnInspectorGUI() {
		if(m_Target == null)
			return;
		this.DrawDefaultInspector();
		CoherentExposeProperties.Expose(m_Fields);
	}
}

Just replace with the actual name of your class.

##Coherent UI system lifetime

Since initialization of the CoherentUISystem component is a costly operation, it is designed to be done once in the first scene of your game. The component itself has the same lifetime as the application. Since Unity tears down the state of the game when you load a new scene, the component is marked not be destroyed using the DontDestroyOnLoad() function. This makes it persist through scenes and is available using the Object.FindObjectOfType function. Getting the system can be done with the following line of code:

var uiSystem = Object.FindObjectOfType(typeof(CoherentUISystem)) as CoherentUISystem;

##Customizing initialization of the Coherent UI System

When using only CoherentUIView components, the Coherent UI System will be automatically initialized using the default parameters. These parameters define global system settings such as whether cookies are enabled, local storage and cache paths, debugger port and others. Check the CoherentUISystem component for a full list.

The Coherent UI System can be initialized with parameters other than the defaults in the following ways. Either drag the CoherentUISystem component to any object and edit the properties in the Inspector window, or edit the CoherentUISystem.cs script located in Standard Assets/Scripts/CoherentUI to fit your needs.

The CoherentUISystem component is designed to be only one in the whole game. Adding more than one CoherentUISystems to your level will result in undefined behavior.

##Update cycle

In a standard C++ or .NET application you need to poll Coherent UI for surfaces each frame using the Update and FetchSurfaces API calls. In our Unity integration, this is all hidden from you and you don't have to worry about it. The CoherentUIViewRenderer component issues rendering events which are handled by our library. All that's left for you is to drag a CoherentUIView component on an object!

##Input forwarding

Due to differences in the input management for iOS/Android, Coherent UI provides a helper class for getting the list of touches for the current frame. The Coherent touch structure is InputManager.CoherentTouch - very much the same as Unity3D's Touch structure. The equivalent methods for Input.touchCount and Input.GetTouch(index) are InputManager.TouchesCount and InputManger.GetTouch(index), respectively.

For iOS there's practically no difference between the Coherent and Unity3D touches. For Android, however, Coherent touches contain only touches that reached the game (i.e. the touch wasn't filtered using the techniques described in the next paragraph). The Unity3D supplied touches on Android aren't filtered and you get all of them when using the Input.touches array, regardless of whether they are on the UI or not. When using Coherent UI for mobile, it is recommended to use Coherent touches instead of Unity3D touches to avoid platform differences between iOS and Android.

On iOS/Android all Coherent UI Views are composited in 2D on-top of your Unity3D application content. When the user start a touch event or performs a gesture there is a mechanism that decides if that event should be handled by the UI or the application. It works like this: in the properties of the View the user can select one of three input modes for a every View - "Take All", "Take None", "Transparent". Keep in mind that all those modifiers are in effect only for events that happend are in the bounds of the View. If the user touches outside a particular View the event is always handled by the game.

  • "Take All" specifies that all events are handled by the View and nothing goes to the game. It is usable if you want to have for instance an in-game browser. All touches on it should be handled by itself and not influence the game.
  • "Take None" specifies that the View passes all input to the game. This is usable if you need to just show some non-interactive views or disable their input completely in some situation.
  • "Transparent" specifies that the input is either handled by the View or the game - usable for HUDs, Menus etc. For Views with "Transparent" input mode the user is the one in charge of deciding if an element on the page is interactive - hence should receive input or is 'input transparent'. Note: iOS: Input "Transparent" views work correctly ONLY if you have included coherent.js in your HTML page. Note: Android: Input on any view works correctly ONLY if you have included coherent.js in your HTML page.

Upon touch within a View, Coherent UI Mobile inspects the touched element:

  • if the element has the CSS class coui-noinput it passes input to the game. The element does not accept input.
  • if the element has the CSS class coui-inputcallback, a method called couiInputCallback(x, y) is called on the element with the coordinates of the event. It should return "true" if the user wants the element to handle the input and "false" if the game should handle it. This allows for custom fine-grained control in JavaScript on which elements are interactive.
  • if the class coui-noinput and coui-inputcallback are missing from the element, it is assumed that it is interactable and takes the input.

To summarize: If a View has an Input State set to Transparent, all elements are by default interactive and take input. You can mark elements with the CSS class coui-noinput to make them transparent to input. If you need more advanced logic when deciding if an element is interactive or not you can decorate it with coui-inputcallback and implement a method couiInputCallback(x, y) on it.

##Custom file handler

The CoherentUISystem component makes use of a static factory function object (FileHandlerFactoryFunc) to create the FileHandler object that is used reading URLs with the coui scheme. The default function returns a handler that reads resources from the path set by Edit → Project Settings → Coherent UI → Select UI folder for the Editor and in the Data folder for built games.

The factory function object is public and can be customized. The FileHandler it returns is passed to the UI initialization routine in the Start method of the CoherentUISystem component. That means the user should set the factory function prior to the invocation of the Start method of the components - e.g. in the Awake method.

Note: You can check the execution order of event function in Unity3D on this page

This is an example usage of a custom file handler:

public class CustomFileHandlerScript : MonoBehaviour {

	class CustomFileHandler : Coherent.UI.FileHandler
	{
		public override void ReadFile (string url, Coherent.UI.ResourceResponse response)
		{
			// Implementation here
		}

		public override void WriteFile (string url, Coherent.UI.ResourceData resource)
		{
			// Implementation here
		}
	}

	//----------------------------------------------------------------------------------

	void Awake()
	{
		CoherentUISystem.FileHandlerFactoryFunc = () => { return new CustomFileHandler(); };
	}
}

##UI Resources

Files for Coherent UI are by default selected from the folder set by Edit → Project Settings → Coherent UI → Select UI folder. Resources found there will be used by the editor and will automatically be copied in your game upon build.

The selected UI resources folder is per-user so that different developers working on the game can have their UI folders wherever they want on their machine. You can also set a per-project folder for the UI resources. This is done by extending the CoherentPostProcessor class by setting a static const setting named ProjectUIResources:

public partial class CoherentPostProcessor {
	public static string ProjectUIResources = "relative/path/to/ui/resources";
}

The per-project path must be relative to the folder of the project and the extension class should live under the 'Editor' folder in Unity. This feature is very handy also if you build your game on machines that can't start Unity and you use the command line. The per-user setting overrides the per-project one so that developers can still put their resources wherever they want.

Warning: When using the "Build & run" option for Android, the required resources will NOT be packaged because this is done as a post-build step. Unity3D pushes the non-repacked APK first, and then executes the post-build step which results in an APK without UI resources and including unneeded files. To work around that, you should either use the "Build" option, which produces an APK on your computer that can be installed on a device using the ADB tool in the Android SDK, or generate an Eclipse project and run it from the IDE.

##Mobile Surface Views

Displaying CoherentUI view on a surface is straightforward for Desktop platforms. Unfortunately the performance and API restrictions of the current platforms do not allow us to fully support views on surfaces for mobile. Mobile Surface Views allow displaying of HTML5 content on a surface in mobile games with the following limitations:

  • the view must be explicitly updated using the MobileSurfaceView.UpdateView method.
  • there is no input for the view. Input could be simulated using JavaScript.

To create a Mobile Surface View, simply add the component to a object with a renderer component. The MobileSurfaceView component will create a new texture for the renderer and replace the main texture of the material with the view.

See also the Mobile Surface Sample in the samples walk-through.

##Logging

Coherent UI logs are automatically redirected to the Unity console (or game log for built games) using the Debug.Log method. You can control the minimum severity of the Coherent UI logs when initializing the Coherent UI System.