如何在 react-VR 中将某些元素固定在屏幕上

How do I keep some element fixed on the screen in react-VR

我想在 react-vr 应用程序中始终显示分数或健康栏。

我可以使用 VrHeadModel - 旋转、yawPitchRoll 和位置,但必须计算它才能保持固定...好像我遗漏了什么。

我该怎么做?

已更新要点,订阅 HM 后延迟更少:

https://gist.github.com/cidicles/b4e978d3f3e2de8b359bdc51b5fb3261


这就是我目前的做法。它有视觉滞后并在循环中设置状态但实现了目标。

为 VrheadModel.rotation() 数组创建一个状态

constructor(props) {
  super(props);
  this.state = {
    hmRot: VrHeadModel.rotation()
  }
}

启动计时器

componentDidMount(){
  this.timer = setInterval(()=>{this.tick()}, 50);
}
componentWillUnmount(){
  clearInterval(this.timer);
}
tick(){
  this.setState({
    hmRot: VrHeadModel.rotation()
  });
}

在 0/0/0 处创建一个视图,并像往常一样在场景中定位固定对象。在主视图上设置旋转以匹配相机的旋转。

  render(){
    let {hmRot} = this.state;
    return (
      <View
        style={{
          position: 'absolute',
          layoutOrigin: [0.5, 0.5],
          transform: [
            {translate: [0, 0, 0]},
            {rotateX: hmRot[0]},
            {rotateY: hmRot[1]},
            {rotateZ: hmRot[2]}
          ]
        }}>
        <Text
          style={{
            position: 'absolute',
            layoutOrigin: [0.5, 0.5],
            backgroundColor: '#f00',
            transform: [
              {translate: [0, 0, -2]},
            ]
          }}>
          Fixed
        </Text>
      </View>
    );
  }

这里有来自 React VR 团队的关于此问题的相关 post: https://github.com/facebook/react-vr/issues/261

答案是使用多个表面:一个不锁头,另一个锁头。

请参阅此处 "Using Multiple Surfaces":Surfaces - React 360

要让您的工作正常,请将示例中缺少的代码分别粘贴到您的 client.js 和 index.js 文件中:

这是一个 link 的工作示例(部分粘贴在下方):Headlocked Surfaces

import { Math as VRMath, ReactInstance, Surface } from "react-360-web";

function init(bundle, parent, options = {}) {
  const horizontalPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);
  const hvPanel = new Surface(300, 300, Surface.SurfaceShape.Flat);

  horizontalPanel.setAngle(0, -0.5);

  const cameraDirection = [0, 0, -1];

  const r360 = new ReactInstance(bundle, parent, {
    fullScreen: true,
    frame: () => {
      const cameraQuat = r360.getCameraQuaternion();
      cameraDirection[0] = 0;
      cameraDirection[1] = 0;
      cameraDirection[2] = -1;
      // cameraDirection will point out from the view of the camera,
      // we can use it to compute surface angles
      VRMath.rotateByQuaternion(cameraDirection, cameraQuat);
      const cx = cameraDirection[0];
      const cy = cameraDirection[1];
      const cz = cameraDirection[2];
      const horizAngle = Math.atan2(cx, -cz);
      const vertAngle = Math.asin(cy / Math.sqrt(cx * cx + cy * cy + cz * cz));
      horizontalPanel.setAngle(horizAngle, -0.5);
      hvPanel.setAngle(horizAngle, vertAngle);
    },
    ...options
  });

  r360.renderToSurface(r360.createRoot("HorizontalPanel"), horizontalPanel);
  r360.renderToSurface(r360.createRoot("HVPanel"), hvPanel);
}

window.React360 = { init };

在你的client.js中:

ReactInstance 构造函数的 frame 属性 中,设置表面角度以匹配相机:水平,或水平和垂直。

在你的index.js中:

记得将 React 组件注册到新的 headlocked surface。