斜方投射の式
\begin{align}
v_x&=v_0\,cos\theta\\
v_y&=-gt+v_0\,sin\theta\\
x&=v_0\,t\,cos\theta\\
y&=-\frac{1}{2}gt^2+v_0\,t\,sin\theta+y_0
\end{align}
から、$ \vec{d} $先にある物体に衝突するよう初速$ p $で物体を投げるときの$ \vec{v_0} $を求めることができます。
//-----------------------------------------------------------------------
//! 力pで距離distに物体を投げるときのVec (retがnullの場合は届かない)
//! //http://www.sousakuba.com/Programming/algo_dandoukeisan3.html
//! //http://www.kumamoto-nct.ac.jp/file/knct-kiyou-2013/pdf/no18.pdf
//-----------------------------------------------------------------------
static public Vector3[] CalcTargetVec(float _p, Vector3 _dist){
float _g = Physics.gravity.y;
Vector3[] ret = null;
Vector3 distXZ = new Vector3 (_dist.x, 0f, _dist.z);
float dist_x = distXZ.magnitude;
float dist_y = _dist.y;
float a = (_g * dist_x * dist_x) / ( 2f * _p * _p );
float b = dist_x / a;
float c = ( a - dist_y ) / a;
float ts = (b*b/4f) - c;
if ( ts >= 0.0 ) {
float rt = Mathf.Sqrt( -c + ( b * b ) / 4f);
float[] ang = new float[2]{Mathf.Atan( ( -b / 2f ) - rt ),Mathf.Atan( ( -b / 2f ) + rt )};
ret = new Vector3[2];
for ( int i = 0; i < 2; i++ ){
ret[i] = distXZ.normalized * _p * Mathf.Cos(ang[i]);
ret[i].y = _p * Mathf.Sin(ang[i]);
}
}
return ret;
}
衝突可能な場合(届く場合)、 返値$ \vec{v} $は2通りあります。
$ \vec{v} $[0]が直線的に衝突する場合、$ \vec{v} $[1]は山なりに衝突する場合のベクトルです。
値をAddForceで渡す場合はForceMode.VelocityChangeを指定します。
Vector3 dir = target.position - transform.position;
float power = 30f;
Vector3[] v0 = CalcTargetVec (power, dir);
if (v0 != null) {
obj.GetComponentInParent<Rigidbody> ().AddForce (v0[0], ForceMode.VelocityChange);
}