diff --git a/examples/3d-gta-with-a-map/README.md b/examples/starting-3d-grand-theft-auto-with-a-map/README.md similarity index 100% rename from examples/3d-gta-with-a-map/README.md rename to examples/starting-3d-grand-theft-auto-with-a-map/README.md diff --git a/examples/3d-gta-with-a-map/assets/A_button.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/A_button.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/A_button.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/A_button.png diff --git a/examples/3d-gta-with-a-map/assets/Barrier.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Barrier.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Barrier.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Barrier.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_A.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_A.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_A.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_A.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_C.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_C.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_C.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_C.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_E.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_E.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_E.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_E.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_G.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_G.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_G.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_G.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_H.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_H.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_H.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_H.glb diff --git a/examples/3d-gta-with-a-map/assets/Building_K.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_K.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Building_K.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Building_K.glb diff --git a/examples/3d-gta-with-a-map/assets/Bush1.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Bush1.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Bush1.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Bush1.glb diff --git a/examples/3d-gta-with-a-map/assets/Cone.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Cone.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Cone.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Cone.glb diff --git a/examples/3d-gta-with-a-map/assets/Flat dark joystick border horizontal.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border horizontal.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Flat dark joystick border horizontal.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border horizontal.png diff --git a/examples/3d-gta-with-a-map/assets/Flat dark joystick border vertical.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border vertical.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Flat dark joystick border vertical.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border vertical.png diff --git a/examples/3d-gta-with-a-map/assets/Flat dark joystick border.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Flat dark joystick border.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick border.png diff --git a/examples/3d-gta-with-a-map/assets/Flat dark joystick thumb.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick thumb.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Flat dark joystick thumb.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Flat dark joystick thumb.png diff --git a/examples/3d-gta-with-a-map/assets/House_A.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/House_A.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/House_A.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/House_A.glb diff --git a/examples/3d-gta-with-a-map/assets/House_D.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/House_D.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/House_D.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/House_D.glb diff --git a/examples/3d-gta-with-a-map/assets/House_N.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/House_N.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/House_N.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/House_N.glb diff --git a/examples/3d-gta-with-a-map/assets/House_T.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/House_T.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/House_T.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/House_T.glb diff --git a/examples/3d-gta-with-a-map/assets/Orange - Sedan Sports.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Orange - Sedan Sports.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Orange - Sedan Sports.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Orange - Sedan Sports.glb diff --git a/examples/3d-gta-with-a-map/assets/PineTree1.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/PineTree1.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/PineTree1.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/PineTree1.glb diff --git a/examples/3d-gta-with-a-map/assets/PineTree2.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/PineTree2.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/PineTree2.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/PineTree2.glb diff --git a/examples/3d-gta-with-a-map/assets/RoadMarking.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/RoadMarking.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/RoadMarking.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/RoadMarking.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Back.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Back.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Back.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Back.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Bottom.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Bottom.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Bottom.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Bottom.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Front.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Front.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Front.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Front.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Left.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Left.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Left.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Left.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Right.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Right.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Right.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Right.png diff --git a/examples/3d-gta-with-a-map/assets/Skybox_Top.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Top.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skybox_Top.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skybox_Top.png diff --git a/examples/3d-gta-with-a-map/assets/Skyscraper_A.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_A.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skyscraper_A.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_A.glb diff --git a/examples/3d-gta-with-a-map/assets/Skyscraper_C.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_C.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skyscraper_C.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_C.glb diff --git a/examples/3d-gta-with-a-map/assets/Skyscraper_E.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_E.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Skyscraper_E.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Skyscraper_E.glb diff --git a/examples/3d-gta-with-a-map/assets/StarterPushable.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterPushable.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/StarterPushable.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterPushable.png diff --git a/examples/3d-gta-with-a-map/assets/StarterToggle_Keyboard.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterToggle_Keyboard.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/StarterToggle_Keyboard.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterToggle_Keyboard.png diff --git a/examples/3d-gta-with-a-map/assets/StarterToggle_Touch.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterToggle_Touch.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/StarterToggle_Touch.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/StarterToggle_Touch.png diff --git a/examples/3d-gta-with-a-map/assets/StartingCapsule.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/StartingCapsule.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/StartingCapsule.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/StartingCapsule.glb diff --git a/examples/3d-gta-with-a-map/assets/StreetLight.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/StreetLight.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/StreetLight.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/StreetLight.glb diff --git a/examples/3d-gta-with-a-map/assets/TerrainAsphalt.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainAsphalt.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainAsphalt.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainAsphalt.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainAsphaltNormal.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainAsphaltNormal.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainAsphaltNormal.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainAsphaltNormal.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainConcrete.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainConcrete.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainConcrete.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainConcrete.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainConcreteNormal.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainConcreteNormal.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainConcreteNormal.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainConcreteNormal.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainGrass.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainGrass.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainGrass.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainGrass.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainGrassNormal.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainGrassNormal.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainGrassNormal.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainGrassNormal.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainRock.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainRock.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainRock.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainRock.jpg diff --git a/examples/3d-gta-with-a-map/assets/TerrainRockNormal.jpg b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainRockNormal.jpg similarity index 100% rename from examples/3d-gta-with-a-map/assets/TerrainRockNormal.jpg rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TerrainRockNormal.jpg diff --git a/examples/3d-gta-with-a-map/assets/Top arrow button.png b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Top arrow button.png similarity index 100% rename from examples/3d-gta-with-a-map/assets/Top arrow button.png rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Top arrow button.png diff --git a/examples/3d-gta-with-a-map/assets/TownTree.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/TownTree.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/TownTree.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/TownTree.glb diff --git a/examples/3d-gta-with-a-map/assets/Tunnel.glb b/examples/starting-3d-grand-theft-auto-with-a-map/assets/Tunnel.glb similarity index 100% rename from examples/3d-gta-with-a-map/assets/Tunnel.glb rename to examples/starting-3d-grand-theft-auto-with-a-map/assets/Tunnel.glb diff --git a/examples/3d-gta-with-a-map/preview.png b/examples/starting-3d-grand-theft-auto-with-a-map/preview.png similarity index 100% rename from examples/3d-gta-with-a-map/preview.png rename to examples/starting-3d-grand-theft-auto-with-a-map/preview.png diff --git a/examples/3d-gta-with-a-map/3d-gta-with-a-map.json b/examples/starting-3d-grand-theft-auto-with-a-map/starting-3d-grand-theft-auto-with-a-map.json similarity index 98% rename from examples/3d-gta-with-a-map/3d-gta-with-a-map.json rename to examples/starting-3d-grand-theft-auto-with-a-map/starting-3d-grand-theft-auto-with-a-map.json index 1227a64cf..aa4c25c76 100644 --- a/examples/3d-gta-with-a-map/3d-gta-with-a-map.json +++ b/examples/starting-3d-grand-theft-auto-with-a-map/starting-3d-grand-theft-auto-with-a-map.json @@ -7515,16 +7515,16 @@ { "author": "", "category": "Camera", - "dimension": "", + "dimension": "3D", "extensionNamespace": "", "fullName": "Third person camera", - "gdevelopVersion": ">=5.5.222", + "gdevelopVersion": ">=5.5.269", "helpPath": "", "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iSWNvbnMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMzIgMzIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDMyIDMyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9DQo8L3N0eWxlPg0KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSI3LDEwIDEsMTMgNywxNiAxMywxMyAiLz4NCjxwb2x5bGluZSBjbGFzcz0ic3QwIiBwb2ludHM9IjEsMTMgMSwyMCA3LDIzIDEzLDIwIDEzLDEzICIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjciIHkxPSIxNiIgeDI9IjciIHkyPSIyMyIvPg0KPGxpbmUgY2xhc3M9InN0MCIgeDE9IjMxIiB5MT0iMTYiIHgyPSIyMSIgeTI9IjgiLz4NCjxsaW5lIGNsYXNzPSJzdDAiIHgxPSIyMSIgeTE9IjI0IiB4Mj0iMzEiIHkyPSIxNiIvPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTIyLjcsMjIuNkMyMCwyMS43LDE4LDE5LjEsMTgsMTZjMC0zLjEsMi01LjcsNC43LTYuNiIvPg0KPHBhdGggY2xhc3M9InN0MCIgZD0iTTE5LjgsMTEuM2MxLjQsMS4xLDIuMiwyLjgsMi4yLDQuN2MwLDEuOS0wLjksMy42LTIuMiw0LjciLz4NCjwvc3ZnPg0K", "name": "ThirdPersonCamera", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/Line Hero Pack/Master/SVG/Virtual Reality/94e95d2c318e1f3dc7151a351024e13c574e1e44669c6696aa107d60230073f6_Virtual Reality_3d_vision_eye_vr.svg", - "shortDescription": "Move the camera to look at an object from a given distance.", - "version": "1.7.1", + "shortDescription": "Third-person camera orbiting an object at configurable distance, elevation, and rotation.", + "version": "1.9.0", "description": [ "Move the camera to look at an object from a given distance with a rotation and an elevation angles.", "", @@ -7549,6 +7549,76 @@ "globalVariables": [], "sceneVariables": [], "eventsFunctions": [ + { + "description": "Define helper classes JavaScript code.", + "fullName": "Define helper classes", + "functionType": "Action", + "name": "DefineHelperClasses", + "private": true, + "sentence": "Define helper classes JavaScript code", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//@ts-ignore", + "if (gdjs.__thirdPersonCameraExtension) {", + " //@ts-ignore", + " return;", + "}", + "", + "/**", + " * It can be built the follow:", + " * ", + " * `objectDefaultRotation.setFromAxisAngle(new THREE.Vector3(0, 0, 1), -Math.PI/2);`", + " * ", + " * `objectDefaultRotation.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI/2));`", + " * ", + " */", + "const objectDefaultRotation = new THREE.Quaternion(0.5, -0.5, -0.5, 0.5);", + "const targetQuaternion = new THREE.Quaternion();", + "const yAxis = new THREE.Vector3(0, 1, 0);", + "const zAxis = new THREE.Vector3(0, 0, 1);", + "const quaternion = new THREE.Quaternion();", + "const objectRotation = new THREE.Euler();", + "", + "/**", + " * @param object {gdjs.RuntimeObject}", + " * @param ratio {number}", + " * @param elevationAngleOffset {number}", + " */", + "function slerpCamera(object, ratio, rotationAngleOffset, elevationAngleOffset) {", + " const layer = object.getInstanceContainer().getLayer(object.getLayer());", + " const threeCamera = layer.getRenderer().getThreeCamera();", + " const threeObject = object.get3DRendererObject();", + "", + " objectRotation.copy(threeObject.rotation);", + " objectRotation.z = -objectRotation.z;", + " objectRotation.x = -objectRotation.x;", + " targetQuaternion.setFromEuler(objectRotation);", + " targetQuaternion.multiply(quaternion.setFromAxisAngle(zAxis, -gdjs.toRad(rotationAngleOffset)));", + " targetQuaternion.multiply(quaternion.setFromAxisAngle(yAxis, gdjs.toRad(elevationAngleOffset)));", + " targetQuaternion.multiply(objectDefaultRotation);", + "", + " threeCamera.quaternion.slerp(targetQuaternion, ratio);", + "", + " // The layer angle takes over the 3D camera Z rotation.", + " layer.setCameraRotation(gdjs.toDegrees(-threeCamera.rotation.z));", + "}", + "", + "//@ts-ignore", + "gdjs.__thirdPersonCameraExtension = {", + " slerpCamera,", + "};", + "" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, { "description": "Move the camera to look at a position from a distance.", "fullName": "Look at a position from a distance (deprecated)", @@ -8060,6 +8130,9 @@ "eventsFunctionsFolderStructure": { "folderName": "__ROOT", "children": [ + { + "functionName": "DefineHelperClasses" + }, { "functionName": "LookFromDistanceAtPosition" }, @@ -8102,6 +8175,21 @@ "name": "onCreated", "sentence": "", "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ThirdPersonCamera::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, { "type": "BuiltinCommonInstructions::Comment", "color": { @@ -8361,18 +8449,136 @@ "comment": "At each frame, the camera must catchup the target by a given ratio (speed)\ncameraX(t) - targetX = (cameraX(t - 1) - targetX) * (1 - speed)\n\nThe frame rate must not impact on the catch-up speed, we don't want a speed in ratio per frame but a speed ratio per second, like this:\ncameraX(t) - targetX = (cameraX(t - 1s) - targetX) * (1 - speed)\n\nOk, but we still need to process each frame, we can use a exponent for this:\ncameraX(t) - targetX = (cameraX(t - timeDelta) - targetX) * (1 - speed)^timeDelta\ncameraX(t) = targetX + (cameraX(t - timeDelta) - targetX) * exp(timeDelta * ln((1 - speed)))\n\npow is probably more efficient than precalculated log if the speed is changed continuously but this might be rare enough." }, { - "colorB": 228, - "colorG": 176, - "colorR": 74, - "creationTime": 0, - "name": "Z translation", - "source": "", - "type": "BuiltinCommonInstructions::Group", + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "StringVariable" + }, + "parameters": [ + "RotationMode", + "=", + "\"ZYX\"" + ] + }, + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsRotatingWithObject", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "ThirdPersonCamera::ThirdPersonCamera::Slerp" + }, + "parameters": [ + "Object", + "Behavior", + "1 - exp(TimeDelta() * RotationLogSpeed)", + "RotationAngleOffset", + "ElevationAngleOffset", + "" + ] + }, + { + "type": { + "value": "ThirdPersonCamera::ThirdPersonCamera::MoveToObject" + }, + "parameters": [ + "Object", + "Behavior", + "OffsetY", + "OffsetX", + "OffsetZ", + "" + ] + }, + { + "type": { + "value": "SetCameraCenterX" + }, + "parameters": [ + "", + "-", + "Distance * Scene3D::CameraForwardX(Object.Layer())", + "Object.Layer()", + "" + ] + }, + { + "type": { + "value": "SetCameraCenterY" + }, + "parameters": [ + "", + "-", + "Distance * Scene3D::CameraForwardY(Object.Layer())", + "Object.Layer()", + "" + ] + }, + { + "type": { + "value": "Scene3D::SetCameraZ" + }, + "parameters": [ + "", + "-", + "Distance * Scene3D::CameraForwardZ(Object.Layer())", + "Object.Layer()", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "StringVariable" + }, + "parameters": [ + "RotationMode", + "!=", + "\"ZYX\"" + ] + }, + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsRotatingWithObject", + "False", + "" + ] + } + ] + } + ], + "actions": [], "events": [ { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [], + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Z translation", + "source": "", + "type": "BuiltinCommonInstructions::Group", "events": [ { "type": "BuiltinCommonInstructions::Standard", @@ -8428,131 +8634,268 @@ } ] } - ] - } - ], - "parameters": [] - }, - { - "colorB": 228, - "colorG": 176, - "colorR": 74, - "creationTime": 0, - "name": "Z rotation", - "source": "", - "type": "BuiltinCommonInstructions::Group", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsRotatingWithObject", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "TargetedRotationAngle", - "=", - "Object.Angle()" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsElevatingWithObject", - "True", - "" - ] - } ], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "TargetedElevationAngle", - "=", - "Object.Object3D::RotationY()" - ] - } - ] + "parameters": [] }, { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Z rotation", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "CameraRotationAngle", - "=", - "TargetedRotationAngle + 90 + RotationAngleOffset + AngleDifference(CameraAngle(Object.Layer()), TargetedRotationAngle + 90 + RotationAngleOffset) * exp(TimeDelta() * RotationLogSpeed)" + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsRotatingWithObject", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "TargetedRotationAngle", + "=", + "Object.Angle()" + ] + } ] }, { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "CameraElevationAngle", - "=", - "TargetedElevationAngle + ElevationAngleOffset + AngleDifference(90 - Scene3D::CameraRotationX(Object.Layer()), TargetedElevationAngle + ElevationAngleOffset) * exp(TimeDelta() * ElevationLogSpeed)" + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::Or" + }, + "parameters": [], + "subInstructions": [ + { + "type": { + "value": "StringVariable" + }, + "parameters": [ + "RotationMode", + "!=", + "\"Z\"" + ] + }, + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsElevatingWithObject", + "True", + "" + ] + } + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "TargetedElevationAngle", + "=", + "Object.Object3D::RotationY()" + ] + } ] }, { - "type": { - "value": "ThirdPersonCamera::LookFromDistanceAtPosition3D" - }, - "parameters": [ - "", - "Object.CenterX() + ThirdPersonCamera::RotatedX(CameraRotationAngle, OffsetX, -OffsetY)", - "Object.CenterY() + ThirdPersonCamera::RotatedY(CameraRotationAngle, OffsetX, -OffsetY)", - "CameraZ + OffsetZ", - "Distance", - "CameraRotationAngle", - "CameraElevationAngle", - "", - "" + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "CameraRotationAngle", + "=", + "TargetedRotationAngle + 90 + RotationAngleOffset + AngleDifference(CameraAngle(Object.Layer()), TargetedRotationAngle + 90 + RotationAngleOffset) * exp(TimeDelta() * RotationLogSpeed)" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "CameraElevationAngle", + "=", + "TargetedElevationAngle + ElevationAngleOffset + AngleDifference(90 - Scene3D::CameraRotationX(Object.Layer()), TargetedElevationAngle + ElevationAngleOffset) * exp(TimeDelta() * ElevationLogSpeed)" + ] + }, + { + "type": { + "value": "ThirdPersonCamera::LookFromDistanceAtPosition3D" + }, + "parameters": [ + "", + "Object.CenterX() + ThirdPersonCamera::RotatedX(CameraRotationAngle, OffsetX, -OffsetY)", + "Object.CenterY() + ThirdPersonCamera::RotatedY(CameraRotationAngle, OffsetX, -OffsetY)", + "CameraZ + OffsetZ", + "Distance", + "CameraRotationAngle", + "CameraElevationAngle", + "Object.Layer()", + "" + ] + } + ], + "variables": [ + { + "folded": true, + "name": "CameraRotationAngle", + "type": "number", + "value": 0 + }, + { + "name": "CameraElevationAngle", + "type": "number", + "value": 0 + } ] } ], - "variables": [ - { - "folded": true, - "name": "CameraRotationAngle", - "type": "number", - "value": 0 - }, - { - "name": "CameraElevationAngle", - "type": "number", - "value": 0 - } - ] + "parameters": [] } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ThirdPersonCamera::ThirdPersonCamera", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "fullName": "Lerp camera", + "functionType": "Action", + "name": "Slerp", + "private": true, + "sentence": "Lerp the camera rotation to _PARAM0_ with a ratio of _PARAM2_ with rotation offset _PARAM3_° and elevation offset _PARAM4_°", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.RuntimeObject3D} */", + "const object = objects[0];", + "const ratio = eventsFunctionContext.getArgument(\"Ratio\");", + "const rotationAngleOffset = eventsFunctionContext.getArgument(\"NewRotationAngleOffset\");", + "const elevationAngleOffset = eventsFunctionContext.getArgument(\"NewElevationAngleOffset\");", + "", + "gdjs.__thirdPersonCameraExtension.slerpCamera(object, ratio, rotationAngleOffset, elevationAngleOffset);", + "" ], - "parameters": [] + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "type": "object" + }, + { + "description": "Behavior", + "name": "Behavior", + "supplementaryInformation": "ThirdPersonCamera::ThirdPersonCamera", + "type": "behavior" + }, + { + "description": "Ratio", + "name": "Ratio", + "type": "expression" + }, + { + "description": "Rotation angle offset", + "name": "NewRotationAngleOffset", + "type": "expression" + }, + { + "description": "Elevation angle offset", + "name": "NewElevationAngleOffset", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "fullName": "Move to object", + "functionType": "Action", + "name": "MoveToObject", + "private": true, + "sentence": "Change the camera position to _PARAM0_ with offset _PARAM2_, _PARAM3_, _PARAM4_ ", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetCameraCenterX" + }, + "parameters": [ + "", + "=", + "Object.CenterX() + LocalOffsetX * Object.Object3D::ForwardX() + LocalOffsetY * Object.Object3D::RightX() + LocalOffsetZ * Object.Object3D::UpX()", + "Object.Layer()", + "" + ] + }, + { + "type": { + "value": "SetCameraCenterY" + }, + "parameters": [ + "", + "=", + "Object.CenterY() + LocalOffsetX * Object.Object3D::ForwardY() + LocalOffsetY * Object.Object3D::RightY() + LocalOffsetZ * Object.Object3D::UpY()", + "Object.Layer()", + "" + ] + }, + { + "type": { + "value": "Scene3D::SetCameraZ" + }, + "parameters": [ + "", + "=", + "Object.Object3D::CenterZ() + LocalOffsetX * Object.Object3D::ForwardZ() + LocalOffsetY * Object.Object3D::RightZ() + LocalOffsetZ * Object.Object3D::UpZ()", + "Object.Layer()", + "" + ] + } + ] } ], "parameters": [ @@ -8566,6 +8909,21 @@ "name": "Behavior", "supplementaryInformation": "ThirdPersonCamera::ThirdPersonCamera", "type": "behavior" + }, + { + "description": "X offset", + "name": "LocalOffsetX", + "type": "expression" + }, + { + "description": "Y offset", + "name": "LocalOffsetY", + "type": "expression" + }, + { + "description": "Z offset", + "name": "LocalOffsetZ", + "type": "expression" } ], "objectGroups": [] @@ -9922,6 +10280,12 @@ { "functionName": "DoMoveCameraCloser" }, + { + "functionName": "Slerp" + }, + { + "functionName": "MoveToObject" + }, { "functionName": "JumpToTargetedRotation" }, @@ -10036,7 +10400,7 @@ "value": "0.125", "type": "Number", "unit": "Second", - "label": "Halfway time for rotation", + "label": "Halfway time for rotation", "group": "Catch-up speed", "quickCustomizationVisibility": "hidden", "name": "RotationHalfwayDuration" @@ -10045,7 +10409,8 @@ "value": "0", "type": "Number", "unit": "Second", - "label": "Halfway time for elevation rotation", + "label": "Halfway time for elevation rotation", + "description": "Only used by Z and ZY rotation modes", "group": "Catch-up speed", "quickCustomizationVisibility": "hidden", "name": "ElevationHalfwayDuration" @@ -10055,6 +10420,7 @@ "type": "Number", "unit": "Second", "label": "Halfway time on Z axis", + "description": "Only used by Z and ZY rotation modes", "group": "Catch-up speed", "quickCustomizationVisibility": "hidden", "name": "TranslationZHalfwayDuration" @@ -10097,6 +10463,7 @@ "unit": "DegreeAngle", "label": "Rotation angle offset", "group": "Position", + "advanced": true, "name": "RotationAngleOffset" }, { @@ -10181,15 +10548,36 @@ "value": "false", "type": "Boolean", "label": "Automatically rotate the camera with the object (elevation)", + "description": "Best left unchecked, use the rotation mode instead", + "deprecated": true, "quickCustomizationVisibility": "hidden", "name": "IsElevatingWithObject" }, + { + "value": "Z", + "type": "Choice", + "label": "Rotation mode", + "choices": [ + { + "label": "Horizontal rotation (good for characters)", + "value": "Z" + }, + { + "label": "Vertical and horizontal rotations (good for cars)", + "value": "ZY" + }, + { + "label": "All rotations (good for spaceships)", + "value": "ZYX" + } + ], + "name": "RotationMode" + }, { "value": "0", "type": "Number", "unit": "DegreeAngle", "label": "Targeted camera rotation angle", - "description": "When this angle is set, the camera follow this value instead of the object angle.", "hidden": true, "name": "TargetedRotationAngle" }, @@ -10198,9 +10586,32 @@ "type": "Number", "unit": "DegreeAngle", "label": "Targeted camera rotation angle", - "description": "When this angle is set, the camera follow this value instead of the object angle.", "hidden": true, "name": "TargetedElevationAngle" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Forward X", + "hidden": true, + "name": "ForwardX" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Forward Y", + "hidden": true, + "name": "ForwardY" + }, + { + "value": "0", + "type": "Number", + "unit": "Pixel", + "label": "Forward Z", + "hidden": true, + "name": "ForwardZ" } ], "propertiesFolderStructure": { @@ -10276,11 +10687,23 @@ { "propertyName": "IsElevatingWithObject" }, + { + "propertyName": "RotationMode" + }, { "propertyName": "TargetedRotationAngle" }, { "propertyName": "TargetedElevationAngle" + }, + { + "propertyName": "ForwardX" + }, + { + "propertyName": "ForwardY" + }, + { + "propertyName": "ForwardZ" } ] } @@ -35560,7 +35983,9 @@ " this._cameraPosition = new THREE.Vector3();", " this._chunkPosition = new THREE.Vector3();", " /**", - " * Trunks, for the 3D physics behavior and navigation meshes.", + " * Trunks, for the 3D physics behavior and navigation meshes. Always given,", + " * empty without trunk collisions: otherwise these behaviors would use the", + " * object box, covering the whole area.", " * @type {gdjs.Surface}", " */", " this.surface = {", @@ -35569,8 +35994,12 @@ " getTriangles: () => this._getTrunkTriangles(),", " getHeightField: () => null,", " };", + " /** The trunk collision properties, changing the surface. */", + " this.trunkKey = '';", " this.loadMaskFromProperties();", " this.updateFromProperties();", + " // Before the behaviors create their shapes.", + " this._updateSurface();", " }", "", " _getMaskSource() {", @@ -35919,8 +36348,12 @@ " _updateSurface() {", " const { object } = this;", " if (typeof object.setSurface !== 'function') return;", - " const surface = object._getTrunkCollisions() ? this.surface : null;", - " if (object.getSurface() !== surface) object.setSurface(surface);", + " const trunkKey = object._getTrunkCollisions() + '|' + object._getTrunkDiameter();", + " if (trunkKey !== this.trunkKey) {", + " this.trunkKey = trunkKey;", + " this.version++;", + " }", + " if (object.getSurface() !== this.surface) object.setSurface(this.surface);", " }", "", " /** @returns {Copy[]} */", @@ -36014,7 +36447,7 @@ " */", " _getTrunkTriangles() {", " const { object } = this;", - " const copies = this.getCopies();", + " const copies = object._getTrunkCollisions() ? this.getCopies() : [];", " const verticesPerCopy = TRUNK_SIDES * 2 + 1;", " const positions = new Float32Array(copies.length * verticesPerCopy * 3);", " const indices = new Uint32Array(copies.length * TRUNK_SIDES * 3 * 3);", @@ -36051,8 +36484,8 @@ " }", " });", " if (copies.length === 0) {", - " // Without triangles, the physics engine would use the object box:", - " // a tiny triangle under the object is used instead.", + " // Without triangles, the physics engine and navigation meshes would use", + " // the object box: a tiny triangle under the object is used instead.", " return { positions: new Float32Array([0, 0, -1, 0.0001, 0, -1, 0, 0.0001, -1]), indices: new Uint32Array([0, 2, 1]) };", " }", " return { positions, indices };", @@ -39032,7 +39465,7 @@ "value": "false", "type": "Boolean", "label": "Trunk collisions", - "description": "Give each copy a static collision shape around its trunk, for the 3D physics behavior (add it to this object, with the \"Static\" type) and navigation meshes.", + "description": "Give each copy a static collision shape around its trunk, for the 3D physics behavior (add it to this object, with the \"Static\" type) and navigation meshes. Without them, these behaviors have no effect on this object.", "group": "Collisions", "name": "TrunkCollisions" }, diff --git a/examples/starting-3d-grand-theft-auto-with-a-map/theme-slots.json b/examples/starting-3d-grand-theft-auto-with-a-map/theme-slots.json new file mode 100644 index 000000000..88da07b7f --- /dev/null +++ b/examples/starting-3d-grand-theft-auto-with-a-map/theme-slots.json @@ -0,0 +1,68 @@ +{ + "version": 1, + "objects": { + "scene:Game Scene/Player": "character.player", + "scene:Game Scene/Car": "vehicle.car", + "scene:Game Scene/Driven_Car": "vehicle.car", + "scene:Game Scene/PushableBox": "env.crate", + "scene:Game Scene/Building_A": "building.tower", + "scene:Game Scene/Building_C": "building.tower", + "scene:Game Scene/Building_E": "building.tower", + "scene:Game Scene/Building_G": "building.tower", + "scene:Game Scene/Building_H": "building.tower", + "scene:Game Scene/Building_K": "building.tower", + "scene:Game Scene/Skyscraper_A": "building.tower", + "scene:Game Scene/Skyscraper_C": "building.tower", + "scene:Game Scene/Skyscraper_E": "building.tower", + "scene:Game Scene/House_A": "building.tower", + "scene:Game Scene/House_D": "building.tower", + "scene:Game Scene/House_N": "building.tower", + "scene:Game Scene/House_T": "building.tower", + "scene:Game Scene/Cone": "prop.obstacle", + "scene:Game Scene/Barrier": "prop.obstacle", + "scene:Game Scene/TownTree": "nature.tree", + "scene:Game Scene/PineForest": { + "Model": "nature.tree" + }, + "scene:Game Scene/PineForest2": { + "Model": "nature.tree" + }, + "scene:Game Scene/Bushes": { + "Model": "nature.grass" + }, + "scene:Game Scene/Terrain": { + "Layer1Texture": { + "slot": "terrain.ground", + "normalMap": "Layer1NormalMap" + }, + "Layer2Texture": { + "slot": "terrain.road", + "normalMap": "Layer2NormalMap" + }, + "Layer3Texture": { + "slot": "terrain.rock", + "normalMap": "Layer3NormalMap" + }, + "Layer4Texture": { + "slot": "terrain.pavement", + "normalMap": "Layer4NormalMap" + } + }, + "scene:Game Scene/Grass": { + "BaseColor": "terrain.grass.base", + "TipColor": "terrain.grass.tip" + } + }, + "effects": { + "effect:Game Scene//SkyBox": "sky.day" + }, + "ignoredObjects": [ + "scene:Game Scene/StreetLight", + "scene:Game Scene/RoadMarking", + "scene:Game Scene/MapLimit", + "scene:Game Scene/Tunnel", + "object:Terrain3D::Terrain3D/AreaPlaceholder", + "object:Terrain3D::TerrainGrass/AreaPlaceholder", + "object:Terrain3D::ScatteredModels/AreaPlaceholder" + ] +}