原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【告知】東京ゲームダンジョン9に出展します

賞与

早くも夏のボーナスを使い切った浪費家な皆さんこんにちは。特に大きな買い物をした覚えはないんですが気づけば手元からお金が消えていました。不思議です。きっと夏の暑さで溶けてしまったに違いない。

 

東京ゲームダンジョン9

というわけで、今週末の8/3に東京・浜松町で行われる東京ゲームダンジョン9に出展します。

tokyogamedungeon.com

福岡の片田舎から東京のど真ん中へ制作中のリズムアクションゲーム「Under A Groove」を抱えて上京する予定です。
東京ゲームダンジョンへの出展はこれで3回目、インディーゲーム展示会への出展は通算7回目(!)となりますが、毎度のように何かしらのトラブルに見舞われるので今回ばかりは何事もなく順調に終えられるよう頑張りたいと思います。
出展ブースの場所は3F一般入退場口の目の前「3B-7」、会場に入って直ぐの場所を頂くことができました。ありがとうございます。

 

展示内容

今回出展する「Under A Groove」は基本的にリズムゲームなんですが、一般的な音ゲーとは少し趣向を変えて『遊べるアニメーションMV』をコンセプトに、楽曲に沿ったアニメーションとプレイヤーの操作がリンクする新感覚なゲームとなっています、

 

去年からこのゲームのプロトタイプ版を色々な展示会に持ち込んで試遊された方からフィードバックをもらっていたのですが、ここに来てようやくゲームとして形が纏まったと思います。
方向性やコンセプト自体は変わってないのですが、今回東京ゲームダンジョン9で展示する試遊版は「見せる」事が多かったこれまでより「遊び」の部分の比重を大きくして、飽きの来ない内容に仕上げることが出来たと自負しています。

 

 

ちなみに今回の試遊版の楽曲にはSHUNTAさんの「COLLECTION」を使用させて頂きました。キラキラハッピーなEDMで聴くだけで幸せな気持ちになれます。

www.youtube.com

当日会場にこらえた方は他のブースの試遊待ちで手が空いた時間にでも立ち寄ってください。どうぞよろしくお願いいたします。

 

【小ネタ】lossyScaleって何だ?

認識相違

連日の猛暑で体が少し溶けている気がするのに体重は増えている認識相違が甚だしい皆さんこんにちは。この季節になると熱中症に気を付けて日中はできるだけ室内で過ごし水分補給にジュースやアイスを口にする機会が増えますが、その分、別のところが不健康になっている気がします。どうしよう。

 

新ステージ作成中

前回の記事でもお伝えしましたがリズムアクションゲーム「Under A Groove」を8月3日に開催される東京ゲームダンジョン9に出展する為、それに向けて新ステージを作成中です。

現状、東京ゲームダンジョン9までに新ステージが完成するかギリギリのところなんですが、序盤の箇所を動画にしてXにポストしたら予想外に「いいね」を多くもらえたので期待を裏切らないよう頑張りたいと思います。

東京ゲームダンジョン9での出展ブースは「3B-7」ですが、もし当日現場に来て上の映像が流れてなかったら「間に合わなかったんだな・・・」と察してください。

 

lossyScale

思えばUnityを触りだして結構な月日が経ちますが、つい先日Transformのプロパティの中に"lossyScale"という項目があることを知りました。
読み取り専用で変更する事ができないこのプロパティ、調べてみるとオブジェクトのグローバルスケールが設定されているようです。

docs.unity3d.com

幾つかのオブジェクトが親子関係となっている場合、子オブジェクトのlocalScaleは親側のlocalScaleに影響を受けるので、例えばあるオブジェクトのlocalScaleが(1.0, 0.5, 0.5)でlocalScaleが(1.0, 1.0, 1.0)となっているオブジェクトをそのオブジェクトの子供とした場合、子側のlocalScaleは(1.0, 2.0, 2.0)となります。

そしてオブジェクトのスケールはlocalScaleしかスクリプトで変更できないので、Unityエディタ上でうっかりlocalScaleが異なるオブジェクトを親子構造にしてしまうとスクリプトによるスケールの変更が思ったような挙動にならないケースも出てきます。

 

