create-playcanvas 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-playcanvas",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Scaffold a PlayCanvas project",
5
5
  "keywords": [
6
6
  "playcanvas",
@@ -1,7 +1,10 @@
1
1
  import type { Entity, RigidBodyComponentSystem } from 'playcanvas';
2
- import { Script } from 'playcanvas';
2
+ import { Script, Vec3 } from 'playcanvas';
3
3
  import { ThirdPersonController } from 'playcanvas/scripts/esm/third-person-controller.mjs';
4
4
 
5
+ /** Ground probes under the player's box collider (half width 0.4): centre, edges and corners */
6
+ const FEET = [-0.38, 0, 0.38].flatMap((x) => [-0.38, 0, 0.38].map((z) => [x, z]));
7
+
5
8
  class RobotAnimation extends Script {
6
9
  static scriptName = 'robotAnimation';
7
10
 
@@ -28,9 +31,10 @@ class RobotAnimation extends Script {
28
31
  }
29
32
 
30
33
  export const addThirdPersonController = (player: Entity, camera: Entity, model: Entity) => {
31
- (player.rigidbody!.system as RigidBodyComponentSystem).gravity.set(0, -18, 0);
34
+ const sys = player.rigidbody!.system as RigidBodyComponentSystem;
35
+ sys.gravity.set(0, -18, 0);
32
36
  if (!player.script) player.addComponent('script');
33
- player.script!.create(ThirdPersonController, {
37
+ const controller = player.script!.create(ThirdPersonController, {
34
38
  properties: {
35
39
  camera,
36
40
  characterModel: model,
@@ -41,6 +45,24 @@ export const addThirdPersonController = (player: Entity, camera: Entity, model:
41
45
  jumpForce: 520,
42
46
  speedGround: 60
43
47
  }
48
+ })!;
49
+
50
+ // The stock ground check is one ray from the centre, so a player standing on a ledge reads as
51
+ // airborne and can't jump. Count it grounded when any probe under the collider finds a solid
52
+ // surface; triggers (colliders without a rigid body) only stop the camera
53
+ const [from, to] = [new Vec3(), new Vec3()];
54
+ const solid = { filterCallback: (e: Entity) => !!e.rigidbody };
55
+ let grounded = false;
56
+ Object.defineProperty(controller, '_grounded', {
57
+ get: () => grounded,
58
+ set: () => {
59
+ const p = player.getPosition();
60
+ grounded = FEET.some(([x, z]) => {
61
+ from.set(p.x + x, p.y, p.z + z);
62
+ to.set(from.x, p.y - 1.1, from.z);
63
+ return !!sys.raycastFirst(from, to, solid);
64
+ });
65
+ }
44
66
  });
45
67
 
46
68
  if (!model.script) model.addComponent('script');
@@ -15,7 +15,7 @@
15
15
  "typecheck": "tsc --noEmit"
16
16
  },
17
17
  "dependencies": {
18
- "playcanvas": "^2.23.0"
18
+ "playcanvas": "^2.23.1"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@playcanvas/eslint-config": "3.0.0-beta.8",
@@ -23,7 +23,7 @@
23
23
  "eslint": "^9.39.5",
24
24
  "prettier": "^3.9.9",
25
25
  "typescript": "~6.0.3",
26
- "vite": "^8.3.2"
26
+ "vite": "^8.3.4"
27
27
  },
28
28
  "engines": {
29
29
  "node": ">=22.23.2"
@@ -134,6 +134,9 @@ for (const [i, [x, z, size]] of TREES.entries()) {
134
134
  crown.setPosition(x, size * y, z);
135
135
  crown.setLocalScale(size * width, size * height, size * width);
136
136
  crown.addComponent('render', { type: 'cone', material: j === 1 ? tips : leaves });
137
+
138
+ // A trigger: it stops the camera's line of sight but the player walks through it
139
+ crown.addComponent('collision', { type: 'cone', radius: (size * width) / 2, height: size * height });
137
140
  app.root.addChild(crown);
138
141
  }
139
142
  }
@@ -142,11 +145,13 @@ prop('stump', [-1.8, 0.4, -2.2], [0.9, 0.8, 0.9], wood);
142
145
 
143
146
  const player = new Entity('player');
144
147
  player.setPosition(0, 1.1, 0);
148
+
149
+ // A box rather than a capsule, so the player stands on ledges instead of sliding off them. Its
150
+ // bottom sits 1 m below the body, inside the controller's 1.1 m ground probes
145
151
  player.addComponent('collision', {
146
- type: 'capsule',
147
- radius: 0.5,
148
- height: 2.4,
149
- linearOffset: new Vec3(0, 0.1, 0)
152
+ type: 'box',
153
+ halfExtents: new Vec3(0.4, 1.2, 0.4),
154
+ linearOffset: new Vec3(0, 0.2, 0)
150
155
  });
151
156
  player.addComponent('rigidbody', { type: 'dynamic', mass: 70, angularFactor: Vec3.ZERO });
152
157
  app.root.addChild(player);
@@ -162,7 +167,7 @@ pants.diffuse = new Color(0.18, 0.29, 0.52);
162
167
  pants.update();
163
168
 
164
169
  const model = new Entity('character');
165
- model.setLocalPosition(0, 0.2, 0);
170
+ model.setLocalPosition(0, 0.3, 0);
166
171
  const part = (
167
172
  parent: Entity,
168
173
  name: string,
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@playcanvas/react": "^0.11.7",
19
- "playcanvas": "^2.23.0",
19
+ "playcanvas": "^2.23.1",
20
20
  "react": "^19.3.0",
21
21
  "react-dom": "^19.3.0"
22
22
  },
@@ -25,11 +25,11 @@
25
25
  "@playcanvas/inspector": "^0.2.0",
26
26
  "@types/react": "^19.3.0",
27
27
  "@types/react-dom": "^19.3.0",
28
- "@vitejs/plugin-react": "^6.1.1",
28
+ "@vitejs/plugin-react": "^6.1.2",
29
29
  "eslint": "^9.39.5",
30
30
  "prettier": "^3.9.9",
31
31
  "typescript": "~6.0.3",
32
- "vite": "^8.3.2"
32
+ "vite": "^8.3.4"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=22.23.2"
@@ -79,6 +79,8 @@ function Pine({
79
79
  scale={[size * width, size * height, size * width]}
80
80
  >
81
81
  <Render type="cone" material={i === 1 ? tips : leaves} />
82
+ {/* A trigger: it stops the camera's line of sight but the player walks through it */}
83
+ <Collision type="cone" radius={(size * width) / 2} height={size * height} />
82
84
  </Entity>
83
85
  ))}
84
86
  </>
@@ -139,9 +141,10 @@ function Scene() {
139
141
  <Block name="fallen-log" position={[0, 0.35, 6]} scale={[3.8, 0.7, 0.7]} material={wood} />
140
142
  <Block name="stump" position={[-1.8, 0.4, -2.2]} scale={[0.9, 0.8, 0.9]} material={wood} />
141
143
  <Entity name="player" ref={player} position={[0, 1.1, 0]}>
142
- <Collision type="capsule" radius={0.5} height={2.4} linearOffset={[0, 0.1, 0]} />
144
+ {/* A box rather than a capsule, so the player stands on ledges instead of sliding off them */}
145
+ <Collision type="box" halfExtents={[0.4, 1.2, 0.4]} linearOffset={[0, 0.2, 0]} />
143
146
  <RigidBody type="dynamic" mass={70} angularFactor={[0, 0, 0]} />
144
- <Entity name="character" ref={model} position={[0, 0.2, 0]}>
147
+ <Entity name="character" ref={model} position={[0, 0.3, 0]}>
145
148
  <Entity name="body" scale={[0.56, 0.88, 0.38]}>
146
149
  <Render type="box" material={shirt} />
147
150
  </Entity>
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@playcanvas/web-components": "^0.28.0",
19
- "playcanvas": "^2.23.0"
19
+ "playcanvas": "^2.23.1"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@playcanvas/eslint-config": "3.0.0-beta.8",
@@ -24,7 +24,7 @@
24
24
  "eslint": "^9.39.5",
25
25
  "prettier": "^3.9.9",
26
26
  "typescript": "~6.0.3",
27
- "vite": "^8.3.2"
27
+ "vite": "^8.3.4"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=22.23.2"
@@ -65,12 +65,15 @@
65
65
  ></pc-entity>
66
66
  <pc-entity name="tree-0-crown-0" position="-7 2.09 -6" scale="2.31 1.98 2.31"
67
67
  ><pc-render type="cone" material="leaves-material"></pc-render
68
+ ><pc-collision type="cone" radius="1.155" height="1.98"></pc-collision
68
69
  ></pc-entity>
69
70
  <pc-entity name="tree-0-crown-1" position="-7 2.915 -6" scale="1.76 1.705 1.76"
70
71
  ><pc-render type="cone" material="tips-material"></pc-render
72
+ ><pc-collision type="cone" radius="0.88" height="1.705"></pc-collision
71
73
  ></pc-entity>
72
74
  <pc-entity name="tree-0-crown-2" position="-7 3.63 -6" scale="1.21 1.54 1.21"
73
75
  ><pc-render type="cone" material="leaves-material"></pc-render
76
+ ><pc-collision type="cone" radius="0.605" height="1.54"></pc-collision
74
77
  ></pc-entity>
75
78
  <pc-entity name="tree-1-trunk" position="6.5 1.125 -6.5" scale="0.475 2.25 0.475"
76
79
  ><pc-render type="box" material="wood-material"></pc-render
@@ -79,12 +82,15 @@
79
82
  ></pc-entity>
80
83
  <pc-entity name="tree-1-crown-0" position="6.5 2.375 -6.5" scale="2.625 2.25 2.625"
81
84
  ><pc-render type="cone" material="leaves-material"></pc-render
85
+ ><pc-collision type="cone" radius="1.3125" height="2.25"></pc-collision
82
86
  ></pc-entity>
83
87
  <pc-entity name="tree-1-crown-1" position="6.5 3.3125 -6.5" scale="2 1.9375 2"
84
88
  ><pc-render type="cone" material="tips-material"></pc-render
89
+ ><pc-collision type="cone" radius="1" height="1.9375"></pc-collision
85
90
  ></pc-entity>
86
91
  <pc-entity name="tree-1-crown-2" position="6.5 4.125 -6.5" scale="1.375 1.75 1.375"
87
92
  ><pc-render type="cone" material="leaves-material"></pc-render
93
+ ><pc-collision type="cone" radius="0.6875" height="1.75"></pc-collision
88
94
  ></pc-entity>
89
95
  <pc-entity name="tree-2-trunk" position="-7.5 0.81 5" scale="0.342 1.62 0.342"
90
96
  ><pc-render type="box" material="wood-material"></pc-render
@@ -93,12 +99,15 @@
93
99
  ></pc-entity>
94
100
  <pc-entity name="tree-2-crown-0" position="-7.5 1.71 5" scale="1.89 1.62 1.89"
95
101
  ><pc-render type="cone" material="leaves-material"></pc-render
102
+ ><pc-collision type="cone" radius="0.945" height="1.62"></pc-collision
96
103
  ></pc-entity>
97
104
  <pc-entity name="tree-2-crown-1" position="-7.5 2.385 5" scale="1.44 1.395 1.44"
98
105
  ><pc-render type="cone" material="tips-material"></pc-render
106
+ ><pc-collision type="cone" radius="0.72" height="1.395"></pc-collision
99
107
  ></pc-entity>
100
108
  <pc-entity name="tree-2-crown-2" position="-7.5 2.97 5" scale="0.99 1.26 0.99"
101
109
  ><pc-render type="cone" material="leaves-material"></pc-render
110
+ ><pc-collision type="cone" radius="0.495" height="1.26"></pc-collision
102
111
  ></pc-entity>
103
112
  <pc-entity name="tree-3-trunk" position="7 1.035 5.5" scale="0.437 2.07 0.437"
104
113
  ><pc-render type="box" material="wood-material"></pc-render
@@ -107,12 +116,15 @@
107
116
  ></pc-entity>
108
117
  <pc-entity name="tree-3-crown-0" position="7 2.185 5.5" scale="2.415 2.07 2.415"
109
118
  ><pc-render type="cone" material="leaves-material"></pc-render
119
+ ><pc-collision type="cone" radius="1.2075" height="2.07"></pc-collision
110
120
  ></pc-entity>
111
121
  <pc-entity name="tree-3-crown-1" position="7 3.0475 5.5" scale="1.84 1.7825 1.84"
112
122
  ><pc-render type="cone" material="tips-material"></pc-render
123
+ ><pc-collision type="cone" radius="0.92" height="1.7825"></pc-collision
113
124
  ></pc-entity>
114
125
  <pc-entity name="tree-3-crown-2" position="7 3.795 5.5" scale="1.265 1.61 1.265"
115
126
  ><pc-render type="cone" material="leaves-material"></pc-render
127
+ ><pc-collision type="cone" radius="0.6325" height="1.61"></pc-collision
116
128
  ></pc-entity>
117
129
  <pc-entity name="tree-4-trunk" position="-2.2 0.765 -8" scale="0.323 1.53 0.323"
118
130
  ><pc-render type="box" material="wood-material"></pc-render
@@ -121,12 +133,15 @@
121
133
  ></pc-entity>
122
134
  <pc-entity name="tree-4-crown-0" position="-2.2 1.615 -8" scale="1.785 1.53 1.785"
123
135
  ><pc-render type="cone" material="leaves-material"></pc-render
136
+ ><pc-collision type="cone" radius="0.8925" height="1.53"></pc-collision
124
137
  ></pc-entity>
125
138
  <pc-entity name="tree-4-crown-1" position="-2.2 2.2525 -8" scale="1.36 1.3175 1.36"
126
139
  ><pc-render type="cone" material="tips-material"></pc-render
140
+ ><pc-collision type="cone" radius="0.68" height="1.3175"></pc-collision
127
141
  ></pc-entity>
128
142
  <pc-entity name="tree-4-crown-2" position="-2.2 2.805 -8" scale="0.935 1.19 0.935"
129
143
  ><pc-render type="cone" material="leaves-material"></pc-render
144
+ ><pc-collision type="cone" radius="0.4675" height="1.19"></pc-collision
130
145
  ></pc-entity>
131
146
  <pc-entity name="fallen-log" position="0 0.35 6" scale="3.8 0.7 0.7"
132
147
  ><pc-render type="box" material="wood-material"></pc-render
@@ -139,9 +154,9 @@
139
154
  ><pc-rigid-body type="static"></pc-rigid-body
140
155
  ></pc-entity>
141
156
  <pc-entity name="player" position="0 1.1 0">
142
- <pc-collision type="capsule" radius="0.5" height="2.4" linear-offset="0 0.1 0"></pc-collision>
157
+ <pc-collision type="box" half-extents="0.4 1.2 0.4" linear-offset="0 0.2 0"></pc-collision>
143
158
  <pc-rigid-body type="dynamic" mass="70" angular-factor="0 0 0"></pc-rigid-body>
144
- <pc-entity name="character" position="0 0.2 0">
159
+ <pc-entity name="character" position="0 0.3 0">
145
160
  <pc-entity name="body" scale="0.56 0.88 0.38"
146
161
  ><pc-render type="box" material="shirt-material"></pc-render
147
162
  ></pc-entity>