diff --git a/src/components/InteractiveObjects/InteractiveObject.js b/src/components/InteractiveObjects/InteractiveObject.js
index 23f2df1..994b3d7 100644
--- a/src/components/InteractiveObjects/InteractiveObject.js
+++ b/src/components/InteractiveObjects/InteractiveObject.js
@@ -19,10 +19,11 @@ import { SingleQuestion } from "./SingleQuestion/SingleQuestion";
import { MazeQuizGame } from "./MazeQuizGame/MazeQuizGame";
import { Particles } from "./Particles/Particles";
import { SceneSwitcher } from "./SceneSwitcher/SceneSwitcher";
+import { Teleporter } from "./Teleporter/Teleporter";
import { GameEngine } from "@/lib/GameEngine";
const InteractiveObjectsImports = {
- GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher,
+ GenericObject, CharacterObject, TextObject, ImageObject, GltfObject, VideoPlayer, Particles, SceneSwitcher, Teleporter,
PuzzleGame1, PuzzleGame2, PuzzleGame4, MazeQuizGame, ClassicPuzzle, PairMatchingGame, SingleQuestion
};
@@ -56,6 +57,7 @@ class InteractiveObject extends EventManager{
case 'SingleQuestion':
case 'Particles':
case 'SceneSwitcher':
+ case 'Teleporter':
this.io = await new InteractiveObjectsImports[obj.type](engine, obj);
this.source = this.io.source || this.io;
this.object = this.io.object;
@@ -174,6 +176,7 @@ const InteractiveObjectTypes = [
'VideoPlayer',
'Particles',
'SceneSwitcher',
+ 'Teleporter',
'TextObject',
'ImageObject'
];
diff --git a/src/components/InteractiveObjects/Teleporter/Teleporter.js b/src/components/InteractiveObjects/Teleporter/Teleporter.js
new file mode 100644
index 0000000..e731caf
--- /dev/null
+++ b/src/components/InteractiveObjects/Teleporter/Teleporter.js
@@ -0,0 +1,41 @@
+import { Group, CylinderGeometry, Mesh, MeshStandardMaterial } from 'three';
+import { EventManager } from '@/lib/EventManager';
+//import { TextObject } from '../TextObject/TextObject';
+
+class Teleporter extends EventManager {
+ emits = ['interaction']
+ constructor(engine, data) {
+ super();
+ return new Promise(async (resolve, reject)=>{
+ const container = new Group();
+ const geometry = new CylinderGeometry(0.25, 0.25, 0.1);
+ const material = new MeshStandardMaterial({
+ color: 0x55aaff, roughness: 0.1, metalness: 0.9
+ });
+ const s1 = new Mesh(geometry, material);
+ s1.isIndividual = true;
+ s1.name = 'T1';
+ engine.clickable.add(s1, ()=>{
+ this.dispatchEvent({type:'interaction', value: 'T1'});
+ engine.hero?.teleport(s2.position)
+ });
+ const s2 = s1.clone();
+ s2.isIndividual = true;
+ s2.name = 'T2';
+ engine.clickable.add(s2, ()=>{
+ this.dispatchEvent({type:'interaction', value: 'T2'})
+ engine.hero?.teleport(s1.position)
+ });
+ s1.position.x = -1;
+ s2.position.x = 1;
+ container.add(s1);
+ container.add(s2);
+
+ this.object = engine.meshUtils.centerOrigin(container);
+ this.object.hasIndividualChildren = true;
+ resolve(this);
+ })
+ }
+}
+
+export { Teleporter }
\ No newline at end of file
diff --git a/src/components/InteractiveObjects/Teleporter/Teleporter.vue b/src/components/InteractiveObjects/Teleporter/Teleporter.vue
new file mode 100644
index 0000000..9a49b60
--- /dev/null
+++ b/src/components/InteractiveObjects/Teleporter/Teleporter.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/SceneDesigner/GameObject.vue b/src/components/SceneDesigner/GameObject.vue
index 9828b6c..0c4e490 100644
--- a/src/components/SceneDesigner/GameObject.vue
+++ b/src/components/SceneDesigner/GameObject.vue
@@ -59,13 +59,14 @@ import Particles from '../InteractiveObjects/Particles/Particles.vue';
import GenericObject from '../InteractiveObjects/GenericObject/GenericObject.vue';
import CharacterObject from '../InteractiveObjects/CharacterObject/CharacterObject.vue';
import SceneSwitcher from '../InteractiveObjects/SceneSwitcher/SceneSwitcher.vue';
+import Teleporter from '../InteractiveObjects/Teleporter/Teleporter.vue';
import OffsetLine from './OffsetLine.vue';
import { InteractiveObjectTypes } from '../InteractiveObjects/InteractiveObject';
const components = {
SvgIcon, OffsetLine, GenericObject, CharacterObject, VideoPlayer, TextObject, ImageObject, SceneSwitcher,
- PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion
+ PuzzleGame1, PuzzleGame2, MazeQuizGame, Particles, ClassicPuzzle, PairMatchingGame, SingleQuestion, Teleporter
};
export default {
diff --git a/src/lib/Hero.js b/src/lib/Hero.js
index 4b3baf1..bd32b47 100644
--- a/src/lib/Hero.js
+++ b/src/lib/Hero.js
@@ -119,7 +119,7 @@ class Hero{
this.model.rotation.reorder('YZX');
}
- update(delta){
+ update(delta){
if (this.ready && this.engine.physics.started && !this.disableInput) {
this.updateCharacterControls(delta)
if (this.engine.renderer.xr.isPresenting && !this.fpv){
@@ -340,6 +340,26 @@ class Hero{
//this.currentAction = 'idle'
}
+ async teleport(v3){
+ if (this.model.visible){
+ await this.engine.motionQueue.add({
+ o: this.model,
+ a: { visible: k => Math.round(k * 20) % 2 == 0},
+ t: 1.5, p: true
+ })
+ this.po.rigidBody.setNextKinematicTranslation(v3);
+ this.model.position.copy(v3);
+ await this.engine.motionQueue.add({
+ o: this.model,
+ a: { visible: k => Math.round(k * 20) % 2 == 0},
+ t: 1.5, p: true
+ })
+ }else{
+ this.po.rigidBody.setNextKinematicTranslation(v3);
+ this.model.position.copy(v3);
+ }
+ }
+
}
export { Hero }
\ No newline at end of file
diff --git a/src/plugins/lang.js b/src/plugins/lang.js
index e08e08f..2d9fcf9 100644
--- a/src/plugins/lang.js
+++ b/src/plugins/lang.js
@@ -143,6 +143,7 @@ const lang = {
ImageObject: 'Image',
Particles: 'Particles',
SceneSwitcher: 'Scene Switcher',
+ Teleporter: 'Teleporter',
},
errors:{
unauthorized: 'Unauthorized',
@@ -310,6 +311,7 @@ const lang = {
ImageObject: 'Изображение',
Particles: 'Частици',
SceneSwitcher: 'Превключвател на сцени',
+ Teleporter: 'Телепортатор'
},
errors:{
unauthorized: 'Отказан достъп',