lossyScaleは親オブジェクトの影響受けない実際のスケールが設定されるので、この値を基準にlocalScaleを設定すると親オブジェクトのlocalScaleの影響受けずに一定のスケールを保つことができます。

/// <summary>
/// lossy scale を 指定の値にする
/// </summary>
public static void SetLossyScale(Transform target, Vector3 scale)
{
    target.localScale = new Vector3(
        scale.x / target.lossyScale.x * scale.x, 
        scale.y / target.lossyScale.y * scale.y, 
        scale.z / target.lossyScale.z  * scale.z
    );
}

下の動画ではCubeと鹿のモデルでCube=親、鹿=子となっていおり、親(Cube)のlocalScaleを変更するとそれに併せて子(鹿)のスケールも変更されることが分かると思います。

これに鹿(子オブジェクト)側に先ほどのコードを使って一定のスケールを保つようなスクリプトをアタッチしてみます。

親(Cube)のlocalScaleの変化に影響されずにスケールを一定に保つことが出来ました。

 

【小ネタ】スクリプトテンプレートを作って作業を効率化しよう

七夕

今年の夏も織姫(or彦星)が天の河を渡って来なかった人恋しい皆さんこんにちは。異例の速さで梅雨明けして夏が始まりましたが、それで喜ぶのは陽キャとリア充だけなので梅雨と同様にこの夏も異例の速さで終了していただけるとありがたいです。

 

東京ゲームダンジョン9

以前もこのブログでお知らせしましたが8月3日に東京・浜松町で開催される東京ゲームダンジョン9に制作中のリズムゲーム「Under A Groove」を出展します。

tokyogamedungeon.com

今回の東京ゲームダンジョン9は東京都立産業貿易センターの3F/4Fの2フロアでの展示となっているのですが、我がStab of Bee Projectの出展ブースは3Fの3B-7に決まりました。

入退場口近くの場所で人の流れ的に多くの人が最初に訪れるような場所なのでお客さんの目に触れる回数は多くなりそうですが、東京ゲームダンジョンのブース配置は同じジャンル同士で纏められる傾向が強く、実際私のブース回りも「Under A Groove」と同様にリズムゲーム・音楽ゲームが多く配置されているので、それらに埋もれてしまわないように頑張りたいと思います。
(左横のブース3B-8はリズムゲームではないけど、ちょっとインパクトのあるタイトルなのでそちらにもお客さんが持っていかれそうだし・・・)

 

テンプレートを作りたい

制作するゲームも規模が大きくなってくると当然ながら作成するスクリプトの数も増えていきます。
一応、できるだけ処理のカプセル化、疎結合を意識して作成していますが、どうしても個別の処理が必要な場合はせめてI/Fは共通化しようとスクリプトに共通のインターフェースを継承させて作成するのですが、そうするとインターフェースに定義したメソッドはクラス内に必ず定義しないといけない、というお決まりがあるので、そうしたクラスを作るたびに「継承するインターフェースのメソッド全てを定義したテンプレートクラスがあれば便利なのに」と思います。

よく考えてみるとMonoBehaviourを継承したスクリプトはUnityエディタのメニューから作成され、しかも「Start()」「Update()」の関数は定義された状態で作成されているので、どこかしらにテンプレートが定義されているはず。

public class TestClass : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
    }
}

それと同じように独自のインターフェースを継承したスクリプトのテンプレートが定義できないか調べてみました。

 

ScriptTemplatesフォルダ

スクリプトのテンプレートを定義する機能はUnityエディタのメニュー上にはありませんが、Unityエディタのフォルダ内にスクリプトのテンプレート定義を直接配置することで設定することができます。

C: > Program Files > Unity > Hub > Editor >(Uniyバージョン)> Editor > Data > Resources > ScriptTemplates

このフォルダを開くと既にいくつかスクリプトのテンプレートが定義されている事がわかります。


