Goal
For this demo we've chosen a minigame called "Memory Box" - you can try it out on this URL. All credit for the game goes to its authors. There's only one change in the code - we added an inline CSS style style="background-color:rgba(0,0,0,0);" to the <body> element and removed the background-color: #000; line from the CSS at the top of the HTML file to make the background transparent.
If you're very eager to see the final result, the video is at the bottom of the article.
Prerequisites
- The AngryBots scene that comes with Unity3D
- A cube mesh (the Unity3D box has flipped texture coordinates and shows Coherent UI textures upside down). We used this one.
- Coherent UI for Unity3D (we'll also assume that you've already imported the package in the AngryBots project)
Scene setup
Now that you have picked a door, add the cube-textures mesh somewhere around the door. It will be used as a surface where the minigame will be rendered. You don't need the whole cube, just the front face will suffice, so feel free to delete the unneeded ones. It's helpful to rename the new GameObject to something meaningful such as "CoherentSurface". That's how we'll be referring to the object from now on.
After you're happy with the placement of the object, add a CoherentUIView component to the surface so we can display HTML on it. Configure the URL, the resolution and make sure to tick the checkbox for transparency (you might not need it, depending on the minigame) and "Click to focus". The latter redirects input to the CoherentUIView after you click on the surface and is useful if you can't be bothered to write input forwarding code :).
If you hit play now you'll already have the minigame up and running, but it won't open the door yet. The setup so far should look like this:
CoherentUIView setup for the minigame
This will toggle the functianlity of the script (which is to fire bullets only) when the user presses the spacebar. Feel free to add any other logic, such as toggling firing when the CoherentUIView gains or loses focus or anything else that you might like.
Door opening logic
When inspecting the prefab, you'll find out that this signaling breaks down to sending the "OnPlay" and "OnPlayReverse" messages to the "AudioSource" and "slidingDoor" sub-GameObjects. Now that we know how to open and close the door, we can start making changes.
We won't need the proximity triggers anymore so just disable the TriggerOnPresence component from the sliding door GameObject. We'll also need to be able to identify the door's "AudioSource" and "slidingDoor" sub-objects, so we have to rename the door to something unique, such as "interiorDoorSlidingMinigame". After we have this we can open the door with the following one-liner:
GameObject.Find("interiorDoorSlidingMinigame/slidingDoor").SendMessage("OnPlay");
Great!
Wiring the minigame completion to opening the door
"<script type="text/javascript" src="coherent.js"></script>".
This will define the "engine" object, which you can use for communication with the game.
Next, we have to find the code that's executed when you complete a level. That's at the bottom of memorybox.js, in the "if(this.isLastCorrectSquare)" conditional. If the script is totally unreadable to you, you can process it using jsbeautifier.org or some other service. Add the line "engine.call("OpenDoor");" at the end of the if block. This will send the message "OpenDoor" to the corresponding ViewListener. That's all for the HTML/JS side - just 2 lines of code!
Last, we have to handle the message sent by JavaScript in the game. To do that we make a new script, MinigameDoorOpener, and add it to the GameObject with the CoherentUIView (the CoherentSurface object). This helper script will subscribe for the View Listener's ReadyForBindings event and bind a handler for the "OpenDoor" message. The handler will simply open the door as we discussed previously. Its code is as follows (the sample script is written in C#, but you can use anything that Unity3D allows):
Now everything is wired and ready to use! After opening the door you can continue playing the minigame if you like it. You can also enhance the demo by enabling the TriggerOnPresence component of the door so it behaves like a normal door after you unlock it instead of just staying open.
Here's the video of the final result:
That's all for today's tutorial on adding big value to your game in 10 minutes. Stay tuned for more!
I love it! Thank you. I just did a GameJam and I was trying to add a puzzle game to open a door before time ran out. But the actual GameJam ended before I could complete the complex puzzle. This would make it 10x easier and cooler.
ReplyDeleteGreat Article!
ReplyDeleteOH MAN! This is GREAT! Thanks!
ReplyDeleteFor the time being i am using the desktop version and recently i tried to play an html5 game using CoherentUi. While the game starts normally in any browser i cant get it to start through the plugin. Its like my clicks don't "reach" the game.
ReplyDeleteHi Will,
ReplyDeleteYou need to tell the view with the game to consume input. You can do that by:
var viewComponent = GetComponent();
viewComponent.ReceivesInput = true;