2017-04-19 81 views
2

我在我的幀內應用程序中使用了一個物理引擎,我希望攝像頭在用戶單擊按鈕時移動。用物理引擎在幀中移動攝像頭

我想保留物理引擎屬性,所以我使用applyImpulse作爲運動方法。

這裏是我的示例場景:

<script src="https://aframe.io/releases/0.3.0/aframe.min.js"></script> 
<script src="//cdn.rawgit.com/donmccurdy/aframe-extras/v2.3.0/dist/aframe-extras.min.js"></script> 
<a-scene physics> 
<!-- Camera --> 
<a-entity id="cameraWrapper" geometry="box" dynamic-body="mass:1" position="0 1 0" width="2" height="1" depth="2" listener> 
<a-entity id="camera" camera universal-controls position="0 1 0" rotation="0 0 0"> 
</a-entity> 
</a-entity> 
<a-grid static-body position="0 0 0"></a-grid> 
</a-scene> 
<div> 
<a id="impulseButton">Move</a> 
</div> 

是應該移動攝像機的JavaScript方法是這樣的:

$(document).ready(function(){ 
    $("#impulseButton").on("click",function(){ 
    applyImpulse(); 
    }); 

function applyImpulse(){ 
    var x = 0; 
    var y = 0; 
    var z = 1; 
    var el = $('#cameraWrapper')[0]; 
    el.body.applyImpulse(
     new CANNON.Vec3(x,y,z), 
     new CANNON.Vec3().copy(el.body.position) 
    ); 
    } 
}); 

然而,運動似乎不是很順暢,而當用戶使用WASD控件,cameraWrapper實體保留在舊位置。我怎樣才能平穩地使用applyImpulse移動相機?

回答

3

universal-controls組件是wasd-controlslook-controls的替代品,可以與aframe-physics-system開箱即用。這很有幫助的關鍵是防止相機通過障礙物,但對於桌面非VR應用程序仍然有用。

用法:

<a-entity camera universal-controls kinematic-body></a-entity> 

kinematic-body分量被添加到檢測在播放器上的碰撞。這是一個more complete example


注:AFRAME-額外的未來版本可能不會有kinematic-body和相機碰撞的支持,所以你可能會在版本3.X.X.被鎖定在不幸的是,這對於更好地支持關鍵虛擬現實案例是必要的,比如擁有用於多人遊戲體驗的物理和在網絡工作者中運行物理以獲得性能。

+0

這仍然不適用於物理引擎 – bear

+0

它確實有效,[現場演示](https://sandbox.donmccurdy.com/walls/)。該演示的源代碼鏈接在答案中。 –

+0

我知道運動人體檢測到碰撞,但我不明白這是如何與applyImpulse或任何其他方法相結合,以相機方式移動相機以檢測碰撞時以編程方式移動相機。對不起,如果這不清楚我的問題。 – bear

1

我認爲這只是一個運動問題,所以js/aframe就是你所需要的。它應該看起來像這樣。這只是一個快速的骯髒,但應該給你的想法。你可以研究玩家運動的東西,並找到很多方法來做到這一點。只需將按鍵功能更改爲按鈕功能即可,並且您應該很好。

所以它會更喜歡這個對所有類型的實體來說的(凸輪,光,播放器......):

this.camMove = function(){ 
     // delta = change in time since last call (seconds) 
      delta = clock.getDelta(); 
      var mDir = 100 * delta; 
      moves = false; 

      var mButtons = ["button1", "button2", "button3"]; 
      for (var i = 0; i < mButtons.length; i++) 
      { 
       if (mButtons >= 0) 
        moves = true; 
      } 

      if (mButtons === button1) 
       cam.translateX(mDir); 
      if (mButtons === button2) 
       cam.translateX(-mDir); 
      if (mButtons === button3) 
       cam.translateY(-mDir); 
       ................ 
       ............ 
       ........ 
} 

時鐘應該在你的AFRAME的功能,但林不知道這件事因爲我用three.js這樣的東西。

+0

translateX和動畫的問題是它們不被物理引擎識別,只有外觀控件。有什麼辦法可以使用applyImpulse來做你的建議嗎? – bear

+1

要使用物理引擎進行這項工作(例如碰撞),您可以用'cameraEl.body.applyImpulse(...,...)'替換'cam.translateX'。參見[docs for CANNON.Body.applyImpulse()](http://schteppe.github.io/cannon.js/docs/classes/Body.html#method_applyImpulse)。 –

+0

@DonMcCurdy這似乎只適用於動態主體的例子。你可以提供一個例子,例如用矢量0,0,1移動運動體相機實體,就像我的問題一樣嗎? – bear