ここに定義したいスクリプトのテンプレート(.txtファイル)を配置します。ファイル名は以下のルールに従って定義します。

[表示優先順]-[メニュー表示名]-[ファイルデフォルト名].[ファイルの拡張子].txt

またメニューパスにおいてアンダースコアを2個使うことでメニューに階層を作ることが出来ます。
例えばテンプレートファイル名を

3-Scripting__Interface__ComPartsIF Script-NewComPartsIFScript.cs.txt

とするとUnityエディタでは右クリックで表示されたメニューの中からScriptingを選ぶと

のように表示され、設定したテンプレートファイルの定義からスクリプトを作成することができます。

 

テンプレートの定義

テンプレートには作成したいクラスのusing設定や継承元の定義、およびメソッドの定義(空メソッドで良い)を行います。
クラス名はエディタ上で書き換えるので「#SCRIPTNAME#」で定義する必要があります。
今回の場合は独自のインターフェースを継承したクラスのテンプレートなので以下のような定義としました。

public class #SCRIPTNAME# : MonoBehaviour, IComPartsInterface
{
    //-------------------------------------
    // Interface
    //-------------------------------------
    public void Init_CommonParts()
    {
        #NOTRIM#
    }
    public void Reset_CommonParts()
    {
        #NOTRIM#
    }
    public void End_CommonParts()
    {
        #NOTRIM#
    }
}

 

最後に

今回はUnityエディタのScriptTemplatesフォルダ内に定義ファイルを設置してスクリプトのテンプレートを追加しましたが、ScriptTemplatesフォルダはUnityバージョン毎に作られるので別のUnityバージョンをインストールした場合、そちらのフォルダの ScriptTemplates を再度設定しなくてはいけません。
また、当然のことながらテンプレートの定義追加は設定したPCのみに有効で、違うPCにも追加したい場合にはそのPCにも同じような処置を行う必要があります。
なのでUnityエディタのアップデートを頻繁に行ったり、GitHub等でプロジェクトを共有している場合はプロジェクト毎にテンプレートを設定することもできます。

その場合はScriptTemplates フォルダをプロジェクト内に作り、その中に先ほどのテンプレートファイルを設置してください。このプロジェクト専用のテンプレートファイルにすることができます。Unityインストール先の ScriptTemplates 同じファイル名がある場合は、このフォルダの中にあるテンプレートが優先されるようです。

【Unity】2次ベジェ曲線を使ってLitMotionでジャンプ機能を実装する

夏風邪

先週発症した夏風邪が一週間たっても未だ完治しない虚弱体質な皆さんこんにちは。発熱や鼻水等の症状は収まったのですがずっと咳が止まりません。咳止めを飲んでも完全に収まらず、咳をすると頭と胸に響いて痛いです、助けて。

 

LitMotion

Unityで標準的に使用されているTween系アセット言えばDoTween辺りが上げられそうですが、ここ最近ではLitMotionも広く使われるようになってきていると思います。

github.com

LitMotionは有志の方によって作成されたたフリーライブラリでDoTweenを比較して機能数では劣るもののTween処理が5倍ほど高速であることが最大の特徴なんですが、少し前のバージョンアップにより、PunchやShakeといったAPIと共にSequence(複数Tweenの順次実行)の機能が追加され、以前と比べてかなり使い勝手の良いライブラリになったと思います。

とは言え、DoTweenには実装されているのにLitMotionでは実装されていない機能が未だあるのは事実で、個人的にはJump系のTween機能がLitMotionに実装されていないのはちょっと痛い。DOPathのようなPathに沿った移動の機能も無いんですが、そちらはSplineを利用することで実装することができたので、以前このブログの記事で紹介しました。

www.karvan1230.com

 

その場でのジャンプ

Jump系機能が無いのは痛いとはいうものの、場所を移動せずに上方向にだけ飛びあるような動作の場合はジャンプの始点から最高到達点までの移動に対して、Easingに放物線を描くカーブを指定すればそれっぽい動作になるので、特に何か難しい工夫をする必要はありません。

Easingにこんな感じのAnimationCurveを指定

 

