- 投稿日:2021-02-13T19:46:40+09:00
Unityの野球ゲームで簡単に変化球を実装する
Unityの野球ゲームで、投手に変化球を投げさせたい場合の簡易的な方法を書きました。
あくまで簡易的なので若干リアルさには欠けるかもしれません。
手順
PlaneとSphereを用意します。
Sphereとカメラの距離はある程度空けておきます。
ボールをど真ん中に投げてみる
まずはボールを真ん中に投げてみます。
SphereにRigidBodyコンポーネントを追加し、スクリプトは以下の通りで試してみます。
powerは1000ぐらい。Ball.cspublic class BallTest : MonoBehaviour { public Rigidbody _rb; public int power; Vector3 direction = Vector3.back;//カメラの方向に投げてみる void Start() { _rb.AddForce(direction * power); } }
powerは丁度いいですが、球が転がってしまったので力を与える方向(direction)を修正します。Vector3 direction = new Vector3(0,0.2f,-1.0f);球に変化を与える
飛ばした球がColliderに当たった際に変化方向に力を加えるという方法でいきます。
以下のように空のオブジェクトを作成しBoxColliderを追加。ボールの軌道の被るように配置します。
isTrrigerはONにします。
最初はスライダーをかけてみます。
Sphereオブジェクトのtagは"Ball"に変更しておきます。ChangeCollider.csint changePower = 100; //変化させる力 Vector3 sliderDirection = new Vector3(1.0f, -1.0f, 0); //変化の方向 private void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "Ball") { Rigidbody ball_rb = other.gameObject.GetComponent<Rigidbody>(); ball_rb.AddForce(sliderDirection * changePower);//ボールに力を加える } }Colliderの位置を前後させることで曲がり始めのタイミングをずらせます。
Z軸に力を加えるとブレーキをかけることもできます。様々な変化をさせてみた
せっかくなので投手を準備して色々な変化球を試してみました。
directionをいじれば様々な変化球を実現できます。
投手のアセットはこちらを使用しました。
- 投稿日:2021-02-13T15:42:43+09:00
【Unity】SRPとBuilt-in Render Pipelineをランタイムで切り替える
はじめに
以前,Scriptable Render Pipelineを自作する記事を書きました.
【Unity】SRPを自作して独自の描画フローを構築するこの記事を書いている際に,Bilt-in Render Pipeline(以降Built-in)で作られている既存のプロジェクトの一部(インゲーム部分とか)にのみ自作SRPを適用することができれば便利だと思い方法を調べました.
方法
https://gist.github.com/togucchi/1b562b457482d4593c50f52ae75a84fa
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; public class RuntimePipelineSwitcher : MonoBehaviour { [SerializeField] private RenderPipelineAsset pipelineAsset; private RenderPipelineAsset renderPipelineAsset; void Update() { if(Input.GetKeyDown(KeyCode.S)) { if (renderPipelineAsset == null) { renderPipelineAsset = pipelineAsset; } else { renderPipelineAsset = null; } GraphicsSettings.renderPipelineAsset = renderPipelineAsset; } } }結論,
UnityEngine.Rendering
名前空間のGraphicsSettings.renderPipelineAsset
を変更することで実現できます.
RenderPipelineAsset
を継承した自作のPipelineAssetをセットします.また,nullを代入するとBuilt-in Render Pipelineに切り替わります.// 独自のSRPに変更する GraphicsSettings.renderPipelineAsset = renderPipelineAsset; // Built-in に戻す GraphicsSettings.renderPipelineAsset = null;最後に
短くなりましたが以上です.簡単に描画フローを切り替えられるので,使い方によってはすごく便利かと思います.
- 投稿日:2021-02-13T15:02:26+09:00
Unity ゲーム実行中に任意のMeshFilterからNavMeshを生成する
目的
Unity実行中にシーン内に存在するMeshFilterからNavMeshを動的に生成し、NavMeshAgentに経路探索させます
とにかくコードが見たい人はこちら
https://github.com/lisearcheleeds/SimpleNavMesh/tree/master/Assets/Scripts/SimpleNavMesh動機
UnityではNavMeshという経路探索AIが機能として実装されていますが、あまり使い勝手が良くないと思われてます。
シーンにBakeする必要があったり、GameObjectをstaticにする必要があったり、NavMeshAgentは速度と回転率を設定する必要があったり、デフォルトで勝手に移動し始めたり、まぁやっぱりなんか使い勝手悪い気がしてきました。使い勝手悪いです。
ただ、今回はその中の大きな要素の一つである「動的にNavMeshを生成するのがめんどくさい」という思い込みを取り除けると思います。ちなみに、テラシュールブログや公式のリファレンスなどで「高レベルのコンポーネントを入手する」と称して同コンポーネントが紹介されているので、
「このUnity公式の拡張コンポーネントがないと実行時にベイク出来ないんだ」とちょっと前まで思ってましたがそんなことは無かったです。
煩雑な上にstatic変数で探索対象を管理していて、宗教上私には使えなかったので倦厭してましたが、ちゃんと読み解けばシンプルな使い勝手で良い感じになります。Unity-Technologies/NavMeshComponents
https://github.com/Unity-Technologies/NavMeshComponents解説
UnityEngine.AI
- NavMeshBuildSource
- ナビメッシュを生成する最小単位
- shapeとかsizeとかtransformとか渡す。
MeshFilter
と1:1- NavMeshData
- 複数の
NavMeshBuildSource
を持つデータNavMesh
にAddNavMeshData()
で渡す
- ナビメッシュを実際に生成する
NavMeshBuilder
にUpdateNavMeshDataAsync()
で渡す
- ナビメッシュを実際に生成する
- 前回の
AddNavMeshData()
もしくはUpdateNavMeshData()
からの差分だけ更新する- NavMeshDataInstance
NavMeshData
のInstance。そのナビメッシュが不要になったときにRemove()を呼ぶNavMesh
にAddNavMeshData()
の返り値で渡されるSimpleNavMesh
https://github.com/lisearcheleeds/SimpleNavMesh/tree/master/Assets/Scripts/SimpleNavMesh
NavMeshController
コンポーネントのIEnumerator GenerateNavMesh()
を実行すると、
navMeshTargetParent
以下の全てのINavMeshTarget
に対してNavMeshを生成します
- INavMeshTarget
NavMeshTargetData
とUpdateNavMeshTargetData()
を持つインターフェイス- MeshFilterTarget
MeshFilter
からNavMeshBuildSource
を作るコンポーネントINavMeshTarget
を実装する- NavMeshController
- 指定されたGameObjectのHierarchy配下の
INavMeshTarget
を集めてBoundsを計算してNavMeshBuilder.UpdateNavMeshDataAsync()
とか叩くコンポーネント- NavMeshTargetData
NavMeshBuildSource
とBoundsを持つデータ出来なかったもの
高台から落下してショートカットするためにOffmeshLinkも動的に生成したかったんですがどうやるんですかね?
まぁそもそもあまり使わないほうが良い気がする
- 投稿日:2021-02-13T13:11:16+09:00
頭部伝達関数を使ったデモアプリをUnity WebGLで無理やり作った
何を作ったか
頭部伝達関数を使って音にエフェクトをかけ、ヘッドホンから出た音が頭の外側で鳴っているような感じで再生されるアプリを作りました。
また、手っ取り早く試せるようにWebGLで作成しました。
イヤホン・ヘッドホンを着けて聞いてみてください。
感じ方には個人差がありますが、頭の周りで音が鳴っているような感じがすると思います。WebGLにるデモアプリ
作ったものはこちら。
HRTF-Demo-WebGL使い方
- ヘッドホンを用意する
- 画面上をタッチする。タッチと同時に音が鳴る。(大きい音がするので注意)
- 緑の円がタッチしたところに表示される。この円はドラッグで動かせる。
- 緑の円の動きに少し遅れて赤い円が動く。
- 赤い円の方向に対応して鳴っている音の方向が変化する。
- 中央黄色い円を押すとサウンドがエフェクトなしで再生される
- 画面下側のボタンを押すと再生される音が変わる
(再生中にノイズが発生しますが仕様です。)
ソースコード
https://github.com/morishift/HRTF-Demo
Unity 2019.4.11f1実装
音に対して頭部伝達関数と呼ばれるデータ(実際には方向に対応するインパルス応答)を使って、選択した方向から音が鳴っているようなエフェクトをかけています。以下の記事がわかりやすいです。
立体音響を動的に生成するサウンドファイル
wavファイル、44100Hz,16bitモノラル
(サンプル曲はGaragebandで作成)畳み込み計算
サウンドデータとインパルス応答との畳み込み計算に重畳加算法を使います。
頭部伝達関数データ
頭部伝達関数のデータとして、以下を使用しました。
元データには頭に対して上下方向の情報も含まれています。このアプリでは頭と同じ高さのデータのみを利用しています。
Bill Gardner and Keith Martin
MIT Media Lab
HRTF Measurements of a KEMAR Dummy-Head Microphone
https://sound.media.mit.edu/resources/KEMAR.html無理やりなところ
Unity WebGLのサウンドに関する機能に制限があり、無理やりな事をやっています。
WebGL でオーディオの使用
Unity公式でアナウンスされているように、UnityWebGLではサウンドについては一部機能しか使えません。単純に音を再生するだけなら問題ありませんが、それ以上のことをやろうとしてもあんまり上手く行きません。(別途プラグインを導入すれば解決できるのかも)AudioClipから波形データが取得できない
Unityではサウンドの波形データはAudioClipオブジェクトから取得できます。
しかしWebGLではそれができません。(AudioClip.GetData()が使えない。SetData()は使える。)
そのため、Unityプロジェクト内にバイナリデータとしてwavファイルを配置しておき、実行時に直接読んで波形データを取得しています。AudioClipのストリーミング再生ができない
AudioClipでストリーミング再生ができれば音にエフェクトを加えながら再生させることもやりやすくなります。しかし、WebGLではサポートされていません。
そのため、1秒程度のAudioClipを連続的に生成・再生しています。
一つのAudioClipで再生するサウンドデータは32分割し、その分割した断片に方向に対応するインパルス応答を畳み込むようにしました。音の方向を選択した直後に鳴っている音が変更されず、遅れて反映されるのはこれに起因します。また、AudioClipとAudioClipのつなぎ目のところでかなり大きいノイズが発生します。
既存の立体音響SDK
試したことはありませんが、Unityで使える立体音響SDKはすでにあります。
本気で立体音響の実装を考えるならこれらを試すのが良いと思います。
Audio Spatializer SDK
https://docs.unity3d.com/ja/current/Manual/AudioSpatializerSDK.html
Resonance Audio
https://resonance-audio.github.io/resonance-audio/develop/unity/getting-started
- 投稿日:2021-02-13T13:11:16+09:00
頭部伝達関数を使ったデモをUnity WebGLで無理やり作った
作ったもの
頭部伝達関数を使って音にエフェクトをかけ、ヘッドホンから出た音が頭の外側で鳴っているような感じで再生されるデモを作りました。
また、手っ取り早く試せるようにWebGLで作成しました。
イヤホン・ヘッドホンを着けて聞いてみると、頭の周りで音が鳴っているような感じがすると思います。WebGLにるデモ
作ったものはこちら。
HRTF-Demo-WebGL使い方
- 画面上をタッチする。タッチと同時に音が鳴る。(大きい音がするので注意)
- 緑の円がタッチしたところに表示される。この円はドラッグで動かせる。
- 緑の円の動きに少し遅れて赤い円が動く。
- 赤い円の方向に対応して鳴っている音の方向が変化する。
- 中央黄色い円を押すとサウンドがエフェクトなしで再生される
- 画面下側のボタンを押すと再生される音が変わる
(再生中にノイズが発生しますが仕様です。)
ソースコード
https://github.com/morishift/HRTF-Demo
Unity 2019.4.11f1実装
音に対して頭部伝達関数と呼ばれるデータ(実際には方向に対応するインパルス応答)を使って、選択した方向から音が鳴っているようなエフェクトをかけています。以下の記事がわかりやすいです。
立体音響を動的に生成するサウンドファイル
wavファイル、44100Hz,16bitモノラル
(サンプル曲はGaragebandで作成)畳み込み計算
サウンドデータとインパルス応答との畳み込み計算をするわけですが、
定義通りの畳み込み計算をそのまま実行すると時間がかかりすぎます。
なので、重畳加算法を使います。頭部伝達関数データ
頭部伝達関数のデータとして、以下を使用しました。
元データには頭に対して上下方向の情報も含まれています。このアプリでは頭と同じ高さのデータのみを利用しています。
Bill Gardner and Keith Martin
MIT Media Lab
HRTF Measurements of a KEMAR Dummy-Head Microphone
https://sound.media.mit.edu/resources/KEMAR.html無理やりなところ
Unity WebGLのサウンドに関する機能に制限があり、無理やりな事をやっています。
WebGL でオーディオの使用
Unity公式でアナウンスされているように、UnityWebGLではサウンドについては一部機能しか使えません。単純に音を再生するだけなら問題ありませんが、それ以上のことをやろうとしてもあんまり上手く行きません。(別途プラグインを導入すれば解決できるのかも)AudioClipから波形データが取得できない
Unityではサウンドの波形データはAudioClipオブジェクトから取得できます。
しかしWebGLではそれができません。(AudioClip.GetData()が使えない。SetData()は使える。)
そのため、Unityプロジェクト内にバイナリデータとしてwavファイルを配置しておき、実行時に直接読んで波形データを取得しています。AudioClipのストリーミング再生ができない
AudioClipでストリーミング再生ができれば音にエフェクトを加えながら再生させることもやりやすくなります。しかし、WebGLではサポートされていません。
そのため、1秒程度のAudioClipを連続的に生成・再生しています。
一つのAudioClipで再生するサウンドデータは32分割し、その分割した断片に方向に対応するインパルス応答を畳み込むようにしました。音の方向を選択した直後に鳴っている音が変更されず、遅れて反映されるのはこれに起因します。また、AudioClipとAudioClipのつなぎ目のところでかなり大きいノイズが発生します。
既存の立体音響SDK
Unityで使える立体音響SDKはすでにあります。
本気で立体音響の実装を考えるならこれらを試すのが良いと思います。
Audio Spatializer SDK
https://docs.unity3d.com/ja/current/Manual/AudioSpatializerSDK.html
Resonance Audio
https://resonance-audio.github.io/resonance-audio/develop/unity/getting-started
- 投稿日:2021-02-13T11:35:43+09:00
Unity + Arborで敵AIデータを使い回す方法 〜ビヘイビアツリー編〜
一つ前の記事ではArborのビヘイビアツリーを使うときに大事なポイントを紹介しました。
この記事では、ビヘイビアツリーにて敵AIロジックを使い回すための方法を解説します!環境
Unity 2020.2.1f1
Arbor 3.7.8Arborのビヘイビアツリーでは「Sub Behaviour Tree Reference」とパラメーターを使うと、行動の使い回しができて便利です pic.twitter.com/VW3WGHz9xa
— asiram@unityゲーム開発 (@asiramasiram) February 10, 2021どういうときに役立つの?
普通ゲームで作成する敵のロジックは複数になります。
Arborでは作成したビヘイビアツリーは、コンポーネントをコピー・ペーストすることで、グラフのコピーができます。
が、こうやってコピーされた敵AI達は、全てに影響する変更をしたくなった際に、コピペしたグラフを一つ一つ開いて修整せねばなりません。
これはツライ…
そこで、今回紹介する方法を使えば、敵AIの行動単位で部品化して使い回せるようになります。
こうすると、一つの行動部品を修整すれば参照している敵全ての行動を修正することができます。
工数削減です!
使い回すために使用するArborの機能
使い回す方法を説明する前に、必要なArborの機能を紹介します。
ざっとこんなところでしょうか。
(アクションとはみたいな基本的なことは説明しません。前回の記事を参照してください
- 外部参照のビヘイビアツリーを再生するためのアクション:
Sub Behaviour Tree Reference
- 参照先のビヘイビアツリーに情報を渡すためのパラメーター
Sub Behaviour Tree Reference アクション
このアクションが使い回しのポイントです。
Sub Behaviour Tree Reference アクションは、外部のビヘイビアツリーを再生するためのアクションです。
「外部のビヘイビアツリー」とは言っていますが、ほとんどプレハブ化したビヘイビアツリーを使用するのが一般的かなと思います。
これは、「SoloTargetCastAttack」というビヘイビアツリーがアタッチされたプレハブを読み込ませているSub Behaviour Tree Reference アクションです。
こちらの例ではプレハブを読み込ませていますが、他の方法(階層から取得など)を選択することもできるようです。
ちなみに、下にずらずら並んでいるのはパラメーターです。
こちらは後で触れるので覚えておくとよいです!パラメーター
Arborにはパラメーターをとる手段がいくつか用意されていますが、今回扱うのはグラフに紐づくパラメーターです。
今回のパラメーターの用途は、使い回しする行動にパラメーターを与えて、挙動をある程度変える目的で使用します(例えば、攻撃力を変えるなど)。
グラフのパラメーターは、Arbor Editorの左側で設定することができます。
+
マークを押して型を選択、型名の横にパラメーター名を定義して、その下に値を設定できます。
上の例だと、String
が型名、attack_name
がパラメーター名、突撃
が設定された値ですね。敵AIデータを使い回す方法
では実際に敵AIデータを使い回す方法を見ていきましょう。
手順はこんな感じです。1. 部品化させたいAI行動を作成、プレハブ化する(必要であればパラメータを定義) 2. 敵A本体のビヘイビアツリーを作成する 3. 2.のビヘイビアツリー内にSub Behaviour Tree Reference アクションを組み込む 4. 3.に1.で作成したプレハブを設定する 5. 必要であれば3.にパラメータの設定を追加する順番に見ていきましょう。
1. 部品化させたいAI行動を作成、プレハブ化する
まずはこんな感じで、
BehaviourTree
コンポーネントがアタッチされただけのGameObjectを作成、プレハブ化しましょう。
(画像だとPlay On Start
とかUpdate Settings
とかいじってありますが、普通に使う分にはそのままの設定で良いと思います)次に、このプレハブに設定されているビヘイビアツリーの中身を作成しましょう。
これが使いまわせる部品になります。
つまり、「SoloTargetCastAttack」という行動が敵A、敵B、敵Cにも参照させて使いまわせるようになります。
今回はこんな感じにして、Sequencerに複数のアクションが紐づく構成にしています。
再利用しやすいように、分岐処理などは避けてシンプルに組みました。
メンテナンスのしやすさも考えて、あんまり複雑にしないほうがいいかなと思います。ワンポイント:パラメータを追加する
パラメータは必要なければ特に追加しなくてもOKですが、再利用性を高めるためにもパラメータを使用して各値を外部から変更できるようにすると使いやすくなります。
先ほどのグラフの一部です。
パラメータを定義して、アクションの各設定値に割り当てることができます。
今回は、「Enemy Action Cast Start」のSkillName
にパラメーターのattack_name
(名前がよくないかも)、CastTime
にパラメーターのcast_time
が割り当たっています。パラメーター名の右隣にある色のついた場所からドラッグ&ドロップで、アクションの設定値に割り当てることができます。
こうすることで、外部からこれらのパラメーターが設定された時に値が各アクションに反映されるようになり、例えば敵キャラによって攻撃力を変えるなどができるようになります。ちなみに、このような使い方をしたときパラメーターに設定されている具体的な値は、デフォルト値扱いになり、外部からパラメーターとして渡されない場合に使用される値になります。
2. 敵A本体のビヘイビアツリーを作成する
この手順は単純にいつも通りビヘイビアツリーを対象のオブジェクト(敵)に対して作成すればOKです。
3. 手順2.のビヘイビアツリー内にSub Behaviour Tree Reference アクションを組み込む
とりあえずこんな感じにしました。
(自作デコレーターをつけて、HP条件を満たしていないときは通常攻撃。みたいなニュアンスの設定にしてみましたよ4. 手順3.に手順1.で作成したプレハブを設定する
最初の手順で作成したプレハブをSub Behaviour Tree Reference アクションに設定します。
ExternalBT
にプレハブをドラッグ&ドロップで設定できます!
こんな感じ。
パラメーターが必要なければこれで終わりです。
ゲームを実行して挙動を確かめてみましょう。
条件を満たしていれば、Sub Behaviour Tree Reference アクションに処理が流れて、設定したビヘイビアツリーに処理が移っていくことがわかると思います!5. パラメータの設定を追加する
Sub Behaviour Tree Reference アクションの下の方の
+
マークから、パラメーターを設定することができます。
最終的にこんな感じになりました。これでAI行動を部品化して、さらにパラメータによって挙動を変えることができるようになりました!
異なる敵に同じ行動をさせたい場合は、2~5の手順を繰り返してSub Behaviour Tree Reference アクションにプレハブ化したビヘイビアツリーを設定しましょう。今回部品化した行動に修正を加えたいときは、手順1.で作成したビヘイビアツリー一つを修正すれば全ての参照している敵に反映されます。
まとめ
敵AIデータを使い回すために必要なArborの機能、手順を解説しました。
これで悲しいコピペ地獄は避けられそうです。
自分はまだ試していませんが、ステートマシンの方でもおそらく同じような使い方ができると思うので、興味がある方は試してみると良さそうです。
- 投稿日:2021-02-13T01:21:58+09:00
原神やゼルダBoWのあの雰囲気を手っ取り早く出す方法
今更ながら原神を遊び始めました。
クオリティがエグくてビックリ!
グラフィックスがすごいすごいと言われていますが、そこよりも実装されてる仕様の量と質がすごい。
このクオリティを出そうと思ったらいったい何人月必要なのか想像するだけで目眩がします。いつかこんなゲームが作りたい、でも過酷なデスマーチと、すごい勢いで増えていく開発費を想像したら作りたくない。
そんな人(自分)の為に手っ取り早く、見た目の雰囲気だけ、なんとなく原神やBoWに近づけるアプローチを置いておきます。1. はじめに
まずはTerrainなどを使ったりアセットストアで買ったりして、木と草が生えてるフィールドを用意します。
この時点ではまだPS2クオリティ。2. ライトをそれっぽくする
DirectionalLightを黄色っぽくして、intensityを少し上げます。
3.影をつける
シャドウマップを適用して影をつけます。ソフトシャドウでもハードシャドウでもいいです。
4.Ambientを調整
↑の時点では影が真っ暗でいかにも一昔前のPCゲームって感じです。
全体的に柔らかい雰囲気にするため、アンビエントライトの調整をします。
ここでAmbient ColorをHDRにすることで全体的に発光した雰囲気を作ることができます。
一気にそれっぽくなりました。5.Fogで遠近感をかもしだす
遠くの木にフォグがかかりました。
静止画だとそんなに差がないですが、実機で動いている状態だとゲーム世界の空気感が変わります。6. ゴッドレイとか置いてみる
雰囲気ものでゴッドレイとか置いてみるとなお良いです。
この他、UnityのVolumeでビネットかけてみたり、風のエフェクト(白い線みたいなやつ)を飛ばしてみたり、色々工夫するとより雰囲気が出そうです。