Skip to content

Commit a3badf8

Browse files
Merge pull request #251 from jeffreylanters/feature/functional-rewrite
Feature/functional rewrite
2 parents bed5027 + 40232b5 commit a3badf8

19 files changed

+738
-442
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
**Before submitting a pull request,** please make sure the following is done:
22

3-
- Fork [the repository](https://github.com/jeffreylanters/react-unity-webgl) and create your branch from `master`.
3+
- Fork [the repository](https://github.com/jeffreylanters/react-unity-webgl) and create your branch from `main`.
44
- Run `npm install` in the repository root.
55
- Ensure the [test environment](https://github.com/jeffreylanters/react-unity-webgl-tests) passes using `npm start` on the library.
66
- Format your code with [prettier](https://github.com/prettier/prettier).

README.md

Lines changed: 107 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<div align="center">
22

3-
![readme splash](https://raw.githubusercontent.com/jeffreylanters/react-unity-webgl/master/.github/WIKI/repository-readme-splash.png)
3+
![readme splash](https://raw.githubusercontent.com/jeffreylanters/react-unity-webgl/main/.github/WIKI/repository-readme-splash.png)
44

5-
[![license](https://img.shields.io/badge/license-Apache_2.0-red.svg?style=for-the-badge)](https://github.com/jeffreylanters/react-unity-webgl/blob/master/LICENSE.md)
5+
[![license](https://img.shields.io/badge/license-Apache_2.0-red.svg?style=for-the-badge)](https://github.com/jeffreylanters/react-unity-webgl/blob/main/LICENSE.md)
66
[![npm](https://img.shields.io/npm/v/react-unity-webgl.svg?style=for-the-badge)](https://www.npmjs.com/package/react-unity-webgl)
77
[![build](https://img.shields.io/github/workflow/status/jeffreylanters/react-unity-webgl/Pre-Compile%20and%20Lint?style=for-the-badge)](https://github.com/jeffreylanters/react-unity-webgl/actions)
88
[![deployment](https://img.shields.io/github/deployments/jeffreylanters/react-unity-webgl/Node%20Package%20Registry?style=for-the-badge)](https://github.com/jeffreylanters/react-unity-webgl/deployments/activity_log?environment=Node+Package+Registry)
@@ -50,6 +50,7 @@ Welcome to the React Unity WebGL Documentation! My name is Jeffrey and I'm here
5050
- [Setting the Canvas's ClassName](#setting-the-canvass-classname)
5151
- [Device Pixel Ratio and Retina Support](#device-pixel-ratio-and-retina-support)
5252
- [Tab Index and Input Keyboard Capturing](#tab-index-and-input-keyboard-capturing)
53+
- [Requesting Canvas Pointer Locking](#requesting-canvas-pointer-locking)
5354
- [Catching Runtime and Loading Errors](#catching-runtime-and-loading-errors)
5455
- [Receiving Internal and Debug Log Messages](#receiving-internal-and-debug-log-messages)
5556
- [Unmounting, Unloading and Quitting](#unmounting-unloading-and-quitting)
@@ -60,6 +61,7 @@ Welcome to the React Unity WebGL Documentation! My name is Jeffrey and I'm here
6061
- [Providing Application Meta Data](#providing-application-meta-data)
6162
- [Getting a Reference to the Unity Canvas](#getting-a-reference-to-the-unity-canvas)
6263
- [Change the Render Size of WebGL Canvas](#change-the-render-size-of-webgl-canvas)
64+
- [Taking Screenshots of the Canvas](#taking-screenshots-of-the-canvas)
6365
- [JavaScript to UnityScript types](#javascript-to-unityscript-types)
6466
- [Creating Unity WebGL builds](#creating-unity-webgl-builds)
6567

@@ -155,24 +157,24 @@ public class EnemyController : MonoBehaviour {
155157

156158
## Communication from Unity to React
157159

158-
> Available since version 6.0.0
160+
> Available since version 6.0.0, refactored in 8.6.0
159161
160162
Sending messages from Unity to React is done using Event Listeners via the Unity Context instance. Invoking these Event Listeners from your Unity Project is quite different.
161163

162164
On the React side of your project an Event Listeners can be registered to the Unity Context instance. Register the Event Listener using the "on" method as following, where "eventName" is the name of your listener, and the "eventListener" method is the Method which will be Invoked which may or may not pass along any Arguments based on your implementation.
163165

164-
> Keep in mind communication from Unity to React is global, so Event Listeners with the same name will overwrite one another.
166+
> Keep in mind communication from Unity to React is global, so Event Listeners with the same name will will be invoked on all Unity Instances.
165167
166168
> Simple numeric types can be passed to JavaScript in function parameters without requiring any conversion. Other data types will be passed as a pointer in the emscripten heap (which is really just a big array in JavaScript). For strings, you can use the Pointerstringify helper function to convert to a JavaScript string. You can read more about parameters and [JavaScript to Unityscript types](#javascript-to-unityscript-types) here.
167169
168170
```ts
169171
function on(eventName: string, eventListener: Function): void;
170172
```
171173

172-
In order to emit Event Listeners, a JSLib file has to be created within your Unity Project "Plugins/WebGL" directory. The React Unity WebGL module exposes a global Object which allows for the emitting of the Event Listeners. When writing your JSLib file, simply invoke the eventName as a member of the "ReactUnityWebGL" object within any method.
174+
In order to dispatch Event Listeners, a JSLib file has to be created within your Unity Project "Plugins/WebGL" directory. The React Unity WebGL module exposes a global method which allows for the dispatchment of the Event Listeners. When writing your JSLib file, simply invoke the eventName using the global methpd "dispatchReactUnityEvent" with an optional parameter.
173175

174-
```js
175-
ReactUnityWebGL[eventName: string];
176+
```ts
177+
function dispatchReactUnityEvent(eventName: string, ...parameters: any);
176178
```
177179

178180
#### Example implementation
@@ -216,14 +218,14 @@ function App() {
216218

217219
To emit the Event Listener we've just created, we'll have to create a new JSLib file within our Unity Project first. This JSLib file will be places within the "Assets/Plugins/WebGL" directory. The JSLib itself has nothing to do with this module, it is natively supported by Unity and is used for all communication between your CSharp and JavaScript in any given context.
218220

219-
We'll start of by creating a new method inside of our JSLib. The name of this method can be anything, but in this example we'll give it it the same name as our Event Name to keep things clean. In the body of the method, we'll emit our Event Listener by invoking a method on the "ReactUnityWebGL" object exposed by the module. All of your Event Listeners are available as a property using the Event Name on the object. We'll pass along the userName and the score. The userName has to go through the built-in "Pointer_stringify" method in order to get the value, otherwise a int pointer will be passed instead. You can read more about parameters and [JavaScript to Unityscript types](#javascript-to-unityscript-types) here.
221+
We'll start of by creating a new method inside of our JSLib. The name of this method can be anything, but in this example we'll give it it the same name as our Event Name to keep things clean. In the body of the method, we'll emit our Event Listener by invoking the global method "dispatchReactUnityEvent" exposed by this module. All of your Event Listeners are available using the Event Name as the first parameter. We'll pass along the userName and the score. The userName has to go through the built-in "Pointer_stringify" method in order to get the value, otherwise a int pointer will be passed instead. You can read more about parameters and [JavaScript to Unityscript types](#javascript-to-unityscript-types) here.
220222

221223
```js
222224
// File: MyPlugin.jslib
223225

224226
mergeInto(LibraryManager.library, {
225227
GameOver: function (userName, score) {
226-
ReactUnityWebGL.GameOver(Pointer_stringify(userName), score);
228+
dispatchReactUnityEvent("GameOver", Pointer_stringify(userName), score);
227229
},
228230
});
229231
```
@@ -350,7 +352,7 @@ function App() {
350352
351353
The Unity context object allows you to enable and disable the fullscreen mode of your application. Cursor locking (using Cursor.lockState) and full-screen mode are both supported in WebGL, implemented using the respective HTML5 APIs (Element.requestPointerLock and Element.requestFullscreen). These are supported in Firefox and Chrome. Safari cannot currently use full-screen and cursor locking. An implementation could look something like:
352354

353-
```js
355+
```ts
354356
function setFullscreen(enabled: boolean): void;
355357
```
356358

@@ -493,6 +495,47 @@ function App() {
493495
}
494496
```
495497

498+
## Requesting Canvas Pointer Locking
499+
500+
> Available since version 8.6.0
501+
502+
Asynchronously ask for the pointer to be locked on current canvas. To track the success or failure of the request, it is necessary to listen for the pointerlockchange and pointerlockerror events at the Document level.
503+
504+
```tsx
505+
function requestPointerLock(): void;
506+
```
507+
508+
#### Example implementation
509+
510+
A basic implementation could look something like this. In the following example we'll request a pointer lock on the click of a button.
511+
512+
```jsx
513+
// File: App.jsx
514+
515+
import React from "react";
516+
import Unity, { UnityContext } from "react-unity-webgl";
517+
518+
const unityContext = new UnityContext({
519+
loaderUrl: "build/myunityapp.loader.js",
520+
dataUrl: "build/myunityapp.data",
521+
frameworkUrl: "build/myunityapp.framework.js",
522+
codeUrl: "build/myunityapp.wasm",
523+
});
524+
525+
function App() {
526+
function requestPointerLock() {
527+
unityContext.requestPointerLock();
528+
}
529+
530+
return (
531+
<div>
532+
<button onClick={requestPointerLock}>Lock Pointer</button>
533+
<Unity unityContext={unityContext} />
534+
</div>
535+
);
536+
}
537+
```
538+
496539
## Tab Index and Input Keyboard Capturing
497540

498541
By default, Unity WebGL builds capture the keyboard as soon as it's loaded. This means that all keyboard input on your React Application is captured by the Unity Application instead. Doing so will result in a focus and blur on all keyboard events when clicking on, or around the Unity Application. Implementing the tabIndex of the element mitigates this issue and allows for other elements to be selected.
@@ -967,6 +1010,56 @@ function App() {
9671010
}
9681011
```
9691012

1013+
## Taking Screenshots of the Canvas
1014+
1015+
> Available since version 8.6.0
1016+
1017+
Takes a screenshot of the canvas and returns a data URL containing image data. The image data is in .png format unless otherwise specified. Enabling preserve drawing buffer within the WebGL context attributes is required in order to take a screenshot.
1018+
1019+
```ts
1020+
function takeScreenshot(
1021+
dataType?: "image/png" | "image/jpeg" | "image/webp",
1022+
quality?: number
1023+
): string | null;
1024+
```
1025+
1026+
#### Example implementation
1027+
1028+
A basic implementation could look something like this. In the following example a button is added to the Render. When it's being clicked, a high quality JPEG screenshot will be taken and opened within a new tab.
1029+
1030+
```jsx
1031+
// File: App.jsx
1032+
1033+
import React from "react";
1034+
import Unity, { UnityContext } from "react-unity-webgl";
1035+
1036+
const unityContext = new UnityContext({
1037+
loaderUrl: "build/myunityapp.loader.js",
1038+
dataUrl: "build/myunityapp.data",
1039+
frameworkUrl: "build/myunityapp.framework.js",
1040+
codeUrl: "build/myunityapp.wasm",
1041+
webglContextAttributes: {
1042+
preserveDrawingBuffer: true,
1043+
},
1044+
});
1045+
1046+
function App() {
1047+
function handleOnClickTakeScreenshot() {
1048+
const data = unityContext.takeScreenshot("image/jpeg", 1.0);
1049+
if (data !== null) {
1050+
window.open(data, "_blank");
1051+
}
1052+
}
1053+
1054+
return (
1055+
<div>
1056+
<button onClick={handleOnClickTakeScreenshot}>Take Screenshot</button>
1057+
<Unity unityContext={unityContext} />
1058+
</div>
1059+
);
1060+
}
1061+
```
1062+
9701063
## JavaScript to UnityScript types
9711064
9721065
Simple numeric types can be passed to JavaScript in function parameters without requiring any conversion. Other data types will be passed as a pointer in the emscripten heap (which is really just a big array in JavaScript). For strings, you can use the Pointerstringify helper function to convert to a JavaScript string.
@@ -984,19 +1077,19 @@ A basic implementation could look something like this. In this example a series
9841077
9851078
mergeInto(LibraryManager.library, {
9861079
GameOver: function () {
987-
ReactUnityWebGL.GameOver();
1080+
dispatchReactUnityEvent("GameOver");
9881081
},
9891082
NextWave: function (waveNumberValue) {
990-
ReactUnityWebGL.NextWave(waveNumberValue);
1083+
dispatchReactUnityEvent("NextWave", waveNumberValue);
9911084
},
9921085
ShowPopup: function (textStringPointer) {
993-
ReactUnityWebGL.ShowPopup(Pointer_stringify(textStringPointer));
1086+
dispatchReactUnityEvent("ShowPopup", Pointer_stringify(textStringPointer));
9941087
},
9951088
SubmitScores: function (scoresFloatArrayPointer, arraySize) {
9961089
var scores = [];
9971090
for (var i = 0; i < arraySize; i++)
9981091
scores.push(HEAPF32[(scoresFloatArrayPointer >> 2) + i]);
999-
ReactUnityWebGL.SubmitScores(scores);
1092+
dispatchReactUnityEvent("SubmitScores", scores);
10001093
},
10011094
});
10021095
```

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
"url": "https://paypal.me/jeffreylanters"
2929
}
3030
],
31-
"main": "./distribution/exports.js",
32-
"types": "./distribution/exports.d.ts",
31+
"main": "./distribution/index.js",
32+
"types": "./distribution/index.d.ts",
3333
"browserslist": {
3434
"production": [
3535
">0.2%",

0 commit comments

Comments
 (0)