import { Camera, Color, MeshRenderer, PrimitiveMesh, Script, UnlitMaterial, Vector3, } from "oasis-engine"; import { ARBackground } from "../AR/ARBackground"; import ARControl from "../AR/ARControl"; import { ARPlaneMode } from "../AR/AREnum"; export default class GameCtrl extends Script { onStart(): void { const { entity, engine } = this; const cameraEntity = entity.createChild("camera"); const camera = cameraEntity.addComponent(Camera); camera.enableFrustumCulling = false; cameraEntity.transform.setPosition(0, 0, 10); const bg = entity.createChild("cameraBG"); const background = bg.addComponent(ARBackground); /** 初始化 AR */ ARControl.init(camera, background, ARPlaneMode.horizontal, () => { // 小程序切换后台与前台的回调 wx.onAppHide(ARControl.onHide.bind(ARControl)); wx.onAppShow(ARControl.onShow.bind(ARControl)); // 设置最终展现的 view 尺寸 // PS. 其实此处只需保持宽高比例与屏幕比例一致即可,可以适当降低宽高数值来降低显存压力 // example. 1000 * 1000 -> 750 * 750 ARControl.viewWidth = engine.canvas.width; ARControl.viewHeight = engine.canvas.height; // PS. 此处小心微信 AR 有坑 // 1. v1 版本的 AR 必须 hitTest 后才会建立空间定位(此处逻辑 ARControl 已经帮忙处理)。 // 2. 就算是 v2 版本,在 start 后,空间坐标系也不是马上就建立完毕的。 // 3. 所以启动成功且空间定位完毕的回调被我封装为一个异步回调。 ARControl.start(() => { // 此处可以写真正的开始逻辑 // ··· // 在相机前方放一个箱子 const boxEntity = entity.createChild("box"); const boxRenderer = boxEntity.addComponent(MeshRenderer); boxRenderer.mesh = PrimitiveMesh.createCuboid(engine, 1, 1, 1); const boxMaterial = new UnlitMaterial(engine); boxMaterial.baseColor = new Color(200 / 256, 200 / 256, 200 / 256, 1); boxRenderer.setMaterial(boxMaterial); const tempVec3 = new Vector3(); const tempWorld = boxEntity.transform.worldPosition; cameraEntity.transform.worldPosition.cloneTo(tempWorld); // 拿到相机前方的朝向 cameraEntity.transform.getWorldForward(tempVec3); // 往前五步放置这个 box tempWorld.add(tempVec3.scale(5)); boxEntity.transform.worldPosition = tempWorld; }); }); } }