かみおかのチラ裏

思い付きを書き溜めておくばしょ

JoyStickを使って、スクロール移動のようなものをできるようにする

前回、RayCastによる衝突判定を利用したScene移動を実装しましたが、
このメニュー画面はまだ完成ではないので、完成に向けてさらに機能を実装します。

ちなみに、今回やりたいこと(イメージ)はコチラ↓

ポケモンエストのステージ選択画面に近いことをしたいんですよね。
全く同じこととなると、おそらくUniRxを使うハメになるのでそこまではしませんが、
このスクロールのようなものはやりたい、ということでアレコレ弄っている感じです。

ということで順番に作業していきます。

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)

JoyStick/JoyStick Packとは?

リリースから相当経っているので、
他のサイトさんの説明の方が分かりやすいと思いますが、簡単に書いておきます。
JoyStickとは、ゲームのコントローラーについているスティック状の入力機器です。
もっと平たくいうと、3Dゲームなどで主人公をぐりぐり動かせるアレです。
最近、アクションゲームなどでスマホゲームでも見かけるのは珍しくなくなりましたね。
JoyStick Packは、このJoyStickを簡単に実装できるアセットです。

実際の使用方法

アセットDL〜使用の仕方は文末の参考サイト様を見ていただく方が早いと思いますので、
そこは省略して今回神岡が実際にやったものについて記載します。

JoyStickの配置

JoyStick Packがインポートできたら、SceneにJoyStickを配置しましょう。
JoyStickプレハブはUIなので、Canvasに配置する必要があります。
Canvasオブジェクトがない場合は、UI > Canvasから作成します。
作成したCanvasにインポートしたJoyStick PackのPrefabsフォルダから、
使いたいJoyStickのプレファブをドラッグします。

これでJoyStickの配置は完了です。

あとは、JoyStickを使える範囲を設定しましょう。
お好みでいいと思いますが、今回はこんな感じで設定しています。

Playerの代わりとなる空のオブジェクトを作成

このJoyStick、プレイヤーを操作するために使用することが多いですが、
今回は視点変更することで擬似的にスクロールしているように見せたいので、
空のオブジェクトを作成します。
名前はわかりやすい任意のものでいいですが、今回は「ChangeViewPoint」にしました。

MainCameraをChangeViewPointの子オブジェクトにする

Player代わりのChangeViewPointにカメラを追従させたいので、
MainCameraをChangeViewPointの子オブジェクトにします。

上記の関係性になっていないと、永遠に移動してくれないので注意してください。
とはいえ、MainCameraをChangeViewPointにドラッグするだけなので、
やることはシンプルです。

ViewPointController.csを作成する

実際にChangeViewPointを制御するためのスクリプトを作成します。
こちらもファイル名はお好みでどうぞ。

using UnityEngine;

public class ViewPointController : MonoBehaviour
{
  //FloatingJoystickを格納する(Inspectorで設定)
    [SerializeField] private FloatingJoystick FJoyStick;

    //移動速度を設定する(Inspectorで設定)
    [SerializeField] private float JSMooveSpeed;

    // Update is called once per frame
    void Update()
    {
   //上下移動する
        this.transform.position += this.transform.up * joyStick.Vertical * JSMooveSpeed * Time.deltaTime;
   //左右移動する
        this.transform.position += this.transform.right * joyStick.Horizontal * JSMooveSpeed * Time.deltaTime;
    }

}

今回は2Dゲームということもあり、
上下左右(斜めも可能なのですが)移動できるようにしたかったので、
upプロパティとrightプロパティを使用しました。
しかし、3Dの場合ですと前後移動したいことも多いと思います。
その場合はforwardを使いましょう。

Unity側の設定

最後に、スクリプトやオブジェクトのアタッチやらをしていきます。
まずはViewPointController.csをChangeViewPointにアタッチします。
次に、ChangeViewPointのInspectorから
FJoyStickにはFloatingJoystickのプレハブを、
JSMoveSpeedには任意の数値を入れましょう。今回は「3」を入れております。

JSMoveSpeedはもちろんコードから直接指定できるのですが、
SerializeFieldにしておきInspectorから設定可能にすると調整しやすいと思います。
この辺はお好みでどうぞ。

こんな感じで動くよ

必要な設定ができていると、こんな感じで動きます。

自力で作るとなるとかなり大変ですが、
このアセットを使うとすごく簡単にできてしまいます。

でも、微妙に見た目がダサいね?


おやおや、画面外にも移動できてしまって青い背景が見えて、
なんだか格好がつきませんね。
せっかく作るゲームなので、ここもちょっとこだわりたいところです。
こちらにつきましても無事に解消できましたので、また別の記事で書きたいと思います。

