投稿記事

ものららい 2022/04/06 18:21

ブロック構造の背景(地面)を作ってみた


こんにちは🍎

今回はちょっと変わった内容にしようということでしたので、背景周りの内容にします。

3D空間上でのゲームで背景というと、なんだか地形や建物をモデリングしたりなどものすごい大変なイメージありますよね…🐄、2Dのマップ制作でも大変なのにそれに輪をかけてとてもとても大変なイメージが付きまとって苦しみが…🍏。

実際、自分も「ゲーム用の軽くて最適化したモデル」を作るのをなるべくやりたくないなぁって常々思ってるくらいで、日々なんかいい方法ないかな?って色々回避する方法を考えてたりします。(ここら辺のもやもやがあるのでビルボードでキャラクターを表示する方式でゲームを作ってたりします…)

でもあんまり頭だけで考えても、そうそういいアイデアが浮かぶことは無いので、まず挫折しないくらい簡単な所から…とシンプルな昔からあるタイルを敷いてく方法の「マップチップ的な感じで地面を作ろう」くらいの所から始めてみました。(一応3D空間上でやるのでマイクラみたいな感じのやつ)


となると、まずやらないといけないのは素材になるブロックを作る事なので、メッシュのUVをいじれるMeshUvControl.csを使用して各6面の柄を任意の物に変えられるCubeっぽい物をブロックのひな型として編集できる機能を作成しました。(平たく言うと6面箱状になるようにUVの調整できる板ポリ配置した物)


Scenes/Scene_BlockCreateEditor

Assets/Script/Tool/
Tool_BlockBase.cs ブロックの作成ツール
Tool_QuadBase.cs 平面ブロックの作成ツール

上記のシーン、Scene_BlockCreateEditorを開くとブロックを作るシーンが開かれます。

このシーンは基本、再生とかは行わないでエディタ内の操作だけでブロックを作っていきます、左Hierarchyの項目内にBlockBaseとQuadBaseというオブジェクトがあるのでこちらをコピペしてからコピーの方でブロックの編集&作成を行います。


コピペするとデフォルトの状態のブロックのひな型ができますのでMeshUV_Lengthの項目にチップの最大数、MeshUV_UpからMeshUV_Rightまでに表示したいチップの番地を入力する事で柄の表示ができます。


柄の設定を行って城壁にしてみました。

これでブロックの作成の準備が整ったので、次はブロック化してみましょう。
Pathに保存したい場所を入力して「アセットに保存」ボタンを押すとPathの場所に保存されます。

ちなみにブロック化したものは一個のメッシュになっていますので、後で微調整したくなった場合ブロックのメッシュだけを調整した物に入れ替えると、配置の方のデータを作り直さなくていいので楽です。



保存されたものをステージ上に配置してみました。(右奥の)
ブロックの作成はこれだけなので、次はブロックの塊を作る作業に移行します。


Scenes/Scene_BlockLayoutEditor

Assets/Script/Tool/
Tool_CombineBlockParts.cs 子すべてのメッシュを結合するルール
Tool_BlockDuplicate.cs ブロックやオブジェクトを指定個数分生成するツール
Tool_ObjectChange.cs 指定のオブジェクトと入れ替えるツール

Scene_BlockLayoutEditorシーンで先ほど作ったブロックを配置してみました。
こちらも先ほどのブロック作成シーンと同じようにCombineBlockPartsBaseをコピーしてからコピー先を編集していきます。

CombineBlockPartsBaseの子の要素のBlockDuplicateはオブジェクトを指定数分XYZに配置していくツールで、一応ブロック用に作っている機能ですが一応オブジェクトならブロック以外も使えるようになってます。

画像の場合X3、Y1、Z3なのでL字型の配置がされてますよね、通常は数値を増やしていっても一方向に伸びてくだけなのですが、FillModeのチェックを入れると下の画像のように中身の詰まった感じの箱型の配置をしてくれるようになります。


