2015年10月17日土曜日

オブジェクトのタグ名検索でハマったこと

Unityでオブジェクトのタグ名検索でちょっとハマったのでメモ。

結論からいうと、オブジェクトのタグ名検索があてにならない特定の状況&タイミング(?)があるので注意。
※ひょっとするとどこかに明記されてる(?)既知の仕様かもしれません。


■環境


Unity 5.1.1f1 personal (C#使用)
Windows7


■注意すべき状況&タイミングの概要


タグ付け済みの子オブジェクトを含む親オブジェクトのプレハブがあるとします。
そして既にシーン上にInitiate済みとします。

説明の便宜上オブジェクト名、タグ名は以下とします。
  • 親オブジェクト名:ObjectA
  • 子オブジェクト名:ObjectC (タグ名:TagObjectC)


問題(?)が起きる手順。
  1. タグ名(TagObjectC)で検索したものを GameObject型の変数に保存。
    ※特に問題なし。
     
  2. ※時間経過でフレームが進み、現在 n フレームとします。
     
  3. ObjectA を Destroyする。
    ※つまり子オブジェクト(ObjectC)も消えます。
     
  4. 同フレーム中にObjectAを再度Initiateする。
     
  5. 「1.」でタグ名(TagObjectC)検索&保存済みのGameObject型の変数の指すObjectCは既にDestroy済み。
    新たにタグ名(TagObjectC)で検索して保存しなおします。
    つまり「4.」で Initiate した ObjectA 内にて検索&結果が返ることを期待しています。
     
  6. ※時間経過で次のフレームに進み、現在 n+1フレームとします。
     
  7. 前フレームでタグ名検索&保存しておいた GameObject型の変数にて ObjectCを参照してみます。
    この時、この変数 はいつのまにか勝手に null になっています。

ちょっとややこしいですが(;・∀・)

注意する点の要約は、

  1. 同フレーム中に同名のプレハブをシーン上でDestroy &  Initiate した。
    ※シーン中に当該プレハブの同時存在は1つ。
     
  2. さらに同フレーム中にてタグ名検索をかけた。
    ※新たにInitiateしたプレハブのオブジェクト内で検索HIT&結果取得することを期待。
     
  3. Destroyした方のタグの付いたオブジェクトを返している&同フレーム中は null ではない。
     
  4. 次のフレームでいつのまにか null になっているので「アレっ?」となる。
    ※Destroy処理がタグ名の内部DB?Hash?にも反映された為?


多分、同フレーム中での実際のオブジェクトのDestroyの処理が行われるタイミング、タグ名とシーン上のオブジェクトの関連性更新などのタイミングの差異問題だと思うので「そういう仕様になっている」ような気がします。

※上記処理の確認はUpdate()内で行っています。FixedUpdate内では未確認。こっちだとひょっとするとDestroy後タグ名の参照先更新(?)がされるかも?


■回避策


今回の状況&タイミングにおいては、子オブジェクト名で検索をするように実装すれば回避できています。
つまりオブジェクト名検索ではさすがに同フレーム中でもInitiateした最新の方をみてくれるようです。

なので今回のケースではタグ名検索を使わなければハマらなかったわけですが(汗。

前々からタグ名検索は便利そうな反面「何かありそう」なモヤっとした雰囲気を感じていたのが少し納得できた感じです。



2015年8月3日月曜日

Shadow Projector活用サンプル~地面から離れると小さく消失する影~

Unity提供のアセット(Shadow Projector)で「丸い影」を落とすサンプル。

ただし上昇して地面から離れるほど影を小さくして消失させます。







サンプル

環境: Windows7x64。Unity5.1.1f1 personal。

プロジェクトのダウンロードはGitHubサイト右下 Download ZIP
https://github.com/maruton/Sample_ShadowProjector



概要

普通(?)にShadow Projectorを利用して「丸い影」を落としたのが下の図1。影を上から照射しています。

この場合、上昇していくと影は次第に大きくなります。
(ある程度の高さを超えると影は薄くなり見えなくなります)

図1


上昇していくと小さくなり、やがて消失する影を考えてみます。

図2は影を下から照射しています。
下方から照射しても床の裏側だけでなく、表側にも影がレンダリングされることを利用します。

図2



光の回折

現実世界で太陽光下(無限遠から平行に照射)のような状況にて、光の回折を考えた場合。
高度が上がるほどに太陽光は真下に回り込むようになります。

結果、上昇していくと影は徐々に小さくなりいずれ完全に消失します。
(電灯などの近接してる非並行な光では逆に影は大きくなったりするので図1の方が自然な感覚)

Unityで屋外フィールド上をキャラクタが上昇/下降するような場合、演出的にも影が小さくなることで高度が上がってる感が出しやすそうです。


とはいえ「誰も影なんかそこまで見てない」という意見が最も的確な気もしますが、


ちょっとやってみたくなったので ⊂⌒~⊃。Д。)⊃


と、強引な動機付けが済んだところで、以後簡単に補足説明。

※夏休みの自由研究に格子回折とかちょっと面白いかもしれません(´∀`)




使用するアセット

Shadow projectorのAssetはUnityに標準で提供されていますが、パッケージ名がUnity5で変わったようです。

Shadow projectorを含むAssetは上部メニューから、

Assets > Import Package > Effects

で、インポート。



Shadow projectorの配置

ここではCubeをキャラクタに見立てて配置しています(オブジェクト名Character)。

インポートしたAssetに含まれる BlobShadowProjector をCharacterオブジェクトにドラッグ&ドロップして子Objectにします。



BlobShadowProjector が下から影を照射するように配置。



Floorオブジェクトに影の照射はしつつもCharacterオブジェクトには照射したくないのでレイヤで調整します。

ここでは簡単に、
  • レイヤ名Characterを新しく作り、Characterオブジェクトをそのレイヤに設定。
  • 子オブジェクト BlobShadowProjector はDefaultレイヤのまま。
さらに 子オブジェクトBlobShadowProjector を選択、Inspector内の Ignore Layersに レイヤ名 Character を指定。

これで レイヤ名 Character に配置したCharacterオブジェクトには影が照射されなくなります。


この状態で床下、床上を見ると以下のようになります。

影は床の表裏ともにレンダリングされているので、床上でも影が見えます。

ここでオブジェクトCharacterを上に移動していくと影が小さくなり、BlobShadowProjector が床よりも上に出た時点で影は消失するようになります。


この辺の微調整は BlobShadowProjector の Inspector内の Field Of View で行います。
他、照射の距離範囲はNear Clip Plane、Far Clip Plane等々。




ここまでで一応、上昇すると影が小さくなりやがて消失する影が簡単にできます。

しかし、Characterオブジェクトが傾むく動作をすると、子オブジェクトのBlobShadowProjector はぶら下がった振り子のような挙動になる為、真下に影が照射されません。

サンプルプロジェクトではこの辺も対応しています。



補足

  • 地面から遠くなるにつれて影の輪郭がハッキリしてしまう
    本当は徐々にぼやけていくべきですが、しくみの都合上仕様です。
    がんばってシェーダーをいじればぼかすこともできるかもしれませんが、軽量低負荷簡単手抜きという目的もあるので割り切ってしまう方が得策と思います。
    シーン上での見せ方とか、高速移動してるとどうせわからないとか、ごまかす手段はいろいろありますタブン|∀゚)
     
  • キャラクタ本体のScaleに注意
    親Objectであるキャラクタ本体と BlobShadowProjector  のScale値が等しくない場合、子オブジェクトの距離指定時に相互Scaleの比率で倍率がかかります。詳細は割愛しますがUnity4頃からこうなっているので仕様なようです。
    距離に倍率をかけて補正すれば良いだけですが無駄な演算が増えるのでScaleは共に <1,1,1>にした方が無難です。
     
  • 本体キャラが縦長の場合
    影そのものはBlobShadowProjector のInspector内のAspect Ratioで縦横比を簡単に変更できます。問題はキャラ本体の向きに追従させなければならない点ですが、サンプルでは軽量化の為考慮してません。
    BlobShadowProjector の向きをキャラ本体の向きに合わせるように制御すれば可能だと思います。
     
  • 本体キャラがロール/ピッチ変動する場合
    サンプルのiTween移動のようにロール/ピッチ角が変動すれば影の縦横比も変動すべきですが、これも軽量化の為に常に丸影です。
    まじめにAspect Ratioを動的に変えてやればそれっぽい楕円な影が落とせそうです。(でもロール/ピッチの両方はちょっと面倒そうです。Field Of Viewも動的にいじらないとダメかも?)


    しかし所詮「丸影」なのでそこまでする必要性は要検討です。

結局なんちゃって影なので、凝るのはほどほどにしておくのが良さそうです(´∀`)


2015年7月27日月曜日

クッキーで自分のページビューを追跡しないようにする

急にBloggerの管理ページから「自分のページビューを追跡しない」が動かなくなったので対策をメモ。
結論からいうとこの問題そのものは解決できず。しかし別な方法で自分のBloggerブログでのPVをカウントしないようにして対応。

状況


Bloggerの管理ページのトップから「詳細な統計情報」をクリックすると「自分のページビューを追跡しない」のリンクがある。




前はこれをクリックで普通に使えていたのに、なぜか今は、


とエラーらしきダイアログが出てうまくいかない。

統計データの取得中にエラー・・・と言われてもデータはGoogle様の管理下ですよね・・・;。

ページのリロードしても状況変わらずで解決しない。(-ω-;)ウーン?


調査&検討

結局この問題の原因はわからず、エラーダイアログが出てしまう件は解決せず。

最近やったことといえば、CSSのテスト用にBloggerでBlogを新たに作成。用が済んだので削除くらい・・・。
これが関係するのかは全く不明。





と、いうことでエラーダイアログが出る件は「またGoole側で何かしているのか・・・」程度に思って気にしないことに  ・⌒ヾ(*´_`)ポイ


しかしいろいろ調べてみると「自分のページビューを追跡しない」はそもそもクッキーをブラウザに登録しているだけな単純なものらしい。

つまり自分でブラウザにクッキーを登録すれば、目的の「自分のページビューを追跡しない」はできるはず。




クッキーをブラウザに登録

普段FirefoxとChromeなど色々使い分けていますが、ここではFirefoxで登録してみます。
※Chromeは検索するとわりと記事が多いのですぐ見つかると思います。

いろいろな方法がある中でアドオンを使うのが比較的楽な感じ。
※FirefoxはSQLiteでクッキーを管理しているらしくソコを直接いじる手もありますがいろいろ面倒すぎでした。ブラウザ実行中はクッキーのDBをいじる作業もできないし。





つまり考え方としては(どのブラウザでも)
  • クッキーを手動登録できるアドオンをインストールして、PVカウントさせないクッキーを手動登録すれば良い
という話ですね。


アドオンインストール


Firefoxのアドオンで Firebug というものを使ってみました。
(ちなみにChromeでは EditThisCookie というアドオンが良く使われているようです。登録するクッキー情報は結局同じなのでアドオンの使い方の差異ですね)


CTRL+SHIFT+Aを押してアドオン画面を開き、アドオン入手タブへ。
右上の検索欄で Firebugで検索&インストール。


 インストールすると右上に虫のマークが追加されます。







 クッキー登録


PVカウントをさせたくない自分のBloggerサイトのトップページをFirefoxで開きます。

右上の虫マークをクリック。

画面下方に以下のようなウィンドウが出てきます。
右上の「Cookie」をクリックし、さらにプルダウンメニューから「Cookieを作成」クリック。


登録ダイアログがポップアップするのでここでクッキーの情報を入力。
(名前とホスト欄は特に間違えないように注意。他欄も全部入力します)



登録するクッキーの情報は、

  • 名前: _ns   ※半角文字。nsの前のアンダーバーを忘れずに。
    ※このクッキーがあるとGoogle BloggerはPVカウントしない仕様なようです。
  • ホスト: example.blogspot.jp  ※半角文字
    ※PVをカウントしたくない、自分のブログURL。
  • パス: /  ※半角文字
    ※ブログを丸ごとPVカウントしたくないので / (ルート)
  • 有効期限: 年月日時分秒
    ※クッキーの有効期間。1年以上先の日付など長めにしておくといいかも。有効期間を過ぎるとクッキーの再設定要。
  • 値: 2  ※半角文字
    ※なぜ2なのかは不明。Googleの仕様?
  • その他のチェックボックス類
    全てチェック無し。
入力後、OKを押して登録。

これでホストで登録したURL(自分のブログ)でPVカウントされなくなるはず。

とりあえずこれでしばらく様子を見ています。

追記:
上では主に自分が日本国内でアクセスする想定で example.blogspot.jp を登録しています、国別リダイレクトで .jp に飛ばされるので。
念を入れるならば同様の手順で example.blogspot.com のように .com のURLも登録しておくと良いかもしれません。
またURLは自分のブログに限らずどこでも設定できてしまうので入力ミスしないように注意です。


Googleにログインしてる時くらいは全自動でPV未カウントにする機能があるといいなぁ・・・。と、ふと思ったり(ボソ。

2015年7月6日月曜日

艦これで通信エラーを回避する方法

艦これで通信エラーを「ある原因においては」確実に回避できることがわかったのでメモ。

(キーワード「艦これ」で当ブログに辿り着いてる方も結構多いようなので、有益かも?と思いメモです)


状況

  • インターネット接続は問題ない。他のサイトは問題なく閲覧できる。
  • 艦これサーバは落ちていないしメンテ中でもない。
  • ログイン画面はすんなり開ける。しかしログイン後の母港画面に辿りつけずに「通信エラー」になる。
  • 特に艦これサーバの混雑で「通信エラー」になっている様子でもない。
  •  キャッシュクリアしても直らない。
  • とにかく自分だけ?ダメなの?そうなの?つД`) タスケテ;




原因と解決策

PCの時計がJST(日本時間)で現時刻を示していないと母港画面手前で「通信エラー」となってしまうようです。

今のところ再現性が100%なので海外アクセス対策(?)のひとつとして艦これサーバ側がチェックしているように思えます。

つまりPCの時計がずれていないか確認しましょう。

もしずれていたらPCの時計を日本時間で現時刻に合わせてみましょう。

他の要因がなければこれでアッサリ母港まで辿り付けます。

ちなみに時計設定時のズレ分はプラスマイナス9分以内にすること。その根拠は後述。
※普通にあわせればまず問題なし。



艦これが許容する時刻のズレ分

「時計を合わせましょう」だけではあまり面白くない(?)ので、

艦これの要求するPC時刻精度

はどれくらいなのかを軽く調べてみました。


毎回キャッシュクリア&PC時刻を意図的にずらしてテスト。ずらし分は秒単位で管理。

(電波時計を目視にて確認、ずらし分加算して手動でPC時刻設定。目視&手動の為1~2秒程度の誤差はありえます)

  • 現時刻 -10分:通信エラー
  • 現時刻  -9分:問題なし
  • 現時刻  +9分:問題なし
  • 現時刻 +10分:問題なし
  • 現時刻 +11分:通信エラー
  • 現時刻 +13分:通信エラー
  • 現時刻 +15分:通信エラー
  • 現時刻 +20分:通信エラー

といった結果から、おおむねプラスマイナス10分付近を判定の基準にしていることが伺えます。

+10分がOKなのに-10がダメなのは目視&手動テストによる誤差か、艦これサーバ側のプログラムの条件判定が >(Grater) か>=(Greater equal)か等の微細なものによる可能性もあるかもしれません。


ということで、この結果から、

PC時刻はプラスマイナス誤差9分以下程度なら大丈夫ぽい

ということがなんとなくわかります。


※将来的にもこの通りかはわかりません。サーバ側が変更される可能性もありえます。
また、本気で海外アクセスを排除するなら他にいくらでもチェックできる箇所はありえるので。




独り言

許容9分として、月差換算(30日)すると1日18秒まで許容となります。

クォーツ腕時計の精度なら余裕でクリアですが、最近のIT機器(特に安価なもの)では微妙に油断できないかもしれません。

PCのRTCはX'talの品質精度や温度、RTCの補正機能などにも関係しますが昔みた時は月差1分以下程度だった記憶。
未確認ですが最近の安価なノートブックあたりは私的には少し気になります。

一部の携帯電話などは一ヶ月で普通に5分以上ズレるものもありました。
通信がオンラインの場合は適時ネットワーク経由で時計補正しているのでズレにくい。
通信オフラインの場合は機器内蔵の時計精度に依存します。部品構成によるので一概には言えませんが。コストをケチりだすとCPU内蔵RC発振とか安価なセラロックを使うということもありえます。これはクォーツ腕時計=X'tal使用よりも低精度です)

昨今はオンライン時刻補正(NTPサーバで時刻同期)があたりまえになってきているので、より部品のコストダウン=低精度化しているような気もします。

つまり1日~1週間に1回は補正する前提。しばらく電源を入れていないPC/携帯や、オフライン運用併用で運悪く時刻同期できない期間が長かった場合はかなり時計がズレているということになります。


NTPサーバによるオンライン同期も実は「絶対」とは言い切れず、たまにサーバが落ちてたりすることもあり実は同期できていないなんてことも。
NTPサーバは比較的実害が低いと見られている(?)のか運用優先が低そうな気も(?)。
(ソフトのリビジョン管理等ではタイムスタンプは結構大事ですが)


過去にはNTPサーバそのものの時刻が(多分管理者の国地域の)ローカル時刻を指しておりタイムゾーン指定されていないのか、その分GMT時刻がズレる・・・なんてこともありました。
(有名企業のNTPサーバでもたまにおかしいこともあったので安心はできません)





たま~にPC(携帯)時刻を見て「だいたい合ってるな~」程度に確認しておくと良いかもしれません(´∀`)





2015年7月1日水曜日

Kindle FireからAmazonアプリストアが開けない場合の対策

急にKindleからアプリストアが開けなくなった問題を解決してみたメモ。

Android機では「またか」と思うけど、Kindle機だとちょっと焦る不思議。

状況

使用機種はKindle FireHD8.9。
  • Amazonアプリストアがある日突然開けなくなった。
  • WiFi~ネット接続は問題無し。
    ブラウザでネットは閲覧可能(Firefox/Chromeで確認)。
  • 何かしらアクセス不能に陥ってる様子。
    Amazonアプリストアのサイトにアクセスできていないような雰囲気?。
    (DNS解決失敗?サイトが落ちているわけはなさそう)




対策

結果的にアプリストアを担う(らしい?)アプリのキャッシュ&保持データをクリアして解決。

以下手順。
※Kindle FireHD8.9以外だとメニューの類が違うかもしれませんが、探せばどこかに同じような項目があると思います。
※作業中のバッテリ切れに注意。USB給電して作業が安心。



ホームで画面上部から下へスワイプ。
メニューが出るので右上の「その他」をタップ。



「設定」画面になる。「アプリケーション」をタップ。


「アプリケーション」画面になる。「インストール済みのアプリ」をタップ。


「インストール済みのアプリ」画面になる。フィルター:欄を「すべてのアプリケーション」にする。
アプリ一覧で下へ見ていき「Apps」を見つける。
2つあるのでサイズの大きいほう(下図では27.61MB)をタップ。


「データ削除」をタップ。
※すぐ下に「キャッシュ削除」も見えるが、「データ削除」でキャッシュも消える。


確認のダイアログが出るので、「OK」で削除。



次にホーム画面に戻り、本体電源ボタンを押下し続ける
シャットダウンしますか?とのダイアログがでてもそのまま押しっぱなしを継続

10秒位押下し続けると画面が消えるので、その後電源ボタンを離す
再度電源ボタンを押して、電源を入れる(再起動)。


ホーム画面の上部メニューから「アプリ」>「ストア」でAmzonアプリストアに行ってみる。

しばらく画面が暗転のままの場合があるかもしれないので焦らず待つ。結構長いです(10秒位?)。
※多分クラウド~端末アプリの情報同期とかKindle特有の高解像度アイコンをダウンロードしてると思われます。


アプリストア画面がでてくれば成功です。


※ワンボタンでクリーン化するアプリかメニューでも提供されていれば便利かも。 一般の方にこんな面倒な操作はさせないのが本来は良いはずで・・・。Kindleは実機からサポート要求するとコールバックで即電話かかってくるのはすごいのですけどね 。問題がそれで解決できれば・・・。



非Kindle機だとGooglePlayからインストールできるAmazonApp(アプリ購入/クラウド同期)もありますが、これもこれでたまにおかしくなることがあるようで・・・。