参考記事

最後に、大いに参考にさせていただいた記事を掲載します。
毎度のことですが、先人の知恵に本当に感謝です...足を向けて寝れませぬ。
qiita.com
solitude-bocchi.com

RayCastによる衝突判定(2D)


ご無沙汰しております。
なんと、前回更新日から136日経ってしまっていたようです。
途中、ダウンしてしまい空いてしまいましたが、開発は細々と継続中です。

今回はRayCastによる当たり判定について、備忘録として書いておきます。

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)
 

さて、現在開発中の「そらとぶメンダコ」のステージ選択画面、
Buttonを使うことでプレイするステージを選択できるようになっているのですが、
一つ問題が...。
選択可能なステージが増えると、視認性や操作性が落ちるのですよね。

今は少ないので視認性に問題はないが、10を超えると...

ということで、画面スクロールをしてひとつの画面内に表示するボタン数を減らそうと思い最初に考えたのがJoyStickによる擬似的な画面スクロールです。

が、当然ですがCanvas内に配置されたUI系のButtonは、
JoyStickによる操作の影響を受けません。
結論を書きますと、UIのスクロールはScroll Viewによって実現できそうなのですが、
Scroll Viewはクセの強い子らしく、なんとか他の方法でできないものかと思いました。

ということで、アドベンチャーゲームなどによくある
ポイント&クリックの仕組みを利用してみることにしました。

さて、ポイント&クリックはご存知の通り、
タップなりクリックしたオブジェクトを何かしらの操作できる仕組みです。
どうやっているかというと、スクリーン上でクリックした位置からRay(光線)を飛ばして
当たり判定をしているようです。
この辺りは他のやり方もあるだろうとは思いますが、
おそらくRayCastによる衝突判定が一番素直で分かりやすいのではないかと思います。

 今回やりたいことの具体的なものとしては、
ステージごとのボタンとなるオブジェクトを配置し、
オブジェクトによって生成するステージを分岐させるなので、
Rayを飛ばす→RayがHitしたオブジェクトを検出する→検出したオブジェクトによってその後の処理を分岐させる、ということになります。

ということで、今回作成したコードは以下のような感じになりました。
(雑に完成した料理を出す某キュー◯ースタイル)

   Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction, 20);
            if (hit.collider)
            {
                if(hit.collider.gameObject.name == "GameObject名")
                {
                    //実行したい処理
                }
            }
        }
    }

ifだらけになってあまりスマートとは言えない実装になってしまいました...。
この実装でも問題なく動きますし、
今回はステージ数がそれほど多くないため極端に負荷が上がるとは思えませんが、
できればswitchで分岐させたかったです;;そっちの方がコード的にも読みやすい。

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

画像が荒くて見づらい場合もありますが、
上部分のScene Viewで実際に飛ばしたRayを可視化しています。
細いですが、赤線で可視化されています。

ちなみに、3Dの場合は少々書き方が違いまして、

   Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, Mathf.Infinity))
            {
                if(hit.collider.gameObject.name == "GameObject名")
                {
                    //実行したい処理
                }
            }
        }
    }

と、このような感じになります。
使用している物理演算が異なりますね。

今回はRayの衝突先のGameObject名を取得して処理を分岐させていますが、
これについてもあまりスマートとは言えない方法だろうと思います。
この方法だと、せいぜい数十程度ならコピペでまあどうにかなりますが、
100を超えてくるとそもそも打ちたくありませんし、何より絶対にミスが発生します。
数が多くなりそうな場合はLayerMaskをうまく使うとよさそうです。
先述の条件分岐も含め、他に良い方法をご存知の方がいらっしゃいましたら、
コメントいただけると嬉しいです。
(ま、マサカリも受け止めます...小声)

ちょっと雑な感じになってしまいましたが、余力があれば加筆修正したいと思います。
今回はこの辺りでさようなら。

Inspectorを整理する

ずっとInspectorに表示されるフィールドが羅列されているだけの状態だったのですが、
つい最近Header Attributeというものを知りまして、とても便利だったので備忘録として残しておきます。
 
いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)
 

 

Header Attributeとは?

Inspectorのフィールドに属性を追加することができます。
フィールドが多い時に使うと、Inspector上の視認性が良くなるので便利です。
Unity 4.0の頃からあったため特に新しい機能ということはないのですが、
Unity入門者向けの本などにはあまり載っていないため、今まで知りませんでしたorz
 

使用例

実際に使って見た方が分かりやすいので、実例を出してみます。
 
