Переключение содержимого по нажатию

В этой статье вы узнаете, как создать сцену с переключением контента одним нажатием кнопки.

Отсканируйте QR-код и посмотрите на получившуюся сцену.

Вам не придется писать свой собственный код для создания этой сцены, все уже сделано заранее.

Подготовка к созданию

Чтобы создать эту сцену, первое, что нужно сделать, это создать новый проект в расширенном редакторе, нажав File → New.

Таким образом, создание сцены начнется с чистого проекта.

Добавление объектов

Добавление групп

Нужно создать две группы, нажав на Add → Group.

Группы появятся в списке объектов справа.

Теперь вы ДОЛЖНЫ переименовать эти группы. Одна из них должна называться Models, а другая Buttons.

Добавление кнопок

Кнопки могут быть любыми 3D-объектами. В данном примере это будут обычные плоскости с текстурой.

Чтобы добавить плоскость, нажмите Add → Plane.

Далее, выбрав плоскость, нужно изменить названия в поле Name на Left и Right.

А также изменить их положение на сцене.

Затем поместите плоскости Left и Right в группу Buttons. Они будут действовать как кнопки.

Также, если вы хотите, чтобы плоскости были текстурированы, выберите плоскость в левой части дерева объектов, а затем, в правой части, перейдите на вкладку MATERIAL.

Нужно установить флажок рядом с полем Map. После, нажать на прямоугольник рядом с полем Map и загрузить файл изображения.

Добавление 3D-моделей

Следующий шаг — добавление 3D-моделей. Это должно быть не менее двух моделей (иначе какой смысл?). В данном примере будет добавлено 3 модели.

Чтобы импортировать, нажмите File → Import.

Далее, выбрав файл, он появится на сцене.

В этом случае мы импортируем еще несколько моделей аналогичным образом.

Затем поместите все добавленные модели в группу Models.

Добавление скрипта

Последним шагом является добавление скрипта. Для этого нажмите по объекту Scene на правой панели.

Для добавления скрипта, нажмите кнопку New на панели скриптов.

Задайте имя вашего скрипта и нажмите Edit, чтобы открыть редактор кода.

Вставьте следующий код в редактор:

let mouse,
	raycaster,
	clock;
const isMae = typeof window.editor === 'object' && typeof window.editor.fromJSON === 'function';
mouse = new THREE.Vector3();
clock = new THREE.Clock();
raycaster = new THREE.Raycaster();

const buttons = scene.getObjectByName('Buttons');
const models = scene.getObjectByName('Models');

let animationSystems = [];

let counter = 0;
function decrease(){
	counter--;
	if (counter < 0) counter = models.children.length - 1;
}
function increase(){
	counter++;
	if (counter > models.children.length - 1) counter = 0;
}

function makeAnimSystem(mesh) {
    const animSystem = {};
    animSystem.mixer = new THREE.AnimationMixer(mesh);
    animSystem.clips = mesh.animations;
    animSystem.mixerUpdate = (delta) => {
    	animSystem.mixer.update(delta);
    };
    animSystem.playAnimationByIndex = (animationIndex, idle = false) => {
        if (animSystem.action) animSystem.action.stop();
        animSystem.clip = animSystem.clips[animationIndex];
        animSystem.action = animSystem.mixer.clipAction(animSystem.clip);
        animSystem.action.clampWhenFinished = true;
        if (animSystem.action) {
	        animSystem.action.loop = idle ? THREE.LoopRepeat : THREE.LoopOnce;
	        animSystem.action.timeScale = 1;
	        animSystem.action.stop();
	        animSystem.action.play();
        }
    };
    return animSystem;
}

function init () {
	console.log('@@ INITIAL COUNTER', counter);
	models.children.forEach(model => {
		const animationSystem = makeAnimSystem(model);
		animationSystem.myName = model.name;
		animationSystems.push(animationSystem);
		model.visible = false;
	});
	models.children[counter].visible = true;
	const a = animationSystems.find((animSystem) => animSystem.myName == models.children[counter].name);
	a.playAnimationByIndex(0);
	console.log('@@ MODELS ANIMATIONS LIST', animationSystems);
}

function update(event) {
	let delta = event.delta;
    	if (isMae) delta /= 1000;
	animationSystems.forEach((a) => a.mixerUpdate(delta));
}

function getIntersects(event, objectsList) {
	const objects = [...objectsList];
	if (!objects.length) return;
	const rect = renderer.domElement.getBoundingClientRect();
	mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
	mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
	raycaster.setFromCamera(mouse, camera);
	const intersects = raycaster.intersectObjects(objects, true);
	return intersects;
}


function pointerup(event) {
	let intersects = getIntersects(event, [buttons]);
	const obj = intersects[0] || undefined;
	if (obj.object.name == "Left") {
		models.children[counter].visible = false;
		decrease();
		models.children[counter].visible = true;
		console.log(`@@ COUNTER ${obj.object.name} CLICKED`, counter);
		const a = animationSystems.find((animSystem) => animSystem.myName == models.children[counter].name);
		a.playAnimationByIndex(0, true);
	}
	if (obj.object.name == "Right") {
		models.children[counter].visible = false;
		increase();
		models.children[counter].visible = true;
		console.log(`@@ COUNTER ${obj.object.name} CLICKED`, counter);
		const a = animationSystems.find((animSystem) => animSystem.myName == models.children[counter].name);
		a.playAnimationByIndex(0, true);
	}
}

Экспорт сцены

Закройте редактор кода и нажмите File -> Publish, чтобы экспортировать вашу сцену.

Вернитесь в стандартный редактор, нажмите на тип объекта JSON MAE на левой панели и загрузите файл, который вы экспортировали из продвинутого редактора.

Вы увидите объект и кнопки на сцене. Теперь вы можете предварительно просмотреть его в редакторе или опробовать на своем устройстве.

Last updated