一応ですが、Tool_CombineBlockPartsは子に存在するメッシュすべてを一つにする機能なので、CombineBlockPartsBaseの中に入っていればBlockDuplicateの中とか関係なくメッシュ結合の対象内になります。

とりあえず配置ができたのでCombineBlockPartsBaseを選択して、Tool_CombineBlockPartsコンポーネントのPathを設定後「アセットに保存」を押してみましょう。



先ほど生成されたブロックの塊をシーンに配置してみました。

一応、このメッシュの結合を行わなくても、BlockDuplicateの配置そのままでブロックを使用する事は出来ますが、ブロックのままの状態だと重なったところの面がそのままなので、データ的にも描画的にもたくさん配置するとかなりの負荷になってしまいます、それを防ぐために結合時に重なる面や埋もれてる面は自動的に削除する処理を入れていますので、結合したメッシュは負荷が削減されていると思います。


ということで、現状のグレーの背景から地面っぽいブロックで似たような地面を作ってみました。



ちょっと歩いてみましたが…、遠景にちょっと違和感感じますよね…🐄


動画だと若干わかりにくいので補足。

ブロックを敷き詰めた感じの構造物を作ると、アンチエイリアスの設定やミップマップが悪さするみたいで、遠景が格子状になってしまってますね…うっ🐄

これ自体はアンチエイリアスやミップマップを切れば出なくなるのですが、人によってはこれらを切るのはちょっと…っていうのもありそうなので何か別の解決策あればいいんですけど、現状はわからないのですみません。

とりあえずここで止まっててもどうしよもないので、今回はその二つを切って見た目をマシにする方向で対応します。

アンチエイリアスはEdit→Project Settings→QualityメニューのAnti AliasingをDisabledにすると切ることができます。

ミップマップはAssets内のテクスチャを選択すると項目が出てくるのでチェックを外してApplyすると切れます。



あまりすっきりした感じではありませんが、これで遠景の格子状は消えます。



ちょっと最後らへんはそれてしまいましたが、これで背景少しは作りやすくなったかな?とか思ってます、…実際ここまでしても背景作るの面倒なのであんまり解決!と胸を張って言えない感じしますが、あんまり考えてもしょうがないので、次回からこの範囲で何か出来る事をコツコツやっていきたいと思います。


最後に、今回の実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。