下の画像はHeader Attributeを使わずにInspectorを表示した場合のものです。

項目ごとに整理しているものの、全て同じように表示されているので少々見づらいです。
コード上だとコメントアウトでコメントしたり、
改行を使って分類ごとに分けられるのでいいのですが、
Inspectorにはもちろん反映されません。
 
対して、Header Attributeを使った場合のInspector。
属性ごとにまとめて表示してくれているので、視認性が良くなりましたね。

使い方

使い方はとっても簡単です。
フィールド定義の上に[Header("")]を追加するだけです。
""の中は任意の文字列を入れます。
上の画像の例だとUIを入れているので、Inspector上だとこんな感じで表示されます。
上手に使えばフィールド定義のコメントアウトが不要になるかもしれません?

ちなみに...ソースコードを貼り付けたかったのですが、
これ、はてな記法MarkDown記法でないと使えないということを知りました...。
見たままで記事を作ってしまったので時すでにおすし。
次回までに対応する所存。

参考サイト

ekulabo.com

qiita.com

 

特定のオブジェクトの物理演算を一時停止させる


ゲームの進行を一時的に止める時に使うことが多いのは
Time.TimeScale=0;ですが...

 

いつもの注意書き
なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)

 

物理演算を使っている自機などをポーズ中に止めたい時、
最もお手軽にできるのがTime.TimeScale=0;です。
しかしこの方法だと、全てのゲーム進行に関わる時間をストップさせてしまいます。
(※厳密には、Update()内に書かれたものなどは止まりません)
そのため、ポーズを解除してゲームに復帰するまでに
カウントダウンさせる時などは、ちょっと不都合です。
時間自体が止まってしまうので、カウントダウン自体も進まないからです。
フラグ管理をすれば実装可能ですが、ちょっとめんどう...。

ということで、何とか特定のオブジェクトだけ停止させる方法がないかと考えていたところ、
Rigidbody2Dクラスにsimulatedというプロパティがあることを教えて頂きまして、
無事に問題を解消できたので備忘録的に残しておきます。

前置きが長くなりましたが、
simulatedとは何かというと、上で書いた通りRigidbody2Dにあるプロパティです。
詳細はUnityの公式リファレンスを見ていただくのが
一番確実だと思うので省略しますが、
このsimulatedはbool型変数なので、trueかfalseのみを代入できます。

trueだとsimulateが有効になり、falseだとsimulateが無効になる。

シンプルですね。

実際に使ってみると、こんな感じです。
ポーズメニューが非表示になったあと、自機がが空中に浮いたまま停止

動画中の自機(メンダコ)は物理演算が有効になっているので、
タップし続けなれば落下してしまいます。
しかしポーズ画面解除〜ゲーム復帰のカウントダウンでは落下させたくないため、
simulated=false;にしています。
Time.TmeScale=0f;と異なる点は、
あくまでもRigidbody2Dにのみシミュレーションを無効にしているため、
それ以外のAnimationやメソッドで動かしているものは動いたままとなる点です。
(例えば動画中の鳥はAnimation+Sin()で動かしています)

特定のオブジェクトだけを動かさないことを実現できる方法は他にもありますが、
Rigidbody2Dを使っている場合で物理演算だけを止めるので十分ならば、
Time.TimeScale=0f;と同じくらい手軽にできる方法ではないかなと思います。

Android版をビルドした際に詰まった話

先日、現在開発中のゲームをiOSでビルドしてみたのですが、
Android端末も購入したのでAndroid版もビルドしてみました。

Unity 2019以降はAndroid Studioなしでビルドできるということだったので、
早速ビルドしてみます。

...

f:id:jupiterthundar:20220405195314p:plain
\ テテーン! /
エラーだらけ〜!

ビルド自体も開始1〜2秒程度で失敗してしまう有様。
SDKが格納されているフォルダが表示されているので、
どうやらSDK周りに何か問題がありそうなので調べてみるものの、
解決に至らず...。

なお、よくある問題としては...
SDK自体が入っていない
・フォルダ名に全角が含まれている
・Product Nameに全角が含まれている
などのようです。

私はこれらの問題はクリアしていたので本当にお手上げでした...が、
ダメ元でエディターのバージョンを上げてみました。

すると、あんなに開始早々でこけていたビルドが通るじゃないですか。
無事、Android端末にインストールもできました。

ちなみに、
私がこれまで使用していたエディターのバージョンは、2020.3.2f1
これを2020.3.32f1に上げただけです。

2020.3.32f1は2020.xx.xxのLTSなので、
つまるところ「最新バージョンではない限り、LTSのバージョンを使え」
という知見を得ました。

