Unityで銃を撃った後に弾痕を当たった位置に残す機能を作る

今回は銃を撃った後に弾痕を当たった位置に残したいと思います。

リアルな世界であれば物に銃弾が当たった場合に弾の当たった跡が残ります。
そんな事どうやってやるんだ!?
と思いますが、何の事はない弾痕をゲームオブジェクトとして作成しておき、それをインスタンス化して、当たった位置に表示するだけです。

まずは弾痕をゲームオブジェクトとして用意したいので、それ用の弾痕の画像を探したんですが、無料で配布されているものが見つからなかったので、自分で作成しました。(^_^;)
ご自分で作成される場合はWindowsならペイントで絵を作り、GIMPで透過するといいです。

弾痕1

用意するのが面倒な方は上の画像をご自由にお使いください。(右クリックから名前をつけて保存)

スポンサーリンク

弾痕をプレハブにする

UnityのAssetsメニューからImport New Assetを選択し、弾痕画像をインポートしてください。
ヒエラルキー上で右クリックから3D Object→Planeを選択します。
Planeが出来たらPlaneにインポートした弾痕の画像をドラッグ&ドロップします。

ホール2

PlaneのインスペクタでbulletholeのShaderをLegacy ShadersのTransparent、Bumped Diffuseに変更します。

これで透過処理した画像が反映されます。
Shaderは全然詳しくないので、解説は出来ません・・・・。

ある程度Planeのサイズを小さくした後で、
銃のゲームオブジェクトの近くへ持っていき、およその弾のサイズと一致するようにサイズを調整します。

ホール1

Shaderを変更する前にこちらの画像を保存してしまったので、背景が表示されてしまっていますが・・・、こんな感じでサイズを調整します。
X、Y、Zのサイズをそれぞれ0.005にしました。

これで弾痕のゲームオブジェクトが出来上がりましたので、Assetsエリアにドラッグ&ドロップしてプレハブにしておきます。
プレハブにしたらシーン上の弾痕オブジェクトを削除します。

弾痕を残す為の処理を追加する

次に銃を撃った時に当たった位置に弾痕のゲームオブジェクトを配置する処理を記述します。
今までの記事をご覧いただいた方は、銃を撃った時の処理Shotスクリプトを修正していきます。
それ以外の方はご自分の銃を撃った時の処理のところに追加してください。

Shotスクリプト内で銃が何かに当たったかどうかを判定しているのはJudgeShot関数です。
そこの中に処理を追加します。

弾痕を入れておく一時的な変数bulletHoleObjを用意しておきます。

穴を開けたいゲームオブジェクトとレイがヒットした時は、InstantiateでbulletHoleを作成します。
配置する位置は当たった位置hitPoint.pointから主人公キャラの向いている方向 * 0.001を引いた位置に設定します。
hitPoint.pointと位置をまったく同じにすると画像が点滅してしまうので、ほんの少しだけ主人公側に移動させます。
角度は

Quaternion.FromToRotation(Vector3.up, hitPoint.normal);

で上方向Vector3.upとヒットした面の角度hitPoint.nomalの間の角度を算出します。
Quaternion.FromToRotationは二つの方向から角度を算出してくれます。

当たったレイヤーが敵だった場合は細かい位置の調整はやめておきました。
敵にうまく弾痕を残すのは難しいです。

なぜならコライダのヒットした位置と角度で弾痕の位置を指定しているので、
敵の見た目のメッシュと当たり判定で使用しているコライダとが完全には一致しないからです。

大雑把な当たり判定をしている時は弾痕を残さない方がいいかもしれません。

キャラクターのMeshCollider(キャラクターのMeshでコライダが作成される)を作ってやってみようかと思ったんですが、コライダの作り方がわかりませんでした。

建物とかは出来るんですが、キャラクターのMeshでコライダを作成してキャラクターのMeshと合わせるやり方がわかりません。
そもそも移動する物にMesh Colliderは使えないのかも?

そんな事情で敵キャラに弾痕を残す場合は当たり判定のコライダを細かく作成しないと、
空中に浮いているようになってしまいます。

Unityの敵キャラの当たり判定を細かくしてよりバイオっぽくする
Unityゲームの敵キャラクターに取りつけるコライダを細かく設定し、当たり判定を細かくします。

の記事で細かく当たり判定する方法を書いていますが、さらに細かくする必要もあるかもしれません。

ホール3

上がブロックに弾を撃ち込んだ時です。
ブロックにはRigidbodyを付け、Is Kinematicにチェックを入れておく必要があります。
Is Kinematicにチェックを入れると、このブロックを手で押せなくなるんですが・・・。

マニュアルには

凸状じゃないメッシュコライダーはリジッドボディがついてないゲームオブジェクトにだけ作用する

という事らしいんですが、今回のブロックはBox Colliderを使用していますが、形状が同じだからMesh Colliderと
同じになってるんですかね。エラーになります。
Mesh Colliderについては詳しく調べてみる必要がありそうです。

ホール4

敵キャラであるゾンビを撃った時の弾痕は上のようになります。
ゾンビの血の色を表現する場合は弾痕の中心を赤っぽくするといいかもしれません。