はこねのはこ

はこねさんの備忘録

一人でもテニスができるようにUnityでVRテニスゲームを作りたいねこ[1]

はじめに

今回もラケットの代わりにフライパンが出てきますが、

心の目で見ればテニスラケットです。

前回の進捗はこちら。

hakonebox.hatenablog.com

steamVRのプラグインを導入して、Unity上でHMDの検出、コントローラの検出を行いました。

しかし、Physic MaterialでBouncinessを調整しただけでは、 コントローラをラケットのように振った場合、うまく飛ばないという結果になりました。

くやしい

のでなんとか前に飛ばしたいです。

今回の目標

コントローラーをテニスラケットのようにスイングし、 当たったボールを前に飛ばす。

作戦

Addforceでボールに瞬間的な加速を与えようと思います。 イメージはこんな感じ。

f:id:hakonebox:20180327013408p:plain

上が前回で下が今回。 認識間違えてたらごめんなさい。

AddForceとは

Rigidbodyに力を加えます。

public void AddForce (Vector3 force, ForceMode mode= ForceMode.Force); 
パラメータ 説明
force ワールド座標における力のベクトル
mode 適用する力のタイプ

力は、アクティブのRigidbodyに対してのみ適用することができ、GameObjectが非アクティブに場合は効果がないようです。

続いてmodeを確認します。

mode 説明
Force(default) 質量を使用して、Rigidbodyへ継続的な力を加えます。
Acceleration その質量を無視して、Rigidbodyへ継続的な加速を追加します。
Impulse その質量を使用し、Rigidbodyに瞬間的な加速を追加します。
VelocityChange 質量を無視して、Rigidbodyに瞬間的な加速を追加します。

ForceModeを指定しないとForceになるようです。

そんなわけでImpulseでボール撃つぞ!!!

スクリプトリファレンスはこちら

docs.unity3d.com

docs.unity3d.com

実装

ラケットのIsTriggerをONにして、ラケットのColliderを当たり判定のみにします。

f:id:hakonebox:20180327014505g:plain

適当に書きます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shot : MonoBehaviour {

    public GameObject Ball;            //ボール
    public float speedZ = 10f;       //スピード
    public float speedY = 3f;

    //ボールに当たった場合
    void OnTriggerEnter(Collider col) {
        if(col.tag == "Ball") {
            Vector3 Force;
            Force= new Vector3(0,speedY,speedZ);
            Ball.GetComponent<Rigidbody>().AddForce(Force,ForceMode.Impulse);
        }
    }
}

ラケットにアタッチしてみましょう。

打てました。

f:id:hakonebox:20180327024137g:plain

フルスイングしても大丈夫でした。 すごく見にくいですが、ボールを飛ばせました。

課題

  1. 当たれば飛ぶってコードなので、実用性ある形に落とす
  2. ラケットのスイングスピードで与える力を変えられるように
  3. ボールが見にくいのでオーラをまとわせるなりなんなりで目立たせる
  4. フルスイングすると部屋が壊滅しかねないくらい危険
  5. 打つ角度を狙えるようにする

さいごに

課題はできましたが、 前に飛ばせたので、今日の分は満足です。