サイレンスブログ

Unity初心者の備忘録をかねた自分のやってきたもの

VisualStudio拡張機能 私的おすすめ

クリスマスということで!

今回は私的おすすめVisualStudio拡張機能を紹介したいと思います。

 

そもそも拡張機能ってどうやって入れるの?

>> VisualStudioメニューバーのツール(T)→拡張機能と更新プログラム(U)→

▷オンライン→検索してダウンロード

 

では紹介していきます!

 

①CodeRush

marketplace.visualstudio.com

特徴

・無料お試し期間は30日らしい。

・機能が多すぎてヤバイ。

・詳しくは↑のサイトで見た方が早いです。

使ってみた感想

・できることが多い故に覚えにくい(褒めています)。

・テンプレート機能が便利!

設定した文字列を入力し、TabまたはSpaseキー(選択可)を押すと、設定したプログラムに変換できる機能(丁寧)。

・私のような初心者だと活かせないかも...。

 

②CodeMaid

http://www.codemaid.net/

特徴

・Maid...メイド...あ^~

・機能は↑を参照してください。ページを翻訳すると分かりやすいです。

・初心者にも分かりやすい。

使ってみた感想

・テンプレート機能はないですが、自動で不要な空行を詰めてくれます。

・頻度は少ないですが並べ替えも便利ですね。

・初めて拡張機能を入れる方にはとりあえず入れてみるのをおすすめします。

 

③BackSpacce

baba-s.hatenablog.com

特徴

・↑こちらを参照してくださいくコ:彡

使ってみた感想

・単純に便利。

・色も自分好みにカスタマイズできるのがイイ!

・シンプルな機能なので入れておいて損はないと思います。

 

④Code alignment

baba-s.hatenablog.com

特徴

・↑こちらを参照してくださいくコ:彡

・ショートカットキーの設定もできるよ!

使ってみた感想

下記のようなコード(空行に注目)は秀丸ユーザーの方に多いのではないでしょうか?

 public int         id1;

 public int         id2;

 public int         id3;

 public int         id4;

VisualStudioだと括弧や改行したりすると自動で空行を削除して揃えてくれますが、逆に空行を入れて揃えたい...というときに使えます!

私は「 = 」揃えを【Shift + Space】でショートカットに登録して使ってます。

 

一応登録の場所は、VisualStudioメニューバーのツール(T)→オプション(O)→

▷環境→キーボード→Alignで検索!

 

ただ、①や②のコードクリーンアップ(不要な空行や改行を消す)機能を使うとせっかく増やした空行が消えてしまうので注意が必要です。

 

くコ:彡趣味枠

⑤ShachikuChanIDE

f:id:yuukiacid:20181225135146j:plain

※画像はモチーフです

http://oxamarin.com/visual-studio-shatiku/

 

タイピングすると社畜ちゃんも一緒にタイピングしてくれます。