よく、エディターのバージョンを上げると互換性がなくて
プロジェクト自体が正常に開けなくなるので、
それが怖くて最初に開発し始めた際に使ったバージョンのままにしていたのですよね...。
(実際、2020.xx.xxから2021.xx.xxに上げると、見事にセーフモード起動になってしまう)

が、よほどの理由がない限りは原則LTSとなっているバージョンで
開発した方が良さそうです。

UnityプロジェクトをiOSに無料でビルドする

f:id:jupiterthundar:20220323213214j:plain
自分が開発したプロジェクトが実機で動くのを見れるのは、感慨深い。

1年ちょっと前にもUnityプロジェクトをiOSへビルドしてみた際の備忘録記事
を書いたのですが、自分で読み返しても情報不足だったり、
一部変更が入ったりして多少手順が変化していたりしました。
更新分などを含め、改めて整理して手順をまとめてみます。
※2022/4/3:注意書きを追記しました。

jupiterthundar.hatenablog.com

前提

この記事でのビルド方法は
Developer会員(Apple Developer Program membership)の場合に
できるビルド方法とは異なり、
Deploygateを介したアプリの配布やTestFlightの利用ができません。
「とりあえず作成したUnityプロジェクトの挙動を実機で確認してみたい」
という場合に有効な方法です。
詳しくは公式ページをご確認ください。

項目名の表記は、それぞれのアプリケーションで使用されている用語に準拠します。
Xcodeなら英語、Unityは日本語にも対応していますが、
実験的な機能であるため英語準拠です。

なるべく正確な記載を心がけていますが、
私の知識不足などにより誤りが含まれている可能性があります。
誤りを発見された場合は、コメント等でご指摘いただければありがたいです(ぺこり)

目次

必要なもの

・Unityプロジェクト
Xcode
・USBケーブル
・実機(今回使用したものはiPhoneXs)

Xcode側の設定をする

今回初めてXcodeを使い始めたなどの理由でアカウント設定が済んでいない場合は、
Xcodeを起動しFile > Preferences > AccountsタブからApple IDを追加しましょう。

 

証明書を作成する

Apple IDの追加が完了したら、証明書を発行します。
Xcodeから実機にビルドする際に必要になるものです。f:id:jupiterthundar:20220318191120p:plain
左下の+をクリックするとApple Developmentが出てくるので、これを選択します。
以前は他にもいくつか選択肢があったのですが、
Ver13.3時点では選択肢が上記の1つのみとなっているようです。

作成した証明書は「キーチェーンアクセス」から確認することができます。

Unity側の設定

Unity側の設定で注意しなければならないのは
「Bundle Identifer」、「Signing Team ID」(下画像の赤丸の項目)でしょう。
ちょっと複雑なので、それぞれ分けて説明します。

まずはFile > Build Settings > Player Settings... > Other Settings を開きましょう。f:id:jupiterthundar:20220323173816p:plain

Bundle Identifer

Bundle Identiferは、デフォルトではPlayer Settings画面上部にある
「Company Name」欄で入力されたものが反映されています。
f:id:jupiterthundar:20220323174558p:plain
何も入力されていない場合は「com.DefaultCompany.」が入力されています。
Company Nameに任意の名称を入れた場合は、
Bundle Identiferが「com.任意の名称.」となります。

例えばCompany Nameに「KamiokaNoChiraura」と入れたとすると、
Bundle Identiferは「com.KamiokaNoChiraura.」が自動的に入力されます。

Company Nameに関する注意(2022/4/3追記)

初期値のDefaultCompanyでビルドすることはできません。
「違う名前を入れてください」という旨のダイアログが表示されるので、
自分にとって分かりやすい任意の名前をつけましょう。


基本的に必要のない設定とは思いますが、
もしCompany Nameと別の名称にしたい場合は、
Bundle Identiferの上にある
「Override Default Bundle Identifer」にチェックを入れましょう。
チェックを入れると、グレーアウトしていた直下のBundle Identiferの項目を
編集することができるようになります。
f:id:jupiterthundar:20220323175108p:plain

Bundle Identiferは、下記の注意項目に気をつけさえすればどんな名前でも問題ありません。分かりやすい名称がいいでしょう。

Bundle Identiferに関する注意

英数字(A-Z、a-z、0-9)、ハイフン(-)、ピリオド(.)のみで構成しなければなりません。
・また、_(アンダーバー)は使用不可です。

Signing Team ID