場所が変わらないその場でのジャンプ動作

 

問題はジャンプしつつ他の場所に移動するようなケースで、例えば下の図のような場面

ペンギンがジャンプして正面にあるCUBEの上面に乗る動作を作りたい場合、Easingの指定だけでは放物線を描いて移動するようなジャンプ動作は作れません。

 

2次ベジェ曲線を使おう

オブジェクトが放物線を描いて移動するには、その放物線を計算する必要がありますが、わざわざ放物線の方程式を書いて計算するよりベジェ曲線を使った方が簡単だと思います。
ベジェ曲線とはコンピュータ上で滑らかな曲線を表現するための計算手法で、始点と終点の間にN個の制御点を設けてそれらを利用して曲線を描きます。より複雑な曲線を描こうとすると制御点の数を増やしていく必要がありますが、今回は簡単な放物線の為、制御点を1個設ける「2次ベジェ曲線」を使う事とします。

 

先ほどの説明だと難しそうな処理になりそうな印象ですが、以外にも2次ベジェ曲線の計算は以下の3ステップで計算することが可能です。

  1. 始点と制御点を結ぶ直線上の点を計算する
  2. 制御点と終点を結ぶ直線上の点を計算する
  3. 1の点と2の点を結ぶ直線上の点を計算する

上の3ステップで導き出した3ステップ目の点が2次ベジェ曲線を描く点となります。1~3の点を時間と共にそれぞれの直線上で移動させてやると2次ベジェ曲線が描かれます。具体的には下の動画の白い曲線が2次ベジェ曲線となります。

 

実装しよう

上記の1~3の点はVector3のLerpを使えば簡単に求められます。

Vector3 CalBezierCurve(Vector3 start, Vector3 end, Vector3 control, float t)
{
  // ①.始点と制御点を結ぶ直線を移動する
  Vector3 Q0 = Vector3.Lerp(start, control, t);
  
  // ②.制御点と終点を結ぶ直線を移動する
  Vector3 Q1 = Vector3.Lerp(control, end, t);
  
  // ③.①と②を結ぶ直線を移動する
  Vector3 Q2 = Vector3.Lerp(Q0, Q1, t);
  
  retur Q2;
}

 

上の関数に渡すtの値をLitMotionにより0~1に変化させて逐次オブジェクトのポジションに反映されてあげれば放物線を描きながらの移動が可能となります。

LMotion.Create(0.0f, 1.0f, moveTime)
  .WithEase(Ease.Linear)
  .Bind(value =>
  {
    Vector3 modPos = CalBezierCurve(StartPos, EndPos, ControlPos, value);
    this.transform.position = modPos;
  })

実際にはこんな感じの動作となります。

 

最後に

ベジェ曲線の性質上、制御点は放物線の最高到達点ではないので、最高到達点を指定するような放物線は描けないのですが。でも複雑な計算式を必要としない、それとなく放物線を描いているように見せたい場合にはこれで十分な気もします。

 

【アセット紹介】Rope Toolkitを使ってロープを作ろう

クーラー風邪

エアコンで室内を冷やしすぎて風邪をひいた免疫力弱目な皆さんこんにちは。梅雨なのに真夏ような暑さが訪れて、辛抱たまらずエアコンのスイッチをONにしたのですが、その所為か朝起きたら喉と鼻を痛めてました、あと体もだるいし。日本の季節って本当に夏と冬だけになったのかもしれない。

 

ロープを作ろう

Untiyで3Dの曲線を作ろうと思うと、Unity標準SplneのSpline Extrudeを用いて線を描画するか、Spline沿ってLineRendererで描画するか、の手法が考えられるかと思いますが、どちらも描画後に曲線を変形させようとすると実装に骨が折れます。
例えば電柱をつなぐ電線やブランコの鎖など、風やその他の影響で自然に変形するような3D曲線を作ろうと思えばアセットの力を借りるのが手っ取り早い、とうわけで今回は手軽にロープが作れるRope Toolkitのご紹介