これで徹夜の作業も捗りそうですね!(そんな余裕があればですが

 

↓読んでみてね↓

comic.pixiv.net

 

 

クリスマスの伏線回収...最後に紹介するのはコレ!

⑥PowerMode

marketplace.visualstudio.com

 

タイピングが楽しくなります。

ただ増やしすぎたりすると重くなるのでそこはお好みで調整してね!

 

私はこんな感じでやってます。

f:id:yuukiacid:20181225140408p:plain

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 

以上です。マイルタスクの提出後や、作業したいのに仕様が上がってこないなどで手が空いてしまった時には、拡張機能を探してみてはいかがでしょうか?

 

仕様が上がってこない現場からお送りしました。。。

【Unity】AnimationのAnimationsを取得したい!

取得したい!

というわけで調べると、いつも調べ物でお世話になっているブログで発見。

 

kan-kikuchi.hatenablog.com

 

この通りに書いてもエラーが!?

4年前ですから当然ですよね。

 

Uniity2017.3 での記述はこちら

 

  private List<AnimationClip> animations = new List<AnimationClip>( );

 

    void Start ( )

    {

        foreach (AnimationState anim in this.GetComponent<Animation>( ) )
  {

            // リストに取得する
    this.animations.Add( anim.clip );
  }

 }

 

ちなみに呼び出すときは以下の文です。

GetComponent<Animation>( ).Play( this.animations[0].name ); 

 

明日も頑張りましょう!

【Unity】Buttonの挙動がおかしい・反応しない時

 

 Case 1

プレゼントボックスなどでページ内に10個アイテムリストを作り、ScrollViewで表示するとき。

リストアイテム10個を生成し、その中にあるスクリプトの初期化を読んだ時にボタンにつけるイベント設定も付け加えていた。

 

        リストを作るスクリプト

for(int i = 0; i < 10; ++i)

{

    GameObject obj = Instantiate(リストに表示するPrefab) as GameObject;

    obj.GetComponent<PrefabにアタッチしているScript>().Init(data)

}

        

        PrefabにアタッチしているScript.cs

public void Init(ItemData data)

{

    GetComponent<Button>().onClick.AddListener(() =>

    {

       // 受け取る処理

    });

}

 

 このとき、アイテムリストのページを切り替えても作ったオブジェクトは消さず、

異なるdataを引数に渡して初期化を改めて行ったけどボタンが反応しない....。

 

原因はAddListener()が初期化されていなかっただけでした!

 

なので、正しく書くと

public void Init(ItemData data)

{

    // Listenerも初期化

    GetComponent<Button>().onClick.RemoveAllListeners();

    GetComponent<Button>().onClick.AddListener(() =>

    {

        // 処理は割愛

    });

}

 ですね!

AddListener()って上書きじゃないんですね。Addって付くものには少し気を付けよう()

 

Case 2

次はカードっぽいオブジェクトにめくる時のアニメーションを与え、

タップでめくれるようにしたかったときに起こりました。

 

めくる動作を表現するためにオブジェクトの Rotate.y をあらかじめ-180しておき、アニメーションで0まで戻したい。

でもなぜかボタンが反応しない!なんでや!!

 

上に透明のオブジェクトがないか、Raycastがチェック外れていないか、EventSystemがちゃんとあるか、なども全部確認して途方に暮れたのでアニメーションを外してみました。でも反応しない....そしてRotateも戻しても反応しな・・・した!w

 

どうやらボタンのOnClick判定にも裏表があったみたいで、いや普通は常識なのかな?

また一つ知識が増えたので良しとします!前向きに。

 

( ..)φ...以上経験談でした!

 

【Unity】アプリ内のレビュー誘導を実装

iOS11対応のレビュー誘導を実装した時に調べたことなどのメモです。

 

まずは iOS11のレビュー誘導情報。

crossbridge-lab.hatenablog.com

 

大まかにまとめると

  • iOS11以降の端末にはSKStoreReviewControllerクラスを使用しましょう!
  • 3回制限があるからレビュー誘導を出すタイミングは考えよう!
  • でもコールバックは取得できないよ!

だと思います!

 

 

次に実装です。

kan-kikuchi.hatenablog.com

 

 この素晴らしいサイトを見て実装して下さい()

 

ただ、使用しているSingletonMonoBehaviourが初期化処理を加えた良いものになっているので、そこも付け加えるか、オススメはしませんがReviewManagerのInit()を何とかする必要があります。

 

その後デバッグ時に躓いたこと

  • ReviewManager.Instance.RequestReview(); を実行しても無反応!

原因 ReviewManager.cs をアタッチしたオブジェクトがシーン内に存在していないことでした。

  • 星は押せるけど送信ボタンが押せない!?

これは不具合ではなく、正常みたいです。

requestReview() - SKStoreReviewController | Apple Developer Documentation

翻訳して読んでみると....

ストアにリリースされたもの以外、つまりデバッグ端末では送信ボタンはdisibleのままが仕様のようです。だから何度も呼び出せたのですね(わかる)

 

 

一発勝負感がありますがAppleを信頼して祈るしかなさそうですね。。。

 

 

【Unity】InstantiateとCoroutine

Coroutine(コルーチン)の使い方が分かってきた今日この頃。

何でもCoroutineにする意味がないと言われ、使いまくっていた無駄なCoroutine部分を無くしつつデバッグしていると、オブジェクトの位置がおかしい・・・・。

 

原因を探ってみると

foreach内でInstantiate()したものをSetParent()でオブジェクトの子にした後、

そのtransform.positionを取得していた処理の

\どこかがおかしいみたい!/

 

以前はyield return StartCoroutine();でこの処理を行っており、

Coroutine処理をやめてから起こった不具合でした。

ソース内でCoroutineを使うと、関係ないはずの部分も並列処理されるのか?などと

考えた時もありましたが、そんなことはなく(あったら困る)。

 

原因はInstantiate()の重さでした。

Debug.Log() や Instantiate() などの速度を計測してみる - Qiita

 

Instantiate()が完了されないまま取得して変な数値になってたんですね・・・・。

 

★結論

Instantiate()を複数使用し、その後すぐに複製したオブジェクトのパラメータを

取得変更する時は、コルーチンで作り終わるまで待とうね!

【Unity】2DSpriteとUIの違い

作業が忙しくなって日が開いてしまいました!(言い訳)

 

今回はUnityのSprite(2Dオブジェクト)とUIの違いについて学んだことをざっくり書き残していきます。

※厳密にはSprite RendererとuGUIの違い

 

まず使用頻度の高いUI

・CanvasRenderer ImageやTextなど作成すると自動的についてるやつ

Canvas UIオブジェクト作成時、一番上の階層に他のCanvasがなければ自動的に作られるやつ

この2つを組み合わせて描画しているようです。

 

描画の順番はHierarchyの上から下にかけて新しくなります。

またCanvasに設定したSorting LayerとOrder in Layerによる描画順制御も行えます。

どちらも値が大きくなるほど新しく描画されるのですが、

・Sorting Layer ― 他の描画オブジェクト(2DSprite)との描画順制御

・Order in LayerはCanvas ー 同士の描画順制御

で使っているイメージです。

 

Image、RawImageの違い

どちらもRectTransformというコンポーネントを所持しており、

画面サイズ毎にUIの配置があまり変わらないよう、Anchorなどで自動的に置換してくれています。

初心者の私が気にする違いは、扱う画像の種類

Image ― Sprite

 パッキングやタイリング可能

RawImage ― Texture

 Web上の画像を表示可能

基本的にはImageでよさそうです。

 

 次にSprite(2Dオブジェクト)

UIと異なり、RectTransformでなく普通のTransformがついてます。

また、SpriteRendererという、単体で描画する機能を持ったレンダラーがついてます。

Canvas同じく、その中にSorting LayerとOrder in Layerがあるので、

UIより先に描画したい場合はSorting LayerでUI、SpriteなどのLayer名を設定し、

Edit > Project Settings > Tags and Layers で順番を変えることで共存可能です。

 

つまり・・・

2DSpriteはCanvas階層内に含めなくても描画できるが、

UIのように画面サイズ変更対応に強くありません。

 

全部UIでいいのでは?

2Dゲームでなければそれで対応できるのかもしれません。

しかし、Sprite(2Dオブジェクト)にはLightを当てることが出来ます。

これはUIでは出来ないことなので2Dゲームの種類によっては必要になると思います。

(アセットを使えば解決ですが)

2Dゲームでも逆にライトを画像に当てない場合はUIだけでいいのかもしれません。

処理速度や効率を考えるようになると話は変わるのでしょうが

今はとりあえず....。

 

【Unity】WebViewを実装した話

ソーシャルゲームや様々なアプリで使われているWebView。

簡単に説明すると、ブラウザアプリを立ち上げずにアプリ内でWebを見ることが出来るものです。

今更ですが、WebViewを実装する過程で試行錯誤した時の話です。

導入後の具体的な使用例などが調べてもあまり見つからない、MacのUnityまたは実機でないと確認できないため、少し時間がかかりました....。

……………………………………………………………………………………………………

使用するのは、greeから提供されているプラグインです。

https://github.com/gree/unity-webview 

 

あと、コールバックを設定するには編集可能なローカルではないWebページも必要です。

ローカルのWebページでやるやり方 ?

unity-webview で自前のHTMLを表示するサンプル - Qiita

 

導入方法は他のサイトで詳しく載っているため割愛します。

Unity上でWebViewを開く unity-webview - テラシュールブログ

https://loumo.jp/wp/archive/20131115085810/

……………………………………………………………………………………………………

作業目標

ボタンをクリック  WebView起動  WebView削除

この動作を何度も行えるプロジェクトを作成してみます。

 導入が終わったら、まずボタンを作ります。(WebViewButton)

f:id:yuukiacid:20180209141845j:plain

 

WebViewButtonの子にWebViewOriginという空のオブジェクトを作ります。

( 子である必要はないですが分かりやすいかなと思い)

そのWebViewOriginに以下のスクリプトをアタッチします。

 

SampleWebviewObject.cs

using System;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SampleWebviewObject : MonoBehaviour {


private WebViewObject webViewObject;
public const string url ="https://www.google.co.jp";

// Use this for initialization
void Start ()
{
  // WebViewObjectの生成
  this.webViewObject = new     GameObject("WebViewObject").AddComponent<WebViewObject>();

  //マージンを求める
  int mX = Screen.width / 9;
  int mY = Screen.height / 5;

  // キャッシュ回避用タイムスタンプ
  //string date = '?'+DateTime.Now.ToString();

 
  // コールバック設定
  this.webViewObject.Init((msg) =>
  {
    switch (msg)
    {
      case "シーン名":

        // WebViewの停止

        this.webViewObject.SetVisibility(false);
        Destroy(this.webViewObject);

        //シーンの遷移
           SceneManager.LoadScene(msg);
        break;

        case "close":
        // WebViewの停止
        this.webViewObject.SetVisibility(false);
        Destroy(this.webViewObject);

Destroy(GameObject.Find("WebViewObjectOrigin(Clone)").gameObject);
        break;
    }
  });

       // URLの設定
  this.webViewObject.LoadURL(url);

       // マージン(余白)の設定
  this.webViewObject.SetMargins(mX, mY, mX, mY);

  // WebViewを有効にする
  this.webViewObject.SetVisibility(true);
}

 

次は、親のWebViewButtonに以下のスクリプトをアタッチします。

 

WebViewButtonManager.cs

using UnityEngine;

public class WebViewButtonManager : MonoBehaviour{


 /// <summary>
 /// WebView起動ボタン押下時
 /// </summary>
 public void LegalButton_OnClick()
 {

#if UNITY_EDITOR_WIN
   // MacでないとUnity上でデバックできないため
   Application.OpenURL("https://www.google.co.jp/");

#else
   // オブジェクトを複製し、有効にする
   GameObject WVO = Instantiate(GameObject.Find("Canvas").transform.Find("WebViewButton/WebViewObjectOrigin").gameObject);
   WVO.SetActive(true);
#endif
 }

}

 

スクリプトを見て分かる通り、以下の流れで動きます。

  1. WebView起動ボタンを押す
  2. WebViewOriginが複製される
  3. WebViewOriginを有効にする
  4. WebViewOriginのStart()処理が始まる
  5. WebViewObjectが生成される
  6. コールバックを受け取り、処理分岐へ
  7. WebViewObjectを削除
  8. WebViewOrigin(Clone)の削除

 8まで終了すると、また1から繰り返すことが出来ます。

今回は繰り返して行えるようInstantiateを使っていますが、他にもっと効率的な方法があるかもしれません。

 ……………………………………………………………………………………………………

 

また、コールバック用の処理としてHTMLに

<a href="unity:コールバック用文字列">  シーン遷移します <a/>

こんな感じで書けばクリック時に送ることができます。

 

(例)

<a href="unity:close">閉じる</a>

webViewObject.Init((msg)の msg == "close"

 

キャッシュのクリーンについては、iosAndroidで対応が異なり、

まだ開発者が手をつけれていないみたいです(2018/2/9 時点)

github.com

でもcookieはクリアできるみたいです!

github.com

 

「キャッシュ」はコンピューターに一時的に記憶された使用頻度の高いデータのこと。

「クッキー」は端末に保存されたウェブブラウザー利用者の情報のこと。

 

ちなみに、SampleWebviewObject.cs内の

// キャッシュ回避用タイムスタンプ
//string date = '?'+DateTime.Now.ToString();を有効にし、this.webViewObject.LoadURL(url+date);として実行しても

キャッシュ回避が出来ていませんでした。

(iosはWebViewが真っ白になります。)

github.com

 

javascriptファイルのキャッシュはよくわからなかった(小声)

 

 今回は以上です!!