FC2ブログ
就活で精神攻撃を与えらた結果、こうなりゃ一人でやってやんよ!という理由でAndroidアプリの開発をしてるぼくの活動記録です。お金に成るクオリティにしたいのです^p^
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
unity4.3でアニメーションイベントできるようになったよ!
2Dの作成にも対応したよ!!
・・・でも実機でのアプリサイズが大幅にあがるけどな!!!

そんなお話。


私だけに起きているのか、この現象についてググっても有用な情報が得られない。
androidでだけそういうことが起きているのだろうか?
では、どういうことが起きているか記そう。
解決策はまだ見当たらない。

【問題】
unity4.3以降でandroidアプリをビルドするとアプリサイズがかなり大きくなる。
新規プロジェクトから作成した状態でも20M以上のサイズ。
ただし、PC上では8Mとなっている。

全く訳が分からないよ。
参考になるサイトが引っかからないため、解決にはほど遠い。
皆2Dガーとかアニメーションイベントガーとか言ってるだけでサイズについて
なにか言をとる人は見当たらない・・・
これは困ったんがぁ。

幸い4.3以降からの機能は使っていないからしばらく4.2あたりで様子見するかね。
アップグレードしてしまったからダウングレードして動作チェックが必要になると思うとめんどうだけど
しょうがない。

しかし、だれもアプリサイズについて言及しないという事は
案外アプリのサイズって重要視されていないのだろうか?
それともこの現象は自分にだけ起きた特殊なケースなのだろうか・・・?

なんだか寒さのせいか、指も腫れて痛いし痒い
かゆい
かゆ・・・うま・・・。
スポンサーサイト
そろそろ新作も形になってきた。
というかネットワークの実装をしないのであればもう出せるけど
今作はちょっとネット系をもう少し深く理解したいので、後少し踏み込んだところまでつくってみようか。
当初の予定より少し遅れるがまぁ今月中にはリリースできるな。

そしてそんな中、実機での動作確認で問題発生。
なんとエディター上での動作ではちゃんSEが鳴るのに実機では鳴らないという事態
しかも一部のSEのみである。

無事解決したのでメモに残したい。

【問題】
エディター上で鳴るSEが実機で鳴らない。

【解決】
audioClipをオブジェクトとしてリソースに格納し、オブジェクトのaudioソースからクリップを取得する事で解決できた。

今回の問題はどうやらリソースに音源を直においていたのがマズかったと思われる。
まず、一部のSEが鳴らないという現象。
どういうSEが鳴らないのか?
 →リソースから取得するデータのみ鳴らない。
  インスペクタに直接ぶっこんだSEは問題なく再生可能
という状況から、リソースの取得時にうまく読め込めなかったのだと推察。

その他Audioクリップを保持するクラスから参照して、音を鳴らす事もできていたので
この事からスマホ(android)でコンパイル時?もしくはスマホの仕様??によりリソースから
音声データを直接生成できないのだと思い、空のオブジェクトを配置してaudioソースをアタッチして
そのaudioClipに鳴らしたい音声データを入れる。(音声データをヒエラルキーにドロップすることでも作れる)
このオブジェクトをリソースフォルダに入れて生成し、生成したオブジェクトのaudioにアクセスして
Clipを入手
する。
これで無事に実機で音を鳴らす事ができた。


audioデータやマテリアルなどヒエラルキーに直接生成できない(形を持たない)ものはリソースから直接取り込む事はできないのかもしれない。エディター上ではできるんだけどね。

まぁ何はともあれ今回の事は勉強になった。
今後はaudio管理も念頭に設計しなくては・・・やはりクラスとしてaudioデータを保持して
そこから取得して鳴らす方が楽なのかも。

うっし!nじゃこれからネットワークの実装に移りんす。
動いていたスクリプトにとある一文を挿入したらエラーが出た。
意味が分からないことにその文章に関してのエラーでなく
よその箇所がエラーとして検出されるのだ!!

意味が分からん!!と思って色々調べた結果、解決。
メモっておこう。

まずエラー文だが、
Assets/〜/スクリプト名.js(74,42): BCE0070: Definition of 'スクリプト名.Start()' depends on 'スクリプト名.メソッド名()' whose type could not be resolved because of a cycle. Explicitly declare the type of either one to break the cycle.
とまぁこんな感じ。

Assets/〜/スクリプト名.js(74,42)で問題あり、とのことだけど
別のスクリプトファイルでメソッドを作成したら上記のように全然違う場所でエラーが起きた。
試しに作成したメソッドの内容をコメントアウトすると普通に動く。
そしてコメントアウトを解除すると上記エラー。
バグか?と思いとりあえずグーグル先生にご助力願う。

どうやら追加した分のメソッド内容で
別のファイルのメソッドを実行→実行先のメソッドでさらに他所のファイルメソッドを実行
という事をしているのだがこれが原因っぽい。
再帰関係の処理とかでもおこるっぽいけど、再帰処理なんてしらねーよあばばば^p^

解決策だが以外に簡単に解決した。
実行先のメソッドでさらに他所のファイルメソッドを実行
赤字の部分の戻り値をIEnumeratorとすることでこのエラーは解消された。

そういえばC#ではyieldを使うところでIEnumeratorを戻り値としないといけないとかなんとか
それがとある条件でjsのほうでも必要となるのだろう。
今回のエラーは知らずのうちにその条件を満たすことで起きたエラーなのだ。

いや〜もっと知識を深めないとまずいな・・・
一応今回のことで無駄に情報収集する事ができたからよしとしよう。
有益な情報もぼちぼち得られたと思うし。