f:id:jupiterthundar:20220323194129p:plain
Signing Team IDには、先ほど作成した証明書に記載されたものを入力します。
キーチェーンアクセスを起動し、ログインの中の証明書タブを開くと、
先ほど作成したApple Development~という名前で始まる証明書があります。
この証明書をダブルクリックすると詳細を確認できるので、
その中の「部署」という項目を確認します。

f:id:jupiterthundar:20220323195405p:plain
これがUnity上のPlayer Settingsの「Signing TeamID」に入力すべきIDです。
あとは「Automatically Sign」にもチェックを入れれば、Unity側の設定は完了です。
f:id:jupiterthundar:20220323195834p:plain

上記設定が完了したらビルド設定画面に戻り、
右下の「Build and Run」をクリックします。
Xcode向けのプロジェクトのビルド完了後、XcodeiOS向けにビルドしてくれます。

ビルドが開始されると何度かパスワードを要求されますが、
これは自身のPCのアカウントのパスワードを入れればOKです。

iOS側の許可

ビルドと実行は自動的に行なってくれるのですが、iOS側にインストールする際、
エラーとなる場合があります。
これは、開発用証明書がiOS側で疑わしいもの扱いされるために起こるのですが、
iOSの設定画面から解消することができます。

iOSの設定 > 一般 > VPNとデバイス管理 に、
デベロッパAPP」という項目があり、
その中に先ほど発行した証明書入っているリストがあるため、これをタップします。
(神岡はダークモード大好きなので、真っ黒画面です)
f:id:jupiterthundar:20220323211243p:plain
リストの中に入ると証明書のファイル名があり、
これをタップすると確認ダイアログが表示されるので、「信頼」をタップします。
f:id:jupiterthundar:20220323211512p:plain
赤丸で囲った部分をタップして、

f:id:jupiterthundar:20220323211559p:plain
「信頼」をタップします。

これでインストールやアプリの起動が問題なく行えるようになります。

証明書に関する注意(2022/4/3追記)

1週間(7日)程度で証明書の有効期限が切れてしまうようで、
端末側で許可した証明書は消滅してしまいます。
アプリ自体は端末に残るのですが、証明書がないため起動できません。
この場合は再度インストールし直しましょう。

その他トラブルシューティングっぽいなにか

Legacy Build System に関するエラー

Xcodeでビルド中、エラーが発生しビルドが中断されることがあります。
エラーの内容は画面左のBuildtimeから確認することができます。
黄色い警告アイコンについては無視してもビルドに影響はありません。
(想定内のエラーかどうかは確認しておいた方が無難ですが)
よく出るエラーとしては、
「The Legacy Build System will be removed in a future releases.~」というものです。
UnityからXcode経由でビルドする際に必ずと言ってもいいくらい発生するといいますか、
デフォルトでこの設定になっているようです。

File > Project SettingsのBuild Systemを確認すると、
「Legacy Bulid System(Deprecated)」で設定されているはずです。
これをクリックするとプルダウンメニューが表示されるため、
「New Build System(Default)」を選択し、右下の「Done」をクリックすると、
エラーが解消されます。
(Defaultのくせにdefaultで設定されていない理由は分かりません...)

私も調べてみましたが、
都度変更して対応されている方が多いので事前回避できないようです。
どなたかご存知の方がいらしたらコメント等残していただけると、
とてもありがたいです(土下座)

Xcode上で中断されたビルドを再開したい

エラーへの対処した後、自動的にビルド再開してくれません。
画面左上に▶︎アイコンがあるので、これをクリックすればビルドを再開してくれます。
基本的なことだとは思うのですが、
私が詰まってしばらく悩んだ箇所なので記載しておきます。

参考記事など

今回も下記ブログを参考にさせていただきました。
いつもお世話になっております。(ぺこり)

nekonenene.hatenablog.com

あと、バンドルID(Bundle identifier)について
分かりやすい記事もありましたので貼っておきます。

qiita.com

 

今回は以上です。
私の情報が更新された場合などは、この記事も随時更新します。
誤りのほか、「ここが分かりづらいんじゃ〜」ということがありましたら、
お気軽にコメントをお寄せください。
ただ、乱暴な言い方はやめてください。チキンメンタルが崩壊しますorz

2021年を振り返る

今年も振り返ってみます。
去年と同じく四半期毎にまとめてみました。

 

  • 1月〜3月
    • Unity1weekで「まりもシミュレーター」をリリース
    • 帯状疱疹になった
  • 4月〜6月
    • かなりヘビーな期間
    • デッサン教室に通い始めた
  • 7月〜9月
    • そらとぶメンダコの開発を始める
    • AXNミステリーを契約した
  • 10〜12月
  • さいごに
続きを読む