Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Common JS Interface and WebGL

Community Beginner ,
Oct 11, 2016 Oct 11, 2016

I'm not a Captivate Developer, but am responsible for writing some WebGL compatibility testing code for the courseware we are developing. I'm hoping to gain some insight into how to execute some custom javascript, and then show/hide some groups on a page based on the results of said javascript.

Basically, we will have two groups of content on a slide, one containing some Unity interactives that will be running in WebGL, another containing videos that will display if the user's browser is not WebGL compatible.

Since the user can navigate to any slide at any given time, I need to perform this compatibility check on each slide that contains the WebGL content.

What I want to do is:

When a page loads, execute some javascript that defines and executes some functions, which in turn set a variable isWebGLCompatible. Then I want to check whether this variable is true or false, and then show/hide the groups containing the appropriate content.

Is something like this possible inside captivate?

1.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Oct 11, 2016 Oct 11, 2016

I think you should create a variable for WebGL and run JavaScript on enter of the first slide to populate it as 0 or 1.

Then create conditional advanced actions to execute on enter of the slides in question to show/hide the applicable groups.

This could all be done dynamically with external JavaScript depending on how you name the elements within the groups. Note that there are no groups to reference in JavaScript.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 11, 2016 Oct 11, 2016

Unfortunately, we can't rely on setting the variable on the first slide, as the user has the freedom to return to any slide using bookmarks, etc.

I've got another solution using pure external js to set the variable, but it involves modifying Captivate's generated index.html file to reference the external js. This will work, but I'd like to avoid this solution if possible.

Is it possible to set the variable and then do the check all on one slide?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Oct 11, 2016 Oct 11, 2016

Then set it in the Head of the html page using the slide enter listener in the Common JS Interface.

In my testing the first slide is always executed even using bookmarks in HTML5.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 11, 2016 Oct 11, 2016

I'm bit puzzled by the heading of this thread. Could you suggest a better TItle, please, because this seems not to be about 'multiple advanced actions'. I could change the title for you if you have a better idea.

If you want to use a conditional action on each slide, I'd suggest a shared action anyway. You can show/hide groups with advanced and shared actions.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Oct 13, 2016 Oct 13, 2016

I'd be interested in seeing an example of this, even with generic WebGL content.

Lilybiri​: Maybe call it Common JS Interface and WebGL.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 13, 2016 Oct 13, 2016

Thanks, changed the title as you recommended.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 30, 2016 Nov 30, 2016

Is there any examples of where WebGL objects have been added to a captivate project successfully? I am attempting to do this with Unity output and would love to learn from someone who has been successful. The only way I can see currently is through a web object linked to the unity WebGL output. I would like to be able to have discreet smaller objects active on the regular captivate page. I have to output to HTML5 and need the 3d objects to be accessible within Captivate. 

 

Much thanks, 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 30, 2016 Nov 30, 2016

We've done this successfully.

In a nutshell, if you create a WebObject in captivate, then in its source, you simply give the name of the folder that you will be building your Unity output to, you should be good to go.

If you're building Unity using WebGL to a directory called "UnityBuild", the path you would give the webobject is UnityBuild/index.html.

Then, after publishing the Captivate project, move the Unity Build folder into the root of the published Captivate directory.

This will let everything work. However, this will embed the WebGL content as an iframe inside of your captivate content, and any scripts running inside the iframe (UnityLoader.js for example) will be seen as cross-site scripting attempts if you try running it locally, so you'll have to run from a server (could even be localhost using something like xampp), or you can run locally in FireFox, as it has more lax security restrictions.

But, if I remember correctly, this WebGL content will have to reload every time you change the captivate slide (even if the webobject is set to persist). This is incredibly annoying, and we had to develop a custom solution to remove the iframe from Captivate's DOM heirarchy in the webpage (so that it won't be forced to reload). Then some considerations also have to be made in order to allow proper scaling with Captivate (if you want it).

Captivate and WebGL don't work well together in my experience, but it is possible.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 07, 2017 Jan 07, 2017

Thanks for this answer. It is much appreciated. I have run into another issue with the Unity/WebGL in Captivate.

I have been working with this for awhile now. If you zip up the Unity WebGL output it goes in through the browse as a web object. My new issue: The webobject loads on the top layer of the iframe. Now adobe states:

In Adobe Captivate 9, web objects and HTML 5 animations (when layered with other shapes) always appear on top 

To work around this issue in HTML5, do the following:

  1. In your Captivate installation folder, open the AdobeCaptivate.ini file.
  2. Edit the file to change the value of UseWidget7 to 1 as follows:

UseWidget7=1
  3. Close and re-launch Adobe Captivate.

You can now position your web objects on top or bottom, and they appear as expected in HTML 5. 

Which I have done so my Captivate buttons etc appear on top. The bummer is that now my Unity controls don’t work? If I switch back to  UseWidget7=0  it is now on the top layer but the buttons work. Did you run into this?

Much thanks for any help.

Collene

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Feb 07, 2017 Feb 07, 2017
LATEST

We had a similar issue when we created our course. Unfortunately, I don't think there's a quick and easy fix.

It sounds like you have Captivate buttons which overlap your Unity content? We didn't encounter this specific problem, but we did have to do a bit of wizardry to make Unity and Captivate play nicely.

Captivate makes a lot of div tags in the HTML DOM, and I suspect that whatever div contains the buttons in question is also blocking interaction with Unity (I assume the Unity interactions are mouse clicks?).

Honestly, it would be a lot (and I mean A LOT) less effort to move the Captivate buttons to a location where they don't overlap Unity (or to resize Unity so it doesn't obscure the buttons).

If that's not an option, I would go with this route:

Remove those buttons from Captivate completely, and revert to having Unity sit on the top zIndex. Instead of having them embedded in Captivate, I would create the buttons either in the html file responsible for launching Unity (iframe), or programatically through custom JavaScript added to the captivate output after it's been published. Alternately, you could put the buttons directly inside of Unity.

If adding the buttons to the iframe or through javascript in the published Captivate HTML, you'll have to look into Captivate's Common JavaScript Interface API​ (Also known as cpAPIInterface) in order to have the buttons communicate with Captivate.

If you add the buttons directly to Unity, you'll have to make calls to Application.ExternalCall() inside of Unity in order to call external javascript from your Unity interactive. These calls, presumably, would wind up going through the cpAPIInterface as well. Additionally, you might have to use the javascript function SendMessage() that comes with every WebGL build to call functions on Unity GameObjects from external JavaScript.

In my opinion, I think it would be easier to add the buttons to Unity (although I'm not entirely sure what the functionality of these buttons is). My reasoning for this is simply that it would be easier to lay the buttons out properly using Unity's UI tools than trying to make it work in the iframe or in Captivate's HTML (and the buttons would scale properly with Unity this way as well).

This can be a huge pain, but might be your only hope. If you're going to attempt this, I would strongly advise that you familiarize yourself with the cpAPIInterface, particularly with the getVariableValue and setVariableValue functions, as well as with some of the cpAPIInterface events like CPAPI_SLIDEENTER and CPAPI_VARIABLEVALUECHANGED. Those were the ones I found most useful.

I hope this helps. Best of luck!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Help resources