Jump→IdleはHas Exit Timeにチェックを入れ、アニメーションが終わったらIdleにいくようにする。 アニメーションの遷移 kamekumechan@gmail.com, いずれはSIRENやバイオハザードみたいなアクションゲームを作りたいと思っています。, ゲームシナリオが書けないので面白いゲームはなかなか作れません・・・・。(^_^;), 名前の由来はカメが好きだからです。 you can read useful information later efficiently. Unityを使った3Dゲームの作り方(かめくめ) Unityでスクリプトから剣の軌跡を作成し表示する 原因は 今回つくるもの. 以下の動画が参考になります(英語字幕)。 購入して使っているのですが、 ちなみに私の場合はStateMachineBehaviourを利用し、アニメーションの途中でそれぞれ呼ばれるようにしています。, weaponTrailフィールドの参照はあらかじめインスペクター上から設定しておきましょう。, 以下は「攻撃する瞬間にActivate()」「攻撃を終えた後にDeactivate()」を呼び出した例です。, はじめまして。 今回はUnityでスクリプトからメッシュを作成し、剣の軌跡を表示してみたいと思います。, TrailRendererを使えば簡単に剣の軌跡を表示出来そうなんですが、わたくしの場合うまく出来なかった為、スクリプトからメッシュを生成する事にしました。, 剣の軌跡はあらかじめ3DCG等で軌跡のメッシュを手動で作成したりする事でも作成出来るみたいですが、わたくしはスクリプト向きっぽいですね(謎), スクリプトからメッシュを生成するようにすれば、剣を振るアニメーションがどんなものであれ、剣の根元と剣先を設定すれば勝手に軌跡を作成してくれるので、個別のアニメーションに対応して軌跡を作成する必要はありません。, 勝手に軌跡を作成してくれると簡単に言ってますが、機能を作るのは結構大変です・・・・(^_^;), 今回の機能を作成する前にスクリプトからメッシュの生成をする方法について知っておく必要があるので、, 剣の軌跡を表示する為にはメッシュを構成する頂点、UV、三角形を作る方法を考えなくてはいけません。, 剣の軌跡を表示する為には剣の根元と剣の先の位置がいくつかわかればその点を繋いでメッシュの頂点情報に使えそうです。, 剣元と剣先は剣の子要素に空のゲームオブジェクトで作成しておきデータを保存すれば良さそうです。, その為には1フレーム毎(UpdateやLateUpdateでデータを取得)に剣元と剣先の位置をデータとして残しておきます。, 過去の位置データと現在の位置データを頂点にすればそこからUV、三角形を設定出来るのでメッシュの生成が出来ますね。, ↑のように1フレーム前の過去の剣元と剣先の位置と、現在の剣元と剣先の位置の4点がわかれば三角形2つを作って四角形の面が出来、剣の動いた間に軌跡を作る事が出来ますね。, 剣の軌跡用のテクスチャを、作成したメッシュに割り当てる為にはテクスチャの横方向を軌跡のメッシュの数に応じて値を変更しなければいけません。, 過去の1フレームの剣の位置と現在のフレームの剣の位置から三角形を2つ作成するので、縦のVの値は0か1の値で、横方向も0か1の値です。, ですが、剣の軌跡を前のデータを元にさらに作成した場合は縦のVの値は0か1で固定ですが、横のUの値は四角形の数によって変わってきます。, ↑のように過去2フレーム前から現フレームまでのデータを使ってメッシュを作成した場合、中間の1フレーム前のUV座標は剣元が(0.5, 0)、剣先が(0.5, 1)にしなければいけません。, 三角形の作成は剣元と剣先の過去フレームのデータから作成する事が出来るので、後は配列に設定する順番だけですね。, 剣の軌跡は手前側を表で統一したい為、過去フレームから時計回りに頂点を指定し三角形のデータを作成していきます。, 剣元の2フレーム前→剣先の2フレーム前→剣元の1フレーム前(ここで三角形1つが出来る)→剣元の1フレーム前→剣先の2フレーム前→剣先の1フレーム前(ここで三角形2つ目)→剣元の1フレーム前→剣先の1フレーム前→・・・・・, キャラクターには武器を持たせ、攻撃ボタンが押されたら攻撃アニメーションが再生されているとします。, 剣の子要素に空のゲームオブジェクトで剣元(StartPosition)と剣先(EndPosition)を作成し設定します。, ↑のように剣の子要素に剣元と剣先を作成します(名前はわかりやすく変えた方がいいですね・・・・)。, StartPositionとEndPositionが設定出来たので、これらの位置をスクリプトから取得し、メッシュを生成してみます。, RequireComponentアトリビュートを使って、このスクリプトをゲームオブジェクトに取り付けた際にMeshFilterとMeshRendererコンポーネントを自動で取り付けます。, 過去フレームの剣元、剣先の位置を保存する時はStartPointsリストとEndPointsリストを使います。, これらのフィールドはインスペクタで確認出来るようにSerializeFieldアトリビュートを取り付けています。, LateUpdateメソッドで剣元と剣先の位置の保存や削除、メッシュの生成を行っています。, 1つの四角形を作るには最低でもStartPointsに2点、EndPointsに2点が保存されている必要がある為、条件を加えています。, また、StartPointsとEndPointsにどんどんデータを保存してもメッシュの数に応じて必要な数は決まって来るので、それ以上になったらデータを削除しています。, メッシュ数を3にすればStartPointsとEndPointsはそれぞれ4点づつが必要になりますね。, その他の頂点リスト、UVリスト、三角形リストをクリアにし、CreateMeshメソッドが呼ばれる度にデータを消して再度データを作成していきます。, 前の剣元の位置→前の剣先の位置→次の剣元の位置→次の剣元の位置→前の剣先の位置→次の剣先の位置, startPoints(剣元)とendPoints(剣先)は一番古いデータが0番目なので、一番古いデータから新しいデータへと頂点を登録していきます。, 今回は頂点を共有しない形で作っているので、三角形はその頂点を順番に繋いでいくだけです。, 剣の軌跡の場合は頂点を共有した方が光の当たり具合がいいような気がするので、後でそちらのスクリプトに切り替えますが、シェーダ―を切り替えるだけでそれほど問題がないような気もします。, RecalculateBoundsはメッシュを覆うBoundsの再計算、RecalculateNormalsはメッシュの法線方向の再計算です。, 頂点、UV、三角形はそれぞれSetVertices、SetUVs、SetTrianglesを使うとリストを配列に変換しなくても引数に設定すればメッシュを生成出来ますが、, SetUVsとSetTrianglesは別の引数も指定する必要がある為、配列化してデータを入れるようにしています。, スクリプトが出来たので、そのスクリプトを取り付ける空のゲームオブジェクトを作成します。, 空のゲームオブジェクトを作成したら名前をSwordTrailとし、Transformの歯車からResetを選び位置をデフォルト値にします。, お絵かきソフト等で256×256ピクセルか512×512ピクセルサイズの画像を作成し、灰色から白色のグラデーションの画像を作成します。, ↑のように右側が剣の色に近い色、左側が色落ちした白色にします(剣の色によって色を変えてください)。, 画像を作成したらUnityのAssetsフォルダで右クリック→Import New Assetを選択し、画像を取り込みます。, 取り込んだ画像を選択し、インスペクタでWrap ModeをClampにして、画像が繰り返されないようにします。, Assetsフォルダで右クリック→Create→Materialを選択し、名前をCreateSwordTrailにします。, 先ほど作成したSwordTrailゲームオブジェクトのマテリアルにCreateSwordTrailを設定します。, SwordTrailはEthan(キャラクター)の子要素ではなく同じレベルの階層に位置しています。, さらにメッシュの表面をカメラの方向にしている為、カメラ側から見ると軌跡が表示されていますが、カメラの反対側から見ると、, 頂点を反時計回りに同じように登録し、三角形を反対側にも作れば裏側からも見えますが面倒くさいので、軌跡の透明化と裏側から見えるようにする処理をシェーダ―を変える事で実現しましょう。, 剣の軌跡を表示する事は出来ましたが、過去フレームの剣元と剣先の位置をそのまま繋いでいる為、軌跡がカクカクしています。, 現在の状態でも十分だとは思うんですが、曲線を作る方法を調べてしまった為、ここからが大変でした・・・(/_;)しくしく, ある点Aからある点Bの間の曲線を作るには、A点での速度、B点での速度が必要だったり、A点の前の点、B点の次の点が必要だったりします。, 今回はCatmull-Romスプライン曲線というA点の前の点、A点、B点、B点の先の点を使ってA点B点間の曲線を求めていきます。, Catmull-Romスプライン曲線を使うとp1とp2間の曲線をp1、p2、p1の前の点p0、p2の次の点p3の4点を使って曲線を作る事が出来ます。, ただこの場合、p1の前の点p0とp2の次の点p3が得られない時は曲線を求める事が出来ません。, わたくしの場合はp2の先のp3が得られない場合はp0、p2を足して2で割って計算する事にしました。, p0、p1、p2、p3の点を使ってCutmull-Romスプライン曲線を使ってp1とp2間の曲線が作られる様子を確認出来るサンプルを作成します。, シーンビュー上でそれぞれの点を動かして出来る曲線を確認したり、p0やp3に点がない場合の曲線の作られ方を確認出来ますが、個人的に確認するように作ったサンプルなのであえて作らなくてもいいです。(^_^;), まずはシーンビュー上で右クリック→Create→Sphereを選択し名前をposition0とし、TransformのScaleを0.3にします。, position0をCtrl+Dキーでコピーし名前をposition1~position3とします。, この4つのpositionがCatmull-Romスプライン曲線の計算に使う4点になります。, 次に右クリック→Create→Emptyを選択し、名前をCatmullSplineTestとします。, CatmullSplineTestには新しくCatmullSplineTestスクリプトを作成し取り付けます。, インスペクタのposition0からposition3には先ほど作成したゲームオブジェクトをそれぞれ設定します。, Catmull_Romメソッドは4点からtに受け取った0~1の割合でp1からp2の間の点を返します。, 例えばp0の点がない場合はp1とp3の点を足して2で割ったベクトルをp0の引数に渡します。, 2で割らずに0.5を掛けた方が計算処理が早くなるかもしれませんが、見た時にわかりやすくしておきました。, Unityを実行してシーンビュー上でposition0からposition3の点をそれぞれ動かすとposition1とposition2の間で作られる曲線が変わるのを確認出来ます。, CutmullSplinTestスクリプトのインスペクタでposition0かposition3の設定をnullにすると曲線の作られ方が少し変わります。, 一つは一度作った頂点情報はそのままにして、現在の剣の位置と前のフレームの位置で曲線を作り頂点リストに追加していくパターン。, こちらはCreateMeshメソッドでは現在の剣の位置と前のフレームの位置だけで計算する為(要はp3の点が求められない)、軌跡の形は変わりませんが曲線があまり綺麗にはなりません。, こちらは現在の剣の位置と前のフレームの剣の位置から作る曲線部分は先ほどのパターンと同じですが、その前のフレームの曲線は4点が求まるので綺麗な曲線になります。, CreateMeshメソッドで毎回曲線を作り直すので、前回作成した剣の位置と前のフレームの位置の曲線を再計算し、綺麗な曲線になります。, それでは現フレームの剣の位置と前フレームの剣の位置で曲線を作っていくスクリプトを作成します。, 先ほどのスクリプトでは頂点を共有しない形で作成していましたが、ここからは共有する形でスクリプトを組んでいきます。, faceDivisionNumは曲線を作る時の分割する数で、isSwordTrailは剣の軌跡を表示するかどうかのフラグです。, 作成したメッシュを再計算しない為にCreateMeshメソッドではverticesListsのクリアを行いません。, その為、表示するメッシュに不用になった頂点をverticesListsから削除します。, で頂点の数が計算出来ますのでそれ以上になった時にDeleteMeshメソッドを呼び出し頂点を削除します。, startHalfは剣元の間の分割点、endHalfは剣先の間の分割点を入れる配列です。, addFloatParamが分割値になり、これをCatmull_Romのtの部分に渡します。, 今回は初期値として分割値を与えてstartHalfとendHalfには分割した点のみ入るようにしています。, 現在の位置の先の点は取得出来ないので、前の前の点と現在の点を足して2で割った値をp3の値として渡します。, UV座標は頂点を共有する形にしたので、頂点番号が偶数かどうかでUV値を変えています。, 偶数の時は剣元の座標を計算するのでVの値は0、奇数の時は剣先の座標を計算するのでVの値は1になります。, また剣先の値を設定したら次は剣元の値なのでaddParamの値を増やして分割値を増やします。, 繰り返し条件は頂点を共有している為、一つの四角形では共有している2点を引いて、さらに一回の繰り返しで三角形を2つ作っている為、2で割っています。, isSwordTrailは剣の軌跡を表示するかどうかのフラグなので、表示する場合だけデータを書き換えています。, DeleteMeshメソッドは分割数 × 2分の頂点とUVを削除します(UVはいらないかも?)。, SetSwordTrailメソッドはアニメーションイベントを別のスクリプトで受け取り、そこから実行するメソッドで、剣の軌跡を表示するかどうかを切り替えます。, またキャラクターにReceiveActionEventスクリプトを作り取り付けます。, インスペクタでSwordTrailゲームオブジェクトをドラッグ&ドロップしてください。, SaveMeshNumを5、FaceDivisionNumを10にして確認します。, モーションが速くてわかり辛いですが、現在の位置と前のフレームの位置を繋いだ線が曲線にはなっていますが、多少歪んでいますね。, わたくしも解説がしんどいです・・・・(((((((((((((ーー;) さささっ・・・, 途中コマ送りして確認している部分でわかりますが、一度描いた軌跡を再計算する為、次のフレームになると元の形を変えています。, ですが、攻撃のモーションが相当遅くなければ気にならないですし、軌跡の曲線が綺麗なのを考慮するとこちらのパターンの方がいいかもしれませんね。, 頭で考えるだけじゃわからないので、紙に絵を書いて頂点の数や、UVの座標、三角形の作成方法を考えました。, それでも完全に出来た!という感じではなく、スクリプトも解り辛いままになっています。, 処理速度を考慮するともう少し最適化しないといけないかなぁとは思いますが、さすがにもうこの機能はやりたくありません。(^_^;), いずれまたやる気が起きた時にでも改良したいですが、その時にまた一からスクリプトを読み解いていかないといけないと思うと恐怖ですね・・・(T_T)/~~~, メールはこちらにお願いします(記事に関する質問は送らないでください)。 今回はAssetStoreで配信されているアセット「X-WeaponTrail」の紹介です。 Why not register and get more from Qiita? 本当にありがとうございます!, AWSのLambdaへのリクエストがCORSエラーかと思ったらサイズが大きすぎたお話, 【Unity】2DAnimationでboneを入れてSpriteを動かしてみたお話, 【Unity】パラメータ変更するマテリアルをアセットから実行中のインスタンスに変えたお話, 【Unity】AnimationControllerでループするステートから一定確率で別のモーションを実行する方法, アザラシが大好きな山梨県産Webエンジニア。2019年3月よりフリーランスSEとして東京で活動中。自称「Web業界のアザラシ」 [詳細], https://assetstore.unity.com/packages/tools/particles-effects/x-weapontrail-20972, Unity2019.3でBlenderのImportSettingsが正常に表示されない現象の対処法, 「第2回 1週間でWebサービスを作るイベント(web1week)」に参加しました!, AWSの「Lambda + CloudWatchイベント」でサイトの監視をさせてみたお話, 【Visual Studio2017】VB.NETのインテリセンスをEnterで確定した場合に改行させない方法, 【Unity】体力ゲージの実装方法の紹介 (一瞬で減る緑ゲージ+徐々に減る赤ゲージ). 攻撃アニメーションの実装が出来たので次はハンマーも一緒に動かして、そのハンマーに衝突判定を付けていきましょう。武器の判定は掴む壁と同じでレイヤーやタグで条件分岐をすればokです。 全然プロフィールになってないな・・・・(-.-), の記事に記載の順番で見て頂くとUnityの基本的な使い方がわかり、簡単なTPSゲームの作成までが出来ます。, わたくしに出来る事は既に記事にしてあるので、ブログ右上の検索窓を活用してください。(._. 下のGIFのようなエフェクトを剣を振るアニメーションに合わせて発生させます。, このようなエフェクトは下図のような連番テクスチャを作成して、ParticleSystemのTexture Sheet Animationの設定をすることでできます。 Point Cacheがあるじゃんと思うかもしれませんが、あれは特定のメッシュの頂点情報を使用しており、Scene中の実際に使用するモデルの座標は参照できません。 Boothにもクオリティの高い作品が多く出展されています。 ただParticleSystemを使うといっても、方法はいろいろとあります。, これは非VRのゲームで多く採用される方法だと思います。 Game Effect Tutorial - Slash - Part 1/4 - DucVu FX, アニメーションに合わせて発生させる方法ですが、Animation Eventを使用することでできます。