Unityでロープを作るアセットと言えばObiRopeが有名なんですが、Rope ToolkitはBurstコンパイラを使用しており、より高速な処理が望める為、スマホ等のモバイルデバイスでの使用も可能との事。丁度アセットストアで2$セールの対象となっていたので興味本位に購入してみました。

 

準備

前述のようにRope toolkitではBurstコンパイラを使用しているため、このアセットの導入前にPackageManagerからBurstをプロジェクト内にインストールしておく必要があります。

Rope Toolkitで生成されるロープはUnityエディタのゲーム実行時に生成される為、シーン内にはロープのオブジェクト(Prefab)を配置するのではなく、空のオブジェクトにRope生成用のコンポーネントをアタッチして、そこにロープを生成させるための設定を行うことでロープが作られます。

上の動画はアセットに含まれているデモシーンを実行した映像ですが、実行前は下の図ような感じでシーン内にはロープのオブジェクトは存在していません。


ロープの生成

Rope Toolkitでロープを定義するには最初にシーン内に空オブジェクトを生成し、そこに「Rope」コンポーネントをアタッチします。

シーン内にSpawnPointsのダイアログが表示されるので二回押下、これがロープの始点と終点になりますが、後でそれらの位置は変更できるので最初は適当な場所で構いません。

始点と終点の位置を変更するにはシーン内のナビゲーションコントロールからハンドアイコンを押下します。

Ropeコンポーネントにはほかにもロープの半径(Radius)やMaterialを設定する欄があるのでそちらも設定します。

 

ロープの動作定義

つぎにロープの始点と終点の動作を定義します。Ropeコンポーネントをアタッチしたゲームオブジェクトに始点と終点分のRopeConnectionコンポーネントを追加します。
これはつり橋のようにロープの両端が固定されている場合、振り子のようにロープの片側が固定されてもう片側は接続されたオブジェクトの動きに影響を受けるような場合等々、作成したいロープの動作をRopeConnectionコンポーネントで設定します。

設定できるタイプは以下の通り

  • Pin Rope to Transform:トランスフォームは自由に動き、ロープが追従する
  • Pin Transform to Rope:ロープは自由に動き、トランスフォームが追従する
  • Pull Rigidbody to Rope:ロープでリジッドボディを引っ張る
  • Two Way Coupling Between Rigidbody And Rope:ロープはリジッドボディに反応し、リジッドボディにフィードバックインパルスを返す

今回は両端が固定されたロープを定義するので、始点と終点のどちらにも「Pin Rope To Transform」を設定します。
そして、ロープを固定する始点と終点のGameObjectをシーン内に作成し、Tranform SettingsのTransformにそれぞれを設定します。


この時、始点側のRopeConnectionにはRope Locationには0を、終点側のRope Locationには1を設定します。

球が始点を固定するGameObject、Cubeが終点を固定

この状態でゲームを実行すると先ほど指定した始点、終点のゲームオブジェクトにつながったロープが生成されます。

 

ロープのカスタマイズ

例えばロープの中間点にロープをピン止めする定義を増やしたい場合、。RopeコンポーネントをアタッチしたゲームオブジェクトにRopeConnectionコンポーネントを追加します。
そして先ほどと同様に固定するためのGameObjectを作成してTranform SettingsのTransformに設定しますが、この時、タイプには「Pin Rope To Transform」を設定して、Rope Locationには0.5を指定します。

これを実行すると

中間点をピン止めしたロープが作られます。

 

これとは逆にロープの中間点に何か重い物がつけられているような動作としたい場合は、中間点のGamesObjectにRigidboyを追加し、RopeConnectionのタイプには「Two Way Coupling Between Rigidbody And Rope」を指定Rigidboy Settingsのbodyに中間点のGamesObjectを指定します。

これを実行すると

中間点が垂れ下がるような動作となります。

 

最後に

Rigidboy Settingsには「Stiffness(剛性)」や「Damping(減衰)」の項目があり、Rigdibodyに影響されるロープの挙動を調整できますが、思ったような挙動をさせるにはRopeConnectionだけでなく、Ropeコンポーネント側の「Stiffness(剛性)」や「Energy Loss」「Collisions」の項目をアレコレと調整して挙動を確認する必要があります。

