networked-aframe 为新用户分配不同的位置

networked-aframe assign different position to new user

我在使用 networked-aframe 设置的多人 A-Frame 环境中遇到问题。

我希望前三个连接的用户具有不同的生成位置,并且任何其他用户都在第三个位置生成,但我无法让它工作。这是我目前在 Html 中的内容:

 <a-entity id="player" 
networked="template:#avatar-template;showLocalTemplate:true;" 
camera 
positioner=""
wasd-controls 
look-controls>
<a-cursor></a-cursor>  
</a-entity>

这是它的 JS 组件:

AFRAME.registerComponent('positioner', {
init: function() {

        var el = this.el,
            counter = 0;

        if (counter == 0) {
            el.setAttribute('position', {x:-16,  y:6,  z:-10});
            counter++;
        }
        else if(counter == 1) {
            el.setAttribute('position', {x:-10,  y:6,  z:-10});
            counter++;
        }
        else {
            el.setAttribute('position', {x:-5,  y:6,  z:-10});
            counter++;
        }
}
});

我发现我必须像这样同步其他组件:

var avatarSchema = {
template: '#avatar-template',
components: [
'positioner',
'position',
'rotation',
'scale',
{
  selector: '.head',
  component: 'material'
},
{
  selector: '.hairs',
  component: 'show-child'
}


]
};
       NAF.schemas.add(avatarSchema);

这是一个大项目,因此代码较多。如果您需要其他任何东西,例如场景设置或头像设置,请告诉我,我会添加它。

我有一个解决方法,因为我不完全了解该组件的工作原理。
我发现在引用NAF.entities.entities
下有一个玩家列表 我制作了一个附加到场景的组件:

AFRAME.registerComponent('foo',{
  init:function(){
    setTimeout(function(){   
      console.log(Object.keys(NAF.entities.entities));
      console.log(Object.keys(NAF.entities.entities)[0]);
      console.log(Object.keys(NAF.entities.entities).length);
    },5000);
  }
});

第一个日志给了我一组玩家 ID。
第二个给出第一个元素的 id。
最后一个给我玩家的数量。

你可以查看加载的玩家数量,根据哪个玩家加载,你可以设置他的位置属性。

if(NAF.. == 1) this.el.setAttribute('position',firstPos);
if(NAF.. == 2) this.el.setAttribute('position',secondPos);
if(NAF.. > 2) this.el.setAttribute('position',third);


此处的工作故障:故障。com/edit/#!/sudden-antler


当然,与其等待 5 秒,我应该听一个已加载的事件,我会在我不那么忙的时候调查它。
如果有人设法用这个组件正确地做到这一点,请发表评论,因为我试图在连接上做这个位置(太早了,其他玩家实体仍然没有加载),试着等到场景加载,但我得到的最接近的是在固定时间后,当我获得玩家数量时动态创建玩家。

我在下面想出了一个有点 hack 的解决方案,但我现在想出了一个干净的方法来确定何时连接。

let connectionResolve;
let connectionPromise = new Promise((resolve, reject) => {
   connectionResolve = resolve;
})

<a-scene networked-scene="onConnect:connectionResolve">


connectionPromise.then(() => {
  // now you can access NAF.connection.getConnectedClients() safely here
  // do stuff
})

您可以将回调传递给联网场景组件的onConnect。它会在您连接时调用该回调。通过将承诺的解析器传递给它,您就可以安全地调用任何东西,并且知道只有在连接时才会调用它。



旧答案

请注意,您应该使用 NAF.connection.getConnectedClients(),而不是实体,因为实体是用户之间共享的任何东西——它只是对应,因为在一个粗略的例子中,化身的数量(仅共享实体)与数量匹配用户数。

function onConnected(callback) {
   setTimeout(() => {
     if (NAF.connection.isConnected()) {
       callback(NAF.connection.getConnectedClients())
     }
     else onConnected(callback)

   }, 100)
}

(这只是给你一个想法。)

docs 似乎并没有为此提供一个好的事件,但他们确实提到了这些功能,我们可以以一种不太 hacky(如果不是很优雅)的方式使用这些功能。