【Unity】マルチタッチの開発に役立つ Unity Remote
ピンチイン、ピンチアウトで拡大縮小する処理を Unity で実装する際に、いちいちビルドして実機に転送して確認だと開発効率が悪いので Unity Remote を使ってみたのですが、結構使えたので導入手順を記載しておきます。
Unity Remote を使えば、Unity Editor 上の画面とデバイスの画面が同期されるので、ソースコードを修正したらデバイスですぐに確認することができます。マルチタッチだけではなく、加速度やジャイロなどの端末固有の入力処理を開発するときに使えそうです。
導入手順(思ったよりも簡単でした)
1. iOSの場合、App Storeから Unity Remote 5 をインストールする
2. PC と 端末 を ケーブルで接続する
3. Unity の メニューから Editor > Project Settings > Editor を選択する
4. Editor Settings のインスペクタで、Unity Remote の Device を 接続した端末に変更する
5. 端末にインストールした Unity Remote アプリを起動する
6. Unity の再生ボタンを押す
注意点
Unity Remote は便利だったのですが、マルチタッチの場合に TouchPhase.Ended の入力が取れないようです。
TouchPhase で 判定しないように書くこともできるみたいですが、今からそのために入力処理を書き換えるのは避けたかったので、最悪、End(手を離した)イベントが受け取れなくても致命的なエラーにならないようにすることで対処しました。
Unity3D:タップ操作の監視(領域指定付き) - devlog [naru design]
参考記事
【Unity】3Dモデルにシェーダーでアウトラインをつける(失敗編)
キャラクターと背景の色が同系色だと見にくいので、白猫プロジェクトみたいに3Dキャラクターの周りを線で囲みたいと思い、やりかたを調べてみました。
トゥーンシェーダー
最初に行き着いたのが、トゥーンシェーダー。
Unity 付属のシェーダーにアウトラインを付けるトゥーンシェーダー(Basic Outline)があるので、試してみました。
1. Assets > Import Package > Effects を実行
2. キャラクター の Material に Toon > Basic Outline を適用
実行した結果(左がBEFORE、右がAFTER)がこちら
=>
髪の毛が全部1色で塗りつぶされちゃってるし、アウトラインもブツブツしてて綺麗に出てない!ソウジャナイヨー!
ステンシルバッファ
次に試したのが、ステンシルバッファを使ったアウトライン表現。
自分でシェーダーを書かなくてはいけないらしい(シェーダー書いたことない)。とりあえずは、新規に作成した適当なシェーダーを適用してみます...
- 任意の場所で、右クリック > Create > Shader > Standard Surface Shader(ファイル名は、ここでは CharacterShader にしました)
- キャラクターの Material の Shader で Custom > CharacterShader を選択
結果はこちら(左がBEFORE、右がAFTER)
=>
とりあえず、新規シェーダーを適用するところまでは試せましたが...ん?なんか暗くない?ん?気のせいじゃないですよね?
もともとキャラクターは Mobile/Diffuse のシェーダーを適用してたのに、別のシェーダーに置き換わったので見た目が変わってしまったんですね、きっと。ということは、Mobile/Diffuse のコードをベースにアウトラインの修正を加えればいいのかな。
てっとり早くシェーダーのコードだけ欲しかったので、Unity内蔵シェーダーのソースコードをのせてくれている、この記事はありがたいです。
Mobile/Diffuse のソースコードを、先ほど新規作成したシェーダーにコピペしたら、とりあえず元に戻りました。そこから、悪戦苦闘すること数時間... こんな感じのシェーダーを書いて試したところ...
Shader "Custom/CharacterShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Outline ("Outline Length", Range(0.0, 10.0)) = 0.1
_OutlineColor ("Outline Color", Color) = (1, 1, 1, 1.0)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 150
Stencil {
Ref 128
Comp always
Pass replace
}
CGPROGRAM
#pragma surface surf Lambert noforwardadd
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
Pass {
Stencil {
Ref 128
Comp NotEqual
}
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float _Outline;
float4 _OutlineColor;
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : SV_POSITION;
};
v2f vert(appdata v) {
v2f o;
float4 vert = v.vertex;
vert.xyz += v.normal * _Outline;
o.pos = mul(UNITY_MATRIX_MVP, vert);
return o;
}
half4 frag(v2f i) : COLOR {
return _OutlineColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
結果はこちら(左がBEFORE、右がAFTER)
=>
斜めはわりとキャラを囲めてるのに、正面向いた時に横の部分のアウトラインが消えてる... うううううう、なんでやー。誰か助けてください(涙
長くなったので一旦ここまでで... 成功したら、記事の続き書きます...
参考記事
Unity のアプリを TestFlight で配信する(iOS編)
ゲームがある程度動くようになったので、自分以外の人(特に非エンジニア)にも遊んでもらうために、TestFlight で 開発途中のゲームを特定のメンバーにだけ配信することにしました。iOS の場合、配信までの手続きが多くて大変だったのでまとめておきます。全体の流れは、以下の記事が参考になりました。
1. iTunes Connect で 新規 App の作成
iTunes Connect のWebページ(https://itunesconnect.apple.com/)を開いて、新規Appを作成します。このままリリースする訳ではないので、中身の情報は仮でいいと思いますが、バンドルIDは、ビルドをアップロードしてしまうと変更できないので、確定させておいたほうがいいかもしれません。
- iTunes Connect を開く(https://itunesconnect.apple.com/)
- マイ App > 左上の+ボタン > 新規 App で App を作成
2. テストユーザーの追加
事前に招待するテスターのメールアドレス(App Store の アカウントに使用しているメールアドレス)を聞いておきましょう。
- iTunes Connect を開く(https://itunesconnect.apple.com/)
- ユーザと役割(マイ App ではないので注意)> iTunes Connect ユーザ > +ボタン で 招待するユーザ情報と権限を設定(ひとまず権限はDeveloperに設定)
- テストユーザの登録が完了すると、招待メールが送信されるのでテスターが承認してくれるまで待つ
3. Unity でビルド
Unityでビルドを実行し、iOS用のプロジェクトを出力します。
- Unity を起動後、File > Build Settings を開く
- ビルド前に Platform を iOS に変更し、Development Build にチェックをつけておく
- ビルド前に Edit > Project Settings > Player で Inspector を開き、Other Settings > Identification > Bundle identifier が 先ほどの新規 App で設定した Bundle Id と一致しているか確認する
- File > Build Settings > Build を実行
4. Xode で Validate
iTunes Connect にビルドをアップロードする前に、Validate を実行してビルドにエラーがないか確認します。
- Unity ビルドで出力された Unity-iPhone.xcodeproj をダブルクリックして Xcode を起動
- Xcode のメニューから Product > Archive を実行
- (しばらく待ちます...)
- アーカイブが完了するとウィンドウが開くので、右側にある Validate ボタンを実行(誤ってウィンドウを閉じてしまった場合は、Xcode メニュー > Window > Organizer で開けます)
私の場合、Validate実行時に設定不足等でいくつかエラーが発生しました。詳細は後述(※1)します。
5. ビルドを iTunes Connect にアップロード
Xcode 経由でビルドを iTunes Connect にアップロードします。
私の場合、アイコンの設定が足りなくてアップロード時にエラーが発生しました。詳細は後述(※2)します。
6. iTunes Connect にアップロードしたビルドを Test Flight で配信する
iTunes Connect で 先ほどアップロードしたビルドを TestFlight で配信します。
- iTunes Connect を開く(https://itunesconnect.apple.com/)
- マイ App > 該当の App を選択 > ヘッダーの「TestFlight」を選択 > 左の「内部テスト」を選択 > 「テストするバージョンを選択」を実行
- ウィンドウ内に先ほどアップロードしたビルドが表示されているので選択
私の場合、アップロードに成功したはずなのに、ビルドが表示されなくて焦りました。調べてみると「待つしかない」とのことで、待ってみたら30分〜1時間ぐらいで表示されました。
※1. Validate 実行時に遭遇したエラー
1-1. Your session has expired. Please log in.
スクショ撮り忘れました... いろいろ調べたのですがよくわからず、何回か Validate 押してるうちに出なくなりました... 謎...
結局やらなかったのですが、Xcode > Preferences > Accounts で サインインしなおすと解消するって言ってる人もいますね。
2-2. Missing iOS Distribution signing identify for xxxxxx
for の後のxxxxxには、実際にはアカウント名が入ります。
解決方法ですが、この記事がわかりやすくて大変参考になりました。
2016年2月15日以降、Missing iOS Distribution Signing identity for XXX というエラーが出た場合の解決方法
私の場合、新しい証明書は入っていたので、古い期限切れの証明書を削除することで解消しました。
※2. Upload 実行時に遭遇したエラー
2-1. This action could not be completed. Try again.
これも、結局原因がよくわかりませんでした。ネットの調子が悪かったのか、iTunes Connect のサーバの調子が悪かったのか... 何回かアップロードしなおしたら、出なくなりました。
2-2. ERROR ITMS-90023: Missing required icon file. The bundle does not contain an app icon for iPad of exactly 167x167 pixels, in .png format.
これは、iOS9用のアイコン画像が足りなかったみたいなんです。
アイコンを追加するには、Xcode > Unity-iPhone > Images.xcassets > AppIcon を選択して、
167 x 167 の適当なアイコン画像を用意して、iPad Pro App iOS9 のところにドラッグ&ドロップすると追加されます(地味にどうやって追加するのかわからなくなっちゃって四苦八苦した挙句、ドラッグ&ドロップで追加できることに気づいた時には脱力しました...)
あとがき
久しぶりにビルドをあげたのですが、手順をすっかり忘れていたり、iOSのバージョンがあがったことでエラーになったりとなかなか大変でした。仕事から帰ってきて深夜に頑張って対応したのですが、ビルドアップ完了の連絡をしても、結局すぐにはインストールしてもらえなかったりするんですよね... あるある。
【Unity】uGUIのオブジェクトをタッチしているか判定する
実装方法
EventSystem.current.IsPointerOverGameObject ()
で判定できます。ただし、これだと実機ではうまくいきません。
EventSystem.current.IsPointerOverGameObject (fingerId)
実機の場合は、fingerIdも指定しないといけません。fingerId は Input#GetTouch で取得できる Touch オブジェクトのプロパティから取得できます。
マウス入力も端末でのタッチ入力も両方対応する場合は、引数なしと引数ありのメソッド両方を呼び出さないといけないようです。
いつ使用するのか
開発中のローグライクゲームの場合、基本的なキャラの操作は Input クラス の値を見て判断しています。マウスからの入力なら Input.GetMouseButtonDown (0) 、実機でのタッチ入力なら Input.GetTouch (0) を利用して、入力した位置を取得して処理しています。ただ、手前のレイヤーにある ボタンなどのUIは uGUI で実装しており、ボタンを押したなどの入力は uGUIのイベントシステムに任せています。
ユーザーからの入力を処理しているところが2ヶ所あるので、何も考えずに実装すると、レイヤーが重なっている箇所は、ボタンもキャラも両方反応してしまいます。
これを防ぐには、uGUIに対して入力した場合は、それ以外の入力処理を実行しないようにする必要があります。今回はマルチタッチは対応しないので、fingerIdを1つだけ受け取る、こんな感じのメソッドを用意することで対応しました。
private bool _IsPointerOverUGUIObject (int fingerId)
{
EventSystem eventSystem = EventSystem.current;
if (eventSystem != null)
{
// マウスでの判定
if (eventSystem.IsPointerOverGameObject ()) {
return true;
}
// タッチでの判定
if (eventSystem.IsPointerOverGameObject (fingerId)) {
return true;
}
}
return false;
}
追記: 実機でうまく動きません
UnityEditor上では上記の実装(IsPointOverGameObjectを使用する方法)でうまくいくのですが、実機(iPhone6s/iOS9.2)だと挙動が不安定でうまく動いてくれませんでした。試行錯誤したものの、結局よくわからず、手動でRayを飛ばして確認する方式に変更しました。
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = screenPosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
下記のスレッドを参考にさせてもらいました。
参考記事
GameObjectが重なっている時uGUIで配置したボタンだけタッチに反応させる [stepism@Unityメモ]
【進捗】WebPlayerのビルドが突然動かなくなる
開発が一区切りしたときにビルドをWebPlayerで公開していたのですが、何の修正が原因なのかわかりませんが、突然動かなくなっちゃいました。
開発途中のゲーム【WebPlayer版】(Safariじゃないと見れません)
起動はするんですが、フロアをタップしてもキャラが動かないという・・・同じソースコードをWebGLでビルドしたら動いたので謎は深まるばかり。
開発途中のゲーム【WebGL版】
WebGLのほうがビルドに時間がかかるし、ビルドの容量がWebPlayerの2倍くらいになるし、WebPlayerのほうが良かったんですけどね。
初めてWebGLでビルドしましたが、パフォーマンス悪くて、アニメーションがガクガクですね... うーん、なんとかしないと(泣
前回からの進捗
・クエストシステムの導入(ドラゴンエイジみたいなクエストシステム入れたくて)
・NPCの導入(宿屋)
・モンスターの特殊移動や特殊攻撃(倍速移動/ランダム移動/ゴールドに群がる/矢攻撃/分裂/盗む/逃げる/ワープなど)
・アイテムの追加実装(へんしんの杖/透明の杖/すばやさ草/疲労草/分裂の杖/出血の杖/諸刃の杖など)
・フッターや操作性などUI/UXの改善
集中力を高めるには
「気が付けば1ヶ月ほど更新していなかったですね」
このセリフ、ブログの書き出しの決まり文句になりつつあります・・・
ブログは更新してなかったのですが、開発は粛々と進めてました。と言いたいところですが、最近プライベートがトラブル続きで、正直この数週間何も手につかなかったです。個人でゲーム開発をするようになってから、どころか、社会人になってからこんなに何をやっても集中できなかったことは始めてで、危うくすべてに挫折しそうになりました。
今もあまり体調は良くないですし、モチベーションが高い訳じゃないのですが、仕事に個人作業に、無理矢理にでも集中力を上げていかないと、とにかく終わらないんですよね・・・終わらないとダラダラやってしまいさらに悪循環です。
これまで集中できなくて悩んだことがあまりなかったので、これを機に色々調べてみました。ネットには様々な方法がありましたが、私はどうも時間で区切るのは逆にストレスが溜まって、あまり好きではないんですよね。私が実践するとしたら、以下の3点が良いかなと思いました。
・「マルチタスク」より「シングルタスク」
余計なことは考えず、目の前のタスクだけに集中する。タスクに取り掛かっているときは、他の情報をなるべく遮断する。話しかけられたりしない静かな場所を確保し、ネットも切断する。
・小さな成果でやる気をつかむ
やる気が出ない時でも、少しでいいから始めてみる。簡単なこと、興味があることでいい。タスクに取り掛かり始めれば、徐々にやる気になり集中力が出てくる。逆に何も始めないと、いつまでも集中力不足を嘆き続けることになる。
・タスクを簡単にするか、タスクを減らすのに労力を割く
さぼっている訳ではないんですよ。タスクの消化に取り掛かる前に、タスクそのものの費用対効果が最大になることにも少しだけ労力を使うようにするということです。
複雑なタスクはできる限り細分化してシンプルなタスクにする。仕様が複雑なら仕様を簡単にできないか模索する。技術的に難しいことであれば、自分で調査するのは諦めて詳しい人に頼る。そもそもタスク自体を無くせないか考える。効果がほぼ同じなら、難しいことを簡単にしてから取り組んだ方が早く終わるはずで、タスクがサクサク終わっていくと、だんだん楽しくなってきて、気づくと集中しているはず・・・たぶん(汗
結局のところ、焦らず、無理をせず、過信せず、毎日継続して一定の成果を上げ続けることが大切ですよね。 というか、こんなこと調べてブログに書いてる暇があったら、さっさと開発を進めなさいという話もあったり、なかったり・・・
参考記事
Github でプライベートリポジトリへのコミットにも草を生やす
Github で 自分のプロフィールページを見ると、こんなグラフがありますよね?
GitHubのリポジトリに対して、commitやissuesの作成などを行うと、緑が増えていきます。これを contribution graph というらしいです。
エンジニアの中には、これを「草」と呼び、コミットなどの活動をすることを「草を生やす」と言っている人もいます(納得ですけどね)。毎日少しずつ草を生やして大きな芝生ができると達成感ありますよね。
ただ、今までのgithubの仕様だと、Private Repository への contributions に関しては、ログインした自分は見れるのですが、他のユーザーから見ることができませんでした。私もプライベートリポジトリ上で作業しているので、自分で見ると上の画像のようにそこそこ緑地化されているのですが、他のユーザーから見るとこんな感じの砂漠です。
ところが先日アナウンスがあり、プライベートプロジェクトへの貢献を他のユーザーに公開できるようになりました!素晴らしい。
公開の仕方は簡単。contribution graph の 「Contributions settings」を開いて、「Public and private contributions」を選択するだけです!
何事も日々の継続が大切ですよね? がんばって緑化運動を進めましょう〜。