例えば上のようにロープの終点側を固定せず振り子のような挙動をさせたい場合、終点側のRopeConnectionの設定を変えるだけでなくRope側の設定も色々変更して調整する必要がありました。

調整後のRopeパラメータ

幸いサンプルシーンには「つり橋」「ブランコ」「振り子」等のロープを使ったギミックの例を参照できるので、それらを確認しながらSettingを行ってい下さい。
一応英語ですがDocumentも付属しています。

 

【アセット紹介】Odin Inspectorで意外と知らない便利機能


点検

車を定期点検にだしたら部品の劣化よりも走行距離が全然伸びてないことを注意された休日ニートな皆さんこんにちは。バッテリーの充電が不十分になりますよ、とやんわりと注意されましたがだからと言って用もないのに車を運転しようとは思わないのできっと次の定期点検でも同じようなことを言われるのだと思います。

 

Odin Inspector

皆さんはOdin Inspectorを使っていますか?Odin Inspectorは Unity界隈では非常に評価が高いアセットであり、導入することで Unity エディタが拡張され、作業を大幅に効率化する事が期待できます。

私はもう何年も前に導入して、このアセットなしには開発できないぐらいなんですが、変数のグルーピングなどいつも同じ機能ばかり使用していて調べてみると意外と知らい便利機能が備わっていて今後の為、これらの機能を忘れないように記事にまとめようと思います。

 

AssetList

List内に設定するGameObjectやScriptabelObjectを指定したフォルダ内から選ぶようになります。
例えば、以下のフォルダにPrefab化したGameObjectが格納されておりListに設定しておきたい場合、

設定するList変数の前にAssetListとファイルパスを設定しておくと

[AssetList(Path = "/Prepair/Prefab/")]
public List<GameObject> AssetList;

フォルダ内のファイルがList化して表示されるので使用するファイルにチェックを入れるだけで済みます。

 

Color palette

指定した名前のカラーパレットから選んでColorを設定できます。

[ColorPalette("My Palette")]
public Color MyColor;

カラーパレットを作成してない場合はこんな感じでInpspector上にボタンが表示されるので、これを押すと

カラーパレットの作成画面が表示されて作成することが出来ます。

カラーパレットを作り終えるとInspectorに反映されます。

 

Button

スクリプト内で関数の上に定義します。

[Button("スクリーンショット")]
private void ScreenShoButton()
{
    // スクリーンショットを保存
    CaptureScreenShot("ScreenShot.png");
}

するとInspector上にボタンが表示されるので

これを押すとPlay Modeにしなくても、その関数が実行できます。デバッグに便利。

 

変数の設定系

Rangeで変数に設定する値の範囲を指定すると

[Range(0, 10)]
public int Field = 2;

スライダーが表示され、指定範囲内で値を設定できます。

 

視覚的に変数をバーとして表示して設定したい場合は

[ProgressBar(0, 100)]
public int ProgressBar = 50;

Progress Barを指定します。

スライダーと同様にDragで値も変更できます。

 

最後に

Odin Inspectorは少し高価なアセットですが、その値段なりの価値はあると思います。
今回紹介した機能以外にもDictionaryの内容を参照できたりと便利な機能がそろっているので、作業の効率化を考えるなら購入を検討してはいかがでしょうか。

【小ネタ】InputSystemからの入力とUI操作との競合を防ぎたい

バージョンアップ

Unityのバージョンアップには毎度冷や汗をかく臆病者の皆さんこんにちは。先日今後のことも考えてUnity2022からUnity6.0へバージョンアップしたのですが作りかけのプロジェクトで案の定エラーが複数個表示され冷や汗を書きました。Unity本体をバージョンアップする際には不要なアセットを削除して、アプデ後にはLibraryフォルダを一度消した方が良いと思います。あと当然ながらバックアップを忘れずに。

 

数をこなして覚えましょうなゲーム