2022_04_07_Assets.zip (971.96kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

ものららい 2022/04/03 14:56

ゲーム的な演出とかのイベント進行など


こんにちは🍎

RPGなどをプレイしてると特定の位置や話の流れでキャラが動いたり会話が始まったりとか自動的な演出する事ありますよね。

それらの動作をスクリプト上に記述していってもいいんですが、規模が大きくなるとどうしてもスクリプトの再読み込み等の時間のロスが大きくなってきて、後に数文字変更した微調整繰り返してくるとだんだんとやきもきしますよね…。

流石に開発進んでくると長い読み込みとか待ってられないので、今回は以前作った会話の機能を改造してイベントの動作を順番にする機能を作ってみました。


まずこんな感じのできるようになりました。

↓今回使用するのは主にこの二つファイル
Assets/Script/CharacterTalkEvent.cs イベント機能
Assets/TalkEvent_001.txt イベントの設定ファイル


基本的にtxtに書かれてるコマンドのある行を順に処理していくというのはキャラクターとの会話の処理と同じものですが、こっちはより上位版になっていて設定されてる範囲で会話以外の事もできるようになっています。

パラメータ等の詳細はCharacterTalkEvent.csの処理中の方に記述していますが、一例をあげると、

Character_Move : "StagePlayer", 4,0,-3, true

という記述は「Character_Move :」の部分は命令の種類で「 "StagePlayer",」は移動の指定をするステージ上のキャラクターの名前、「 4,0,-3,」は順にx,y,z、最後の「true」は移動後に次の処理を行うか即座に次の処理を行うかboolで設定できます。

他にも色々ありますが、こういう命令を組み合わせることでイベントが始まったときに村人が寄ってきてから会話を始める、や、プレイヤーが近づいたときにみんな驚いたあとで逃げていく、や、敵兵NPCが一か所に集まってみんなで作戦を練り始めるとかの演出の準備に使えます。


今回思いつく範囲で一応基本的な所は用意しましたが、状況に応じてまだまだ必要なコマンドが出てくると思うのでその都度CharacterTalkEventに追加していけばいいかなと思っています。

CharacterTalkEventができたのでCharacterTalkは必要なくなりそうですが、普通の会話をする程度ならCharacterTalkの方がシンプルで楽なので、今後も一応残しておきます。(CharacterTalkの方に不備あったのでコマンドを解読する処理はCharacterTalkEventに合わせました。


一応イベントはひと段落付いたので(しゃべってるキャラ画像の差し替えとかONOFFとか、他不足はあるけど実際使っていかないと何ともな感じなのでもうちょい後で…リソース引っ張って来る方法とかもあるので後で…)、次はキャラクターとかじゃなくちょっと変わった所をやりたいと思います。(お楽しみに🍎)


今回のの実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。

2022_04_03_Assets.zip (571.34kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

ものららい 2022/03/24 16:00

NPCとか


こんにちは🍎

前回は昨日の繋ぎこみを行ってそれっぽくなりましたが、今回はよりRPG感出るようにNPCについてちょっと作りこみをおこないました。(結構時間かかってしまったけど🐡)


一応ここではNPCは「構造的にはプレイヤーと同等」「自立移動する」「周りを認識するセンサーを持ってる」的なややアクション寄りの機能を持ったものを最終的に作成する予定なので、先ほどの内容を含めたものを作っていきます。

でも、RPG的なNPCって言うと移動しないで突っ立ってて会話だけできるみたいな店番してる店員みたいなのもいるじゃん!…と思うので、そういう「移動はしないけどでも何かしらのアクションはしたい」などのNPC未満のステージ上に存在する何らかのアクションをするオブジェクトは今後はStageEventとして扱っていきます。

平たく言うとこんな感じ。
StageNpc = プレイヤーと同等の機能を持つ自律的な動作をするオブジェクト
StageEvent = プレイヤーの操作に応じて何かしらのアクションを返すオブジェクト

一応将来的にはプレイヤーを追いかけたり等、もう少し複雑な動きしたりしてほしいですが、現状で使うかわからないような機能を作りこんでも良くないので、今回はあくまでRPGなどでもよくある汎用的な「目的に移動」と「ランダムに移動」に絞って作りました。

それだけでも実際動作させるとゲームっぽくなりますね🍎


「ランダムに移動」は移動先を自分の位置から適当に乱数で出せばいいので簡単ですが、「目的に移動」の方は自分で座標チェックして一つ一つ手付でやらない場合は何かしらの進路検索の機能が必要になってきます。

ただ、進路検索処理とかを自前でやろうとすると、実際とても大変(自分はやり方見当もつかない…)なので素直にunityの機能の一つであるNavigationを使用していきます。(せっかくUnity使ってるんだし

一応下記リンクで詳細わかりますがちょっと見にくいので「unity Navigation」とかで検索すると詳しく説明してるサイトとか結構あります。

Unity ユーザーマニュアル ナビゲーションと経路探索

簡単に説明すると、あらかじめNavigation Staticで設定された移動可能エリアをあらかじめ設定しておいて、障害物などを考慮した移動ルートをその都度自動的に出してくれるものです。


一応ナビゲーション使う前の準備がありますが簡単なのでさらっとご説明します。


まず移動する地形オブジェクトに対してNavigation Staticのチェックを入れます。


Navigationの設定パネルが出ていない場合は、Window → AI → Navigationにあります。


Navigationの設定パネルで一通り設定が完了したらBakeボタンを押すと画像と同じようにNavigation Staticの設定をした地形に青いエリアが出てきます。
この青いエリアがNavMeshAgentが移動できるエリアなので、途中途切れていたりしなければ基本的に問題なく目的地まで移動できます。

普通に使えば一筆書きにルートの上をなぞって進む感じで、設定次第で段差や谷などをジャンプして飛び越えたように移動するのも簡単でにできるのでとてもいい機能ですが、…今回は自前の移動システムとのあれこれがあって素直に使用できなので、開始、終点座標からルート座標配列を取得する処理を作ってそれを元に座標を順にたどるように移動処理を行って動かしています。

一応ですが、今回の使い方はあまりいい使い方とは言えない感じの結構カオスな実装してるので、ちゃんと理解したい方はちゃんと説明しているサイトを見て実装するのをお勧めします。
もうちょい素直に使えそうな感じになったらそっちに移行するかもですが、現状しばらくはとりあえずこの方式で行きたいと思います。

今回用意したNavigationの進路検索だけ使用する機能。
Script/BaseSystem/Static/RootNavigation.cs


NPCのリアクションと進路移動の動画。


おまけで進行ルートにミスがあったときにルート再検索して難を逃れる動画。


次回は自動で進行するイベントみたいなのを着手したいですが、微妙に会話のシステムとバッティングしそうなのでちょっと考え中…。


実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。

2022_03_24_Assets.zip (511.22kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

ものららい 2022/03/11 12:16

Unityで今まで作ってみた物をつなぎ合わせてみた


こんにちは🍎

前回キャラクターの基本的な動作の部分ができたので、今回は実際に今まで作った機能の「会話ウィンドウ」と「ふきだしセリフ」と「キャラクター」を使って移動してNPCと会話できるようにしてみました。

機能の繋ぎこみ自体はもともと初めから想定してたので問題は無かったんですが、今回会話処理というものの結構な実装の手間さを再確認してしまって、ここら辺の作業苦手だな~って思いました。

会話がNPCが一言しか言葉を発しないならそれなりに楽なんですが、普通は会話始まると数ページくらい文言が表示されて決定ボタンを押しながらどんどん読んでいきますよね。

実際それをしようとすると何かしらの会話データを解読する処理が必要になるので、まずそこから作ってましたが、経験上なるべく複雑なものにしたくないので今回は.txtファイルに一行ずつ命令文を書いていくシンプルな形を心がけるようにしました。(過去にjsonとかxmlとかでデータ保持して色々やってみましたが結局入力するデータの肥大化とかシンプルから遠ざかって行ったので今回はごくごくシンプルに徹しました。)

実際に会話データ Assets/TalkText_001.txt の中身にこんな記述がありますが。

name:ものほし
text:こんにちは!
text:今日はいい天気ですね。

会話データの命令文について説明しますが、「name:」で始まる行は会話ウィンドウの名前欄の文字列の変更で「text:」が会話ウィンドウのセリフ文言の変更になります。

基本的によほどの事が無い限り命令は「text:」に行くまで命令は自動的に次へ次へと行われます。

それはなぜかというと、名前の変更を行った際に処理が停止してしまうともう一回決定ボタンを押さないとセリフの表示がされないので、レスポンス的に非常にももやもやする感じになるので、決定キーを押して次の命令を行う動作は次のセリフの表示(または現在のセリフのアニメーションを完了させる)のみを行うようにしています。

実際そこら辺の処理は Assets/Script/CharacterTalk.cs や Assets/Script/BaseSystem/UI/UI_TextAnimation.cs に書いてありますが、若干仮組感あり今回もあんまり上手く実装できたとはいいがたいのでお手柔らかに。(これから使用できる命令も少しずつ増やしていければなど…)

ちなみにですが、会話データは色変えと改行タグ(<color=#ffffff>や<br>)が使えます。
操作に関しては、話しかけたり会話ウィンドウ内の決定はEnterキーでできます。


実際に動作してみたやつ。


他にもNPC周りの実装とかネタはあるんですが、今回会話データの命令の処理とかアニメーションする文字列にタグ適応とかで結構消耗してしまったので、そこらへんは次回に回そうと思います🐄


実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。

2022_03_11_Assets.zip (457.35kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

ものららい 2022/03/04 13:30

Unityでキャラクターを動かしてみた その3

こんにちは🍎

まず初めに、MeshUvControl.csに特定のタイミングで謎のMeshFilterが取得できないエラーが発生してたので、エディタ拡張の形で数値設定できるように修正しておきました。
結局OnInspectorGUIの使い方が微妙に間違ってただけですが、再生時とか終了時とかに余計な処理が走らなくなったので非効率的な初期化チェックがなくなってより良くなったと思います。(今後は気を付けたいですね🐡)
以下本題。


前回前々回でそれなりに動いてたのでもう次のテーマに行ってもいいんじゃないの?的な感じもありますが、一応まだやることあるのでその3やります。


Unity上でキャラをRigidbodyを使用してコライダーの地形判定を行って移動している際に結構悪さしてくるのがコライダーの摩擦設定だったりします。


例として素の状態でZの+方向に移動しつつジャンプした挙動です。

次に摩擦設定をセットして上記と同じ事をした時の挙動です。


自分もよくわかってなかったころは、なんか壁にこすりながらジャンプしてるとオブジェクトが引っかかって気持ちよくなかったりしてなかなか市販のゲーム見たいにならなくって何なんだろ?って思ってもやもやしてましたがコライダーに設定する「Physic Material」の設定を知ってから解決することができました。

Physic Materialって何?って方はこちら。
Unity ユーザーマニュアル 物理特性マテリアル

平たく言うと摩擦や跳ね返りを設定するもので、設定したPhysic MaterialはコライダーのMaterialにセットします。

こんな感じの。

設定を適応させたいコライダーの赤丸の部分にセットすると動作に反映されます。
※今回はわかりやすくプレイヤーキャラにセットしてます。


自分は0.1にしていますが、周りを見渡すと摩擦を0にしている人が結構いますので摩擦の数値はそこの所はお好みで設定するといいです。


とりあえずこれで解決してよかった…!と思ってるとまた新しい不具合が出てきます。(こういうのが精神的につらい…🐄)

具体的には設定した範囲の物体の摩擦が0になるので、物理的な加速、衝突や角度のついた所での落下などで一度ついた加速値が消える事がなくなります。(0.1でも消えきるまでに少しかかる)


摩擦0.1で大体こんな感じ。(0なら止まることなくすぅーっと行きます)

摩擦が無さすぎて坂を上る事も出来なくなり、さらに一度ついた加速値がなかなか消えないので困りますよね。

幸いRigidbodyには現在の速度ベクトルを設定する項目のvelocityというのがありますので、無駄な加速が起きないように設定してしまいましょう。

_rigidbody.velocity = Vector3.Scale(_rigidbody.velocity, Vector3.up);

自分で作っている現状の移動の処理では、移動中にはY方向の加速値以外は必要ないのでY以外は常に物理挙動で加速しないようにしています。


実際に上記の処理を走らせて無駄な加速が起きなくした場合の動作です。
(※自作の移動処理では実際移動の入力が切れたタイミングで上記の処理のあるループが走らなくなるので入力が切れたタイミングで坂を滑ってたりします、ここら辺の加速値の引っ張り感が少し欲しい場合は0にしないで徐々に減るようにvelocityを設定してあげれば引っ張りも残りつつきちんと移動する感じになります)


これで一通りの理想的な動きのするキャラクターの挙動ができたので、次回はこれを使用して別のことをやってみたいと思います。


実際動作するアセットフォルダも置いておきますので、アセットフォルダを空プロジェクトに入れれば確認できます。

2022_03_03_Assets.zip (446.84kB)

ダウンロード

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

3 4 5 6 7 8 9

記事のタグから探す

月別アーカイブ

記事を検索