新作も土台が固まってきたし残りは主にキャラ制作。これがまた時間かかりそうだな。
遅くても12月上旬にはリリースして、また他に勉強+新作作りを行いたい。
photonを利用してのネットワーキング。
現在、チュートリアルやらなんやらをいろいろ見ているところ。
それで気がついたのもメモ。

チュートリアルを動かしたところ、アップデート内でマスターの移動処理しか書いてないのに
クライアント側で同期できてる
のを見かけた。
どういうことかと注意深く拝見すると、photonViewスクリプトがアタッチされたオブジェクトに秘密があった。

photonViewインスペクタのオブジェクトに直接オブジェクトをドロップするとトランスフォームが入力される。
そのときインスペクタ内容が
・Owner
・View ID
・Observer(UnityEngine.Transform)
・Observer option
・Serialization
の五つが表示され、この中のSerializationがポイント。
Serializationの内容にOnly PositionだったりRotationだったりScaleなどがあり
どうやらこれの設定でわざわざスクリプト内にOnPhotonSerializeViewを表記しなくても
指定した内容に従い自動で同期
してくれるっぽい。
ん〜なるへそ。
最初いたときはマスタークライアントであればクライアントの同期は勝手に行われるのかと思って混乱した。

ちなみにphotonViewインスペクタのObserverに同オブジェクト内のスクリプト(多分Photon.MonoBehaviourを継承したクラス)をドロップするとインスペクタ内容がSerializationの抜けた四つの項目になりObserverも()内がそのスクリプト名になる。
このときはちゃんとOnPhotonSerializeViewで同期処理を明記する必要があるんだろうね。

ふぃ〜ちかれた。
上の階の住民がごっつんごっつん五月蝿いお・・・何がおこったんだお・・・。
とにかくオンラインゲームが作りたい!
ということで行き着いた結果がphotonだ。
これのcloudサービスを使えばサーバってやつを自ら得ずともオンラインゲームが作れるとか作れないとか・・・

ということでものは試しに使ってみた。

結果。。。。

かなり簡単にオンライン系っぽくできる事がわかった!!
といってもチュートリアルを触っただけだから自分が実装できるかどうか…

とりあえず触ってみてわかって来た事をメモメモ。
思いついた順序で書き記す。

まずvoid OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
これはリスナーだろうという事がわかった。
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){
   if (stream.isWriting){
       stream.SendNext(transform.position);//"Encode" it, and send it
   }else {
       transform.position = (Vector3)stream.ReceiveNext();
   }
}
上記のように綴られ
stream.isWritingがtrueならtransform.positionを送信。
falseなら受信transform.positionに受信しているのだと思われ。
では、stream.isWritingとは何なのか?

おそらく、一番始めにアクセスしたユーザーのことだと思う。俗にいうマスターってやつかな。
一番はじめにサーバーにアクセスする事でこのスクリプトをアタッチしたオブジェクトの書き込み権限を持つものだと解釈。=stream.isWritingがtrue。
上に記したスクリプトの場合、マスターになったユーザ(stream.isWriting==true)がオブジェクトを移動させる事でOnPhotonSerializeViewが作動し(実際には動かさなくても作動しているが)現在のオブジェクトtransformをサーバーに書き込む。
その他の非マスターユーザ(stream.isWriting==false)はオブジェクトのtransformをサーバーから受信し反映させる。
その結果両者間でオブジェクトの位置が同期する。
といった所だろう。
追記:どうもphotonViewをアタッチしたとき、observedにスクリプトをドロップして同期の処理を行ったりするけど、そのスクリプト内にこのメソッドがないとエラーが出る。中身は空っぽでもいいのでOnPhotonSerializeView()は確実に記述しよう。RPCでの処理に頼って抜かしていたらエラーが出たのでメモ。

その2、RPC(remote procedure call)
翻訳すると遠隔呼び出しの手続き、って感じ。
こっちの指示でこのスクリプトがアタッチされた(必要があるのかないのか)よそのオブジェクトに命令する。
void Update(){
(省略)
   if (Vector3.Distance(transform.position, lastPosition) >= 0.01f){
      lastPosition = transform.position;

      photonView.RPC("SetPosition", PhotonTargets.Others, transform.position);
    }
}

[RPC]
void SetPosition(Vector3 newPos){
   transform.position = newPos;
}

上記のupdate内で使用されてる
photonView.RPC("SetPosition", PhotonTargets.Others, transform.position);

[RPC]
void SetPosition(Vector3 newPos){
   transform.position = newPos;
}
を呼び出している。多分[RPC]でマーキングする必要あり。

この時photonView.RPC()は何をしているか?
まず第一引数"SetPosition"はこのスクリプト内のvoid SetPosition(Vector3 newPos)を作動させるのに必要。
次に第二引数"PhotonTargets.Others"、これは誰がこのメソッドを使用するかというのを指定してる。PhotonTargets.Othersは自分(マスター?)以外。
試しにPhotonTargets.の値をマスターみたいなやつにしたら非マスター側ではポジションの変化はしなかった。
で第三引数"transform.position"はvoid SetPosition(Vector3 newPos)の第一引数に入れる値を入れてやる。

上記の結果、
このオブジェクトをマスターが操作
 →一定の距離が離れると距離を更新してRPC発動
  →非マスター側でSetPosition()が使用される
結果同期する。
こんな感じか・・・?

おそらく、とか、だろう。とか多用するけど、手探りだからしょうがない。
まったく見当違いの可能性もあるから、気づいたら修正したい。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。