世間ではきっとナイトレインで賑わっているでしょうが、ボッチ人間には手が出しづらいので評判の良かったソウルライクゲームを購入しました。

 

ソウルライク定番のダークファンタジーな世界が舞台の高難易度アクションRPGゲームで、キャラクターはアニメ調のトゥーンレンダリングが採用されておりCODE VEIN辺りに見た目は似てますが、プレイ感覚はソウルライクというより仁王ライクと言った方が良いと思います。
手に入る武器防具にランダム特性が付いていたり、武器防具の同種による揃え効果があったり、ステージはミッション形式で一度ステージを離脱して他のステージを探索後戻ったりすると、それまでのショートカットやギミックの解除がリセットされるなど、ゲームルールは完全に仁王・ウォーロンの影響を受けています。

その為か敵(ボス)の攻撃はかなり激しく早い攻撃ばかりで、それに打ち勝つには相手の攻撃を見極めてパリィやジャスト回避といった行動を組み合わせることが必要になります。まぁウォーロンほどパリィを強要されませんが、エルデンリングのように色んな武器・戦技・魔法の中から戦略を考えて敵に対峙する的な攻略要素は少なく、ひたすら相手のモーションとタイミングを覚えててカウンターを決めるなり回避するなりの行動を取ることが必要で、その苦行の繰り返しが楽しいと思えるかがこのゲームを楽しめるかの分水嶺になっています。

ソウルライクの中でも仁王・ウォーロンの系譜が好きな方はこのゲームに適応できて楽しむことができますが、エルデンリングのようなプレイ感覚を求める方は少し合わないゲームなのではないでしょうか。

 

InputSystemは使いやすい

Unity2022以降のバージョンを使う場合は旧Unity.Input APIを使うよりもInputSystemを使うケースの方が多いかと思います。
Input Systemではマウスやキーボード、ゲームパッドなどあらゆる入力デバイスを一元で管理できるInputActionが用意されており、それを使えばマウスの左クリックとスマホ画面のタッチ入力が同じイベントとして扱うことが出来るのでデバイスの違いを意識せずにスクリプトを組むことができます。

docs.unity3d.com

InputSystem使用下でのUI操作にはEventSystemにアタッチされたInputSystem UI InputModuleを使用しますが、こちらはシーン内にCanvasを作成する際に自動で付与されていたりするので特に意識することなくボタンクリック等のイベントも発火させることが出来ます。

このボタンクリックは当然ながらマウスの左クリックや画面のタッチ操作によって操作されます。そしてInputActionによるマウスの左クリックおよび画面のタッチも同時にイベントして発火されます。このため、普通に実装するとゲーム画面のUI操作(ボタンクリック)とゲームの操作入力が競合する状態になります

 

競合を避けたい

例としてマウスの左クリックを押下(ドラッグ)すると前に進み、離すと止まる、という操作のゲームを考えます。
この状態で画面内に一時停止用のボタンを配置してやると

ボタン押下による一時停止と同時に少し操作キャラクター(ペンギン)が前に進んでいる事がわかると思います。

このようなケースではInputActionによる発火イベント内でEventSystemのIsPointerOverGameObjectを参照する事がもっとも簡単な実装かと思います。

// Input Actionのperformedコールバック
public void OnCallBack_OnFire(InputAction.CallbackContext context)
{
    // UIの上にカーソルがあったら、入力を受け付けない
    if (EventSystem.current.IsPointerOverGameObject()) return;

    // ボタン押下時の処理
    Event_OnFire();
}

この手法は全てのUIを対象としてUI上にカーソルなどがあれば入力をブロックする方法です。そのため、ImageコンポーネントなどのUIも対象となるため注意が必要ですが、ボタンだけとしたい場合はRayキャストを飛ばしてUI要素を取得し型チェックするなど少し面倒な実装になるので、画面中に不要なUIを表示しない等の対策をして上記のコードを実装するのがおすすめです。

この対処を先ほどのゲームに実装した結果は以下のようになります。

一時停止ボタン押下してもキャラクターが前進しなくなりました。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。