Skip to content

Commit 36c231b

Browse files
marklundinCopilot
andauthored
ESM tutorial fixes (#777)
* Enhance JSON loading tutorial with ESM examples and tabbed interface for better clarity and organization * Enhance Google Ads tutorial with tabbed interface for Classic and ESM code examples * Enhance custom shaders tutorial with tabbed interface for Classic and ESM code examples * Refactor custom shaders tutorial to remove redundant comments and clarify resource types for shaders and textures * Enhance animated textures tutorial with tabbed interface for Classic and ESM code examples * linting * Update loading-json.md Co-authored-by: Copilot <[email protected]> * Update custom-shaders.md --------- Co-authored-by: Copilot <[email protected]>
1 parent 8b4ab12 commit 36c231b

File tree

4 files changed

+186
-14
lines changed

4 files changed

+186
-14
lines changed

docs/tutorials/animated-textures.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ tags: [animation, textures]
44
thumb: https://s3-eu-west-1.amazonaws.com/images.playcanvas.com/projects/12/405882/831708-image-75.jpg
55
---
66

7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
710
<div className='iframe-container'>
811
<iframe src="https://playcanv.as/p/BM93v05L/" title="Animated Textures" allow="camera; microphone; xr-spatial-tracking; fullscreen" allowfullscreen></iframe>
912
</div>
@@ -16,6 +19,9 @@ It can be very useful to animate a material that has been applied to a surface.
1619

1720
The square plane in the example uses the script `scrolling-texture.js` to constantly move the UV offset every frame. For example, this can be used to simulate flowing water. The update loop is displayed below.
1821

22+
<Tabs defaultValue="classic" groupId='script-code'>
23+
<TabItem value="classic" label="Classic">
24+
1925
```javascript
2026
ScrollingTexture.prototype.update = function(dt) {
2127
var velocity = ScrollingTexture.tmpVec2;
@@ -36,6 +42,32 @@ ScrollingTexture.prototype.update = function(dt) {
3642
};
3743
```
3844

45+
</TabItem>
46+
<TabItem value="esm" label="ESM">
47+
48+
```javascript
49+
update(dt) {
50+
const velocity = ScrollingTexture.tmpVec2;
51+
const offset = ScrollingTexture.tmpOffset;
52+
53+
// Calculate how much to offset the texture
54+
// Speed * dt
55+
velocity.set(this.speed.x, this.speed.y);
56+
velocity.scale(dt);
57+
58+
// Update the diffuse and normal map offset values
59+
offset.copy(this.material.diffuseMapOffset);
60+
offset.add(velocity);
61+
62+
this.material.diffuseMapOffset = offset;
63+
this.material.normalMapOffset = offset;
64+
this.material.update();
65+
};
66+
```
67+
68+
</TabItem>
69+
</Tabs>
70+
3971
We calculate the required offset into a temporary vector `tmp`. This is simply: `speed * timeStep`. Then we add this offset to the offset property for both the diffuse map and the normal map by modifying the `diffuseMapOffset` and `normalMapOffset` properties. These values are `pc.Vec2`s which shift the UV co-ordinates used to map the texture to the surface. If you are using other maps (e.g. emissive) you will also need to update these offset properties as well. Finally we call `material.update()` to propagate the changes into the shader.
4072

4173
This is a simple straightforward method to modify a material's offset and scroll a texture. It does have one downside which is this code modifies the actual material's properties. So if you have multiple models in a scene with the same material, they will all be affected.

docs/tutorials/custom-shaders.md

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ this.material.setParameter('uDiffuseMap', diffuseTexture);
140140
The effect demonstrated in this tutorial is achieved using a height map texture. We access the texture from the asset registry using the code above. At the
141141
top of our script we have declared a script attribute called 'maps' which allows us to set a texture from the PlayCanvas Editor:
142142

143+
<Tabs defaultValue="classic" groupId='script-code'>
144+
<TabItem value="classic" label="Classic">
145+
143146
```javascript
144147
CustomShader.attributes.add('vs', {
145148
type: 'asset',
@@ -166,6 +169,46 @@ CustomShader.attributes.add('heightMap', {
166169
});
167170
```
168171

172+
</TabItem>
173+
<TabItem value="esm" label="ESM">
174+
175+
```javascript
176+
/**
177+
* @attribute
178+
* @title Vertex Shader
179+
* @type {Asset}
180+
* @resource shader
181+
*/
182+
vs;
183+
184+
/**
185+
* @attribute
186+
* @title Fragment Shader
187+
* @type {Asset}
188+
* @resource shader
189+
*/
190+
fs;
191+
192+
/**
193+
* @attribute
194+
* @title Diffuse Map
195+
* @type {Asset}
196+
* @resource texture
197+
*/
198+
diffuseMap;
199+
200+
/**
201+
* @attribute
202+
* @title Height Map
203+
* @type {Asset}
204+
* @resource texture
205+
*/
206+
heightMap;
207+
```
208+
209+
</TabItem>
210+
</Tabs>
211+
169212
When our height map texture is loaded we can set the uniform `uHeightMap` to be the `pc.Texture` object.
170213

171214
## Updating uniforms
@@ -235,8 +278,6 @@ export class CustomShader extends Script {
235278
static scriptName = "customShader";
236279

237280
/**
238-
* Vertex Shader
239-
*
240281
* @attribute
241282
* @title Vertex Shader
242283
* @type {Asset}
@@ -245,8 +286,6 @@ export class CustomShader extends Script {
245286
vs = null;
246287

247288
/**
248-
* Fragment Shader
249-
*
250289
* @attribute
251290
* @title Fragment Shader
252291
* @type {Asset}
@@ -255,8 +294,6 @@ export class CustomShader extends Script {
255294
fs = null;
256295

257296
/**
258-
* Diffuse Map
259-
*
260297
* @attribute
261298
* @title Diffuse Map
262299
* @type {Asset}
@@ -265,8 +302,6 @@ export class CustomShader extends Script {
265302
diffuseMap = null;
266303

267304
/**
268-
* Height Map
269-
*
270305
* @attribute
271306
* @title Height Map
272307
* @type {Asset}

docs/tutorials/google-ads-for-games.md

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ tags: [scripts, monetization, games]
44
thumb: https://s3-eu-west-1.amazonaws.com/images.playcanvas.com/projects/12/889020/CDC848-image-75.jpg
55
---
66

7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
710
Links for this tutorial:
811

912
- [Flappy Bird Demo][flappy-bird-ads-demo]
@@ -46,6 +49,9 @@ Go to the [Google H5 Ad Tutorial (Start)][tutorial-template-start] project dashb
4649

4750
This is a simple project where it's ready for us to add the button click callbacks to show the ads in the `ui-controller.js` script:
4851

52+
<Tabs defaultValue="classic" groupId='script-code'>
53+
<TabItem value="classic" label="Classic">
54+
4955
```javascript
5056
// ...
5157
// initialize code called once per entity
@@ -75,6 +81,37 @@ UiController.prototype.initialize = function() {
7581
};
7682
```
7783

84+
</TabItem>
85+
<TabItem value="esm" label="ESM">
86+
87+
```javascript
88+
// ...
89+
// initialize code called once per entity
90+
initialize() {
91+
this.rewardedGivenPanelEntity.enabled = false;
92+
this.rewardedAdButtonEntity.button.active = false;
93+
94+
const onRefresh = () => {}
95+
96+
this.refreshButtonEntity.button.on('click', onRefresh)
97+
98+
this.interstitialAdButtonEntity.button.on('click', (e) => {
99+
100+
});
101+
102+
this.rewardedAdButtonEntity.button.on('click', (e) => {
103+
104+
});
105+
106+
this.okRewardButtonEntity.button.on('click', (e) => {
107+
108+
});
109+
};
110+
```
111+
112+
</TabItem>
113+
</Tabs>
114+
78115
The first step is to add the Google SDK integration files which we can do by copying the folder 'Google H5 Games Ads' from the [Flappy Bird project][flappy-bird-ads-demo].
79116

80117
![](/img/tutorials/google-afg/copy-afg-folder.gif)
@@ -202,6 +239,9 @@ Let's start with adding an interstitial ad to the project.
202239

203240
Add the following code to the interstitial ad button click event callback in `ui-controller.js`:
204241

242+
<Tabs defaultValue="classic" groupId='script-code'>
243+
<TabItem value="classic" label="Classic">
244+
205245
```javascript
206246
// ...
207247
this.interstitialAdButtonEntity.button.on('click', function(e) {
@@ -336,6 +376,9 @@ var onRefresh = function () {
336376
// ...
337377
```
338378

379+
</TabItem>
380+
</Tabs>
381+
339382
When the refresh button is pressed, we disable the reward button entity so that it isn't shown to the player and we are in a known state.
340383

341384
In the `beforeReward` callback, we keep a reference to the function to show the ad and enable the reward button as we know we can show an ad to the player.
@@ -367,9 +410,6 @@ Let's see it in action:
367410

368411
The completed `ui-controller.js` file should look like this:
369412

370-
import Tabs from '@theme/Tabs';
371-
import TabItem from '@theme/TabItem';
372-
373413
<Tabs defaultValue="classic" groupId='script-code'>
374414
<TabItem value="esm" label="ESM">
375415

docs/tutorials/loading-json.md

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Loading JSON Data
33
tags: [loading]
44
thumb: https://s3-eu-west-1.amazonaws.com/images.playcanvas.com/projects/12/405827/G8YF23-image-75.jpg
55
---
6+
import Tabs from '@theme/Tabs';
7+
import TabItem from '@theme/TabItem';
68

79
<div className="iframe-container">
810
<iframe src="https://playcanv.as/p/cHnXIXoN/" title="Loading JSON Data" allow="camera; microphone; xr-spatial-tracking; fullscreen" allowfullscreen></iframe>
@@ -12,6 +14,43 @@ thumb: https://s3-eu-west-1.amazonaws.com/images.playcanvas.com/projects/12/4058
1214

1315
## Loading JSON from an asset
1416

17+
<Tabs defaultValue="classic" groupId='script-code'>
18+
<TabItem value="esm" label="ESM">
19+
20+
```javascript
21+
22+
/**
23+
* @attribute
24+
* @title Character Data
25+
* @type {Asset}
26+
* @resource json
27+
*/
28+
characterData = null;
29+
30+
parseCharacterData(data) {
31+
const names = [];
32+
33+
// Read the character data from the JSON asset and return a list of names
34+
const characters = data.characters;
35+
for (let character of characters) {
36+
names.push(character.firstName + ' ' + character.lastName);
37+
}
38+
39+
return names;
40+
}
41+
42+
//...
43+
44+
// Get JSON data from a project asset
45+
const characterData = this.characterData.resource;
46+
47+
// Parse JSON data
48+
const names = this.parseCharacterData(characterData);
49+
```
50+
51+
</TabItem>
52+
<TabItem value="classic" label="Classic">
53+
1554
```javascript
1655
Game.attributes.add('characterData', {
1756
type: 'asset',
@@ -42,12 +81,38 @@ var characterData = this.characterData.resource;
4281
var names = this.parseCharacterData(characterData);
4382
```
4483

84+
</TabItem>
85+
</Tabs>
86+
4587
You can see in the code above that all you need to do to load JSON data from an asset in your project is to use a Script Attribute of type 'asset' or to retrieve the asset from the asset registry, then access the `resource` property. For an asset of type `json` the data will already be parsed into a standard javascript object when you access the `resource` property.
4688

4789
Once you have the javascript object you can access the data as normal. For example, looping through properties as in `parseCharacterData`.
4890

4991
## Loading JSON from a remote server
5092

93+
<Tabs defaultValue="classic" groupId='script-code'>
94+
<TabItem value="esm" label="ESM">
95+
96+
```javascript
97+
async function loadJsonFromRemote(url, callback) {
98+
const res = await fetch(url);
99+
const json = await res.json();
100+
callback(json);
101+
}
102+
103+
//...
104+
105+
// load JSON from a remote server
106+
loadJsonFromRemote("https://api.github.com/", (data) => {
107+
// display JSON data from remote server
108+
el = document.querySelector("#xhr-json");
109+
el.textContent = JSON.stringify(data, null, 4);
110+
});
111+
```
112+
113+
</TabItem>
114+
<TabItem value="classic" label="Classic">
115+
51116
```javascript
52117
Game.prototype.loadJsonFromRemote = function (url, callback) {
53118
var xhr = new XMLHttpRequest();
@@ -68,6 +133,9 @@ this.loadJsonFromRemote("https://api.github.com/", function (data) {
68133
});
69134
```
70135

136+
</TabItem>
137+
</Tabs>
138+
71139
In this code we are using the XMLHttpRequest object (which is part of the standard web browser API) to request JSON data from a URL, in this case the Github API.
72140

73141
After receiving the `"load"` event we parse the JSON data using `JSON.parse` (another part of the standard web browser API) and return the data via the `callback` function.
@@ -76,9 +144,6 @@ Note, that the call to `loadJsonFromRemote` is **asynchronous**.
76144

77145
Here is the full code listing:
78146

79-
import Tabs from '@theme/Tabs';
80-
import TabItem from '@theme/TabItem';
81-
82147
<Tabs defaultValue="classic" groupId='script-code'>
83148
<TabItem value="esm" label="ESM">
84149

0 commit comments

Comments
 (0)