Ammo.js Three.js - 计算投篮所需的力向量

问题描述

我正在用three.js和ammo.js构建一个篮球游戏。 (启用3d)

篮筐/篮筐和球的位置不断变化 (AR),因此击球必须是动态的和相对的。

我需要计算施加到球上的力矢量,才能成功击球。在游戏中,用户会滑动进行射击,这会影响“完美射击”的力量。

我看过许多用于计算轨迹、弹道学等的代码和方程示例,我一直在将它们从 C# 转换为 JavaScript,因为我在 Unity 论坛上找到了很多脚本。

我需要一个函数来计算初始力向量3 使用球的位置、篮筐的位置、球的质量和重力来应用到球上。初始角度或最大高度(终端速度 y)也必须传递给这个函数,正如我在我见过的所有方程和计算器中所注意到的。

编辑:

所以我将我在 Unity 论坛(下方)上找到的脚本转换为 Javascript/Three.js:

function getBallVeLocity( ballPos,rimPos,angledegrees,gravity ) {
  
  const Vector3 = {
    forward: new THREE.Vector3( 0,1 ),up: new THREE.Vector3( 0,1,0 )
  };
  
  // Get angle in radians,from angledegrees argument
  const angle = THREE.Math.degToRad( angledegrees );
  
  gravity = gravity || 9.81;

  // Positions of this object and the target on the same plane
  const planarRimPos  = new THREE.Vector3( rimPos.x,rimPos.z ),planarBallPos = new THREE.Vector3( ballPos.x,ballPos.z );

  // Planar distance between objects
  const distance = planarRimPos.distanceto( planarBallPos );
  
  // distance along the y axis between objects
  const yOffset = rimPos.y - ballPos.y;
  
  // Calculate veLocity 
  const initialVeLocity = ( 1 / Math.cos( angle ) ) * Math.sqrt( ( 0.5 * gravity * Math.pow( distance,2 ) ) / ( distance * Math.tan( angle ) + yOffset ) ),veLocity = new THREE.Quaternion( 0,initialVeLocity * Math.sin( angle ),initialVeLocity * Math.cos( angle ) );

  // Rotate our veLocity to match the direction between the two objects
  const planarPosDifferenceBetweenObjects = planarRimPos.sub( planarBallPos ),angleBetweenObjects = Vector3.forward.angleto( planarPosDifferenceBetweenObjects ),angleUpRotated = new THREE.Quaternion().setFromAxisAngle( Vector3.up,angleBetweenObjects ),finalVeLocity = angleUpRotated.multiply( veLocity );
  
  return finalVeLocity;
}

我是这样说的:

const veLocity = getBallVeLocity( ball.position,rim.position,45 );
ball.body.applyForce( veLocity.x,veLocity.y,veLocity.z )

它射错了方向而且很弱。我假设我在函数结束时没有正确进行旋转,弱点可能是由于质量没有增加。球的质量是 2,所以我假设我应该将一些 Y 值乘以 2??不知道:(

这是我尝试转换的 C# 脚本:

using UnityEngine;
using System.Collections;
 
public class ProjectileFire : MonoBehavIoUr {
 
    [Serializefield]
    Transform target;
 
    [Serializefield]
    float initialAngle;
 
    void Start () {
        var rigid = GetComponent<Rigidbody>();
 
        Vector3 p = target.position;
 
        float gravity = Physics.gravity.magnitude;
        // Selected angle in radians
        float angle = initialAngle * Mathf.Deg2Rad;
 
        // Positions of this object and the target on the same plane
        Vector3 planarTarget = new Vector3(p.x,p.z);
        Vector3 planarPostion = new Vector3(transform.position.x,transform.position.z);
 
        // Planar distance between objects
        float distance = Vector3.distance(planarTarget,planarPostion);
        // distance along the y axis between objects
        float yOffset = transform.position.y - p.y;
 
        float initialVeLocity = (1 / Mathf.Cos(angle)) * Mathf.Sqrt((0.5f * gravity * Mathf.Pow(distance,2)) / (distance * Mathf.Tan(angle) + yOffset));
 
        Vector3 veLocity = new Vector3(0,initialVeLocity * Mathf.Sin(angle),initialVeLocity * Mathf.Cos(angle));
 
        // Rotate our veLocity to match the direction between the two objects
        float angleBetweenObjects = Vector3.Angle(Vector3.forward,planarTarget - planarPostion);
        Vector3 finalVeLocity = Quaternion.AngleAxis(angleBetweenObjects,Vector3.up) * veLocity;
 
        // Fire!
        rigid.veLocity = finalVeLocity;
 
        // Alternative way:
        // rigid.AddForce(finalVeLocity * rigid.mass,ForceMode.Impulse);
    }
}

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)