unityのThirdPersonで銃を持たせて構えるエイム動作などを実装してみたメモ② 視点変更でエイムカーソルを動かしキャラを追従させる

unity エイム 銃 構える 3Dゲームの作り方
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^-^*)

この記事はunityで銃のエイムを実装してみたメモです。

前回の記事はこちら。

使用したバージョンはunity2020.3.40です。

アーカイブをダウンロード
アーカイブをダウンロード
●PRスペース●

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

やること 画面中央にエイムカーソルを表示して、キャラが常にそこを向くようにする

Starter Assetsだと動くだけなので、エイムとかはないから自分で実装しないといけない。

エイムをする場合は常にエイムカーソルの方向を向いて狙いをつけないといけないので、その部分をやります。

銃のアセットはVRIFとかに入ってたから、射撃はこれをスクリプトでいじればいけそう。

最終的にこんな感じになりました。

上にも下にもスピード早くしても追従している

このやり方で良いのか不明ですが、ChatGPTに聞きながら試行錯誤したら一応動いたのでここに手順を書いておきます。

①エイムカーソルのキャンバスを追加

ゲームオブジェクト ⇒ UI ⇒ キャンバスグループ でキャンバスを追加。

ゲームオブジェクト ⇒ UI ⇒ 画像 で画像も追加します。

unity エイム 銃 構える

画像はキャンバスの子にしておく。

unity エイム 銃 構える

Imageにはデフォルトで白い四角の画像が設定されてます。

unity エイム 銃 構える

デフォルトで画面の真ん中にあるので、ここにエイムカーソルっぽい画像が来ればいけそうです。

Imageにエイムカーソルっぽい画像を選ぶ

Imageの「ソース画像」のところで表示する画像が指定できます。

unity エイム 銃 構える

点線の円っぽいやつ(circle dashed)がいいかな?

unity エイム 銃 構える

多分unityにデフォルトで入ってるやつだと思うけど(違ってたらごめん)、まぁそれっぽいのを選べばOK。

2024/07/21追記:エイムカーソルの画像を無料配布します

久々にいじったら、↑の点線の丸はVRIFアセットに同梱されていたヤツなのでデフォルトでは入ってませんでしたΣ(゚Д゚)

まぁ簡単に作れるしGIMPの機能で10分くらいで作れたのでここに置いておきます。

https://knb-mayumi.com/wp-content/uploads/2023/11/AimCursor20240721-1.zip

簡単に作れたので特にクレジット表記も不要ですし縛りもしません。暴力表現も性的表現も公序良俗に反する利用でも自己責任で勝手に使ってくださいw

クレジット表記したいなら勝手に「グラフィッカー 神部まゆみ」とか書いてこのブログやBOOTHのURLでリンク貼ってくれても構いません。

一応unitypackageも同梱してあります。スプライトの設定くらいしかしてないけど(;^_^A

エイムカーソル 無料 配布 画像

中央の+はテキストレイヤーにしてあるので、気に入らなければxcfファイルをGIMPで開けば編集しやすくしてあります。

エイムカーソル 無料 配布 画像

追記おわり。

サイズを調整する

これで画像が変わった!…けどでかすぎますね(;^_^A

unity エイム 銃 構える

0.5くらいがちょうどいいかな?まぁ画像によると思います。

unity エイムカーソル

②カメラから画面中央にレイを飛ばし、追従用にエイムカーソルにオブジェクトを表示

これをすることでこんな感じでエイムカーソルのところに追従用のオブジェクトが表示され、カメラが常にそこを見ます。

この時点ではプレイヤーは追従しません

空のオブジェクトでもOK。

オブジェクトを表示しなくても、エイムカーソル画像が表示されている位置を常に見れれば一番いいんだけど。

キャンバスImageのTransform位置は、実際に表示されているエイムカーソルの位置と全く別のところにあるので無理そうだった。

上手くやればできるのかもしれないけど、「特定のオブジェクトの方向を常に向く」なら実装しやすいのでこの方式にしました。

やり方は以下から↓

やり方:追従用のオブジェクトを追加しておく

エイムカーソルのところに表示されるオブジェクトを追加する。

空のオブジェクトでもいいんだけど、スフィア(球)でも追加しておきます。

unity エイム 銃 構える

場所はスクリプトで強制的に指定するのでどこでもいいけど、空のオブジェクトにしない場合はサイズを調整したり色をつけておくと良いかも。

名前はAimTargetにしておきます。

unity エイム 銃 構える

0.01にして分かりやすく赤いマテリアルを設定してみた。

Aimターゲットはプレイヤーモデルの子にしておいたほうが上手く向きが合った

子にしないと微妙にキャラの正面から位置がズレたので子にした。

unity エイム 銃 構える

Cinemachineの設定

この記事を書く前にCinemachineだけで良い感じにカメラワーク作れないかと試行錯誤してみたけど、私の知識ではキツそうだったので諦めた(~_~;)

LookAtやAimとか指定すればいけるかと思ったけど、良い感じにカメラが見てくれなかったのでいっそnothingにしてスクリプトで指定する方式にしました。

unity エイム 銃 構える

FollowだけPlayerCameraRoot (1)ってのを指定してあるけど、これはStarterAssetsにデフォルトで設定されている空のオブジェクトで、恐らくCinemachine追従用でプレイヤーの子に設定してあります。

unity エイム 銃 構える

CinemachineのFollowには何かしら指定しないと視点変更すらできなかったのでこれは絶対に必要。

Starter Assetsについては前回書いた記事を参照。

CinemachineBrainのほうは特に何もいじってません。

unity エイム 銃 構える

コード CameraRaycast.cs

カメラから画面中央(エイムカーソルが表示されてるところ)にまっすぐレイを飛ばし、カメラから10m先の位置に指定したオブジェクトを強制的に移動させます。

10mじゃなくて5mだとちょっと距離が足りずに視点変更した時に意図しない動作をしたので、ある程度距離をとったほうが良いです。

using UnityEngine;

public class CameraRaycast : MonoBehaviour
{
    public Camera mainCamera; // メインカメラの参照
    public Transform targetObject; // 空のオブジェクトのTransform
    public Animator animator; // アニメーターコンポーネント

    void Update()
    {
        // Aimがtrueの時のみ処理を実行
        if (animator.GetBool("Aim"))
        {
            // カメラの位置から画面中央に向かってレイを飛ばす
            Ray ray = mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));

            // レイの原点から方向に10m伸ばした座標を計算して空のオブジェクトに代入
            targetObject.position = ray.origin + ray.direction * 10f;
        }
    }
}

これでエイムカーソルのところに指定したオブジェクトが常に表示されるので、そのオブジェクトを常に見る設定にすればエイムできます。

AimTargetオブジェクトにアタッチして、カメラとターゲット、プレイヤーのアニメーターを指定します。

アニメーターを指定するのはアニメーター変数のAimがオンの時にだけ作動させるため。

unity エイム 銃 構える

③エイムカーソルに常にキャラが向くようにする

②までだとキャラがエイムカーソルの方を向かないので、キャラが常にエイムカーソルのほうを向くようにします。

非エイム中の動作がおかしくなるようなら切り替えられるようにするけど、とりあえず不都合なさそうなのでこれでいきます。

コード LookAtObject.cs

これはオブジェクトBが常にオブジェクトAの方向を向くようにするスクリプト。

一応followSpeedで追従の速さも指定できるようにしたけど、あまり変わらないかな?(;^_^A

using UnityEngine;

public class LookAtObject : MonoBehaviour
{
    public Transform objectA; // オブジェクトAをInspectorで指定
    public Transform objectB; // オブジェクトBをInspectorで指定
    public float followSpeed = 5f; // 追従の速さ(大きいほど速く追従)
    public Animator animator; // アニメーターコンポーネント

    private void Update()
    {
        // Aimがtrueの時のみ処理を実行
        if (animator.GetBool("Aim"))
        {
            // ターゲットオブジェクトの向きを緩やかに追従
            Vector3 targetDirection = objectA.position - objectB.position;
            targetDirection.y = 0f; // 高さは考慮しない場合、y軸の回転を無効にする

            // 線形補間を使用して緩やかな追従を行う
            Quaternion targetRotation = Quaternion.LookRotation(targetDirection.normalized);
            objectB.rotation = Quaternion.Slerp(objectB.rotation, targetRotation, Time.deltaTime * followSpeed);
        }
    }
}

プレイヤーモデルにアタッチして、

  • ObjectAに追従したいオブジェクト
  • ObjectBに追従するプレイヤーモデル
  • Follow Speedに追従スピード
  • アニメーターにプレイヤーのアニメーター

を指定すればOK。

unity エイム 銃 構える

これで良い感じになった!

うん、ちゃんと追従してますね!

LookAnimatorアセットも併用したら更に良い感じになった

LookAnimatorアセットは有料だけど、簡単に指定したオブジェクトを常に注視してくれます。

しかし真後ろに来た時に振り返ってくれないので、LookAnimatorを使う場合でも③の工程は必要。

特に上向いたあたりで仰ぎ見る感じになって自然になった気がする。

上にも下にもスピード早くしても追従している

これでエイムカーソルを動かした時の動きがちょっと自然になった気がする。

まぁなくてもいけるけどね(;^_^A

ChatGPTのおかげでできたのでお礼を言っておく(*^-^*)

更に私に尽くしてくれることを期待して、お礼は忘れないで言っておくw

unity エイム 銃 構える

でも人間を相手にするように話したほうが細かく条件を指定できる気がするし、こちらもちゃんと対応したほうが指定を言語化しやすいのか?結果的に良いパフォーマンスになる気がする。

AIだからって邪険に扱ったらダメですね。

なんかChatGPTに感情をこめて応援すると精度が上がる説もあるらしいです。

まぁChatGPTが出してくれる文章も励ましてくれる感じのが多い気がするし、それで少しやる気になることもあるのでお互い様かなw

AIに感謝しつついじっていきます。

おわりに

ChatGPTのおかげで案外簡単にできて良かった。

プログラミング系は英語圏の膨大なデータを学習しているからかなり頼りになりますね。

しかし分からないところはちゃんと自分で調べたり、ある程度知識がないと具体的なプロンプトが指定できないので遠回りになったりするけど…。

次は細かい調整とか銃を撃ったりとかしたいな。

何か簡単なゲームを作ってunity playあたりにアップしてみたいかな。

まぁぼちぼちいじってみます(*^-^*)


追記: エイム時にズームするスクリプトを書きました。


タイトルとURLをコピーしました