主なコンテンツ

〜主なコンテンツ〜

1. Unityで製作したゲームと製作Tips
  1. 三月精チャレンジ(東方Project二次創作)
    1. 作り方
  2. 英語学習2D(オリジナルスマホアプリ)
2. UE4
3. ゲームアプリ見学
4. Bitbucket & SourceTreeでの一連の流れ
  1. 前半
  2. 後半
5. Tips
  1. UnityのTips
  5. SQL文のTips
  6. Final IK
  7. GearVR+Unity

2016年2月4日木曜日

UnityのTips


  • よく使うクラスの継承関係と、保有する主要な変数・関数

    • Object:class in UnityEngine
      • Destroy関数など
    • GameObject:class in UnityEngine/継承元:Object
      • activeSelf, tagtransform変数など
      • GetComponent, FindSetActive関数など
      • HierarchyにあるGameObjectのベースとなるクラス
      • ややこしいが、Componentクラスにも同じ変数や関数がある
      • TransformにもFindがあるが、GameObjectのFindとはかなり仕様が異なる(参考
    • Component:class in UnityEngine/継承元:Object
      • gameObject, tag, transform変数
      • GetComponent関数など
      •  GameObjectにアタッチされる全てのもののベースとなるクラス
      • コンポーネントを生成する関数はない(スクリプトでコンポーネントを追加したり削除したりはできない)とComponentのリファレンスに書いてあったが、GameObject.AddComponentを使えば可能に見える
    • Behaviour:class in UnityEngine/継承元:Component
      • enabled変数など
    • MonoBehaviour:class in UnityEngine/継承元:Behaviour
      • Update関数など

  • FindChild()がスクリプトリファレンスにない件

    • Find推奨でFindChildは廃止される可能性あり(参照
    • なお、Findが調べるのは子のみで孫までは調べてくれない模様(参考

  • Unityでロード先のシーンが真っ黒のとき

    • Window>LitghtingからLightmapをビルドする(参考
    • Lightmapをビルドする際は問題のシーンを開いている必要がある
    • Lightmapをビルドすると、関連フォルダとファイルがシーンのあるディレクトリに生成される
    • シーンごとにLightingの設定が保存されてる模様
    • Autoのチェックは外したままでOK

    • privateだけどInspectorで入力できるようにしたい

      • [SerializeField]をつける

    • プロパティだけどInspectorで入力できるようにしたい

    • 構造体だけどInspectorで入力できるようにしたい

      • 構造体は不可能
      • クラスなら可能なので、クラスにして[System.Serializable]をつける(参考

    • RaycastHitでRayの当たったオブジェクトのタグを調べる場合

      • hit.collider.tag == "enemy"、のようにcolliderから取得するのが一般的のよう
      • hit.transform.tagだとRigidbosyしか付いてないオブジェクトのtagも取ってこれてしまう?

    • Animatorでのトランジションの削除

      • 推移元のアニメーションを選択するとトランジションの一覧があるので、そこから削除する

    • Animatorのトリガーをオフにする

    • 現在再生中のアニメーションを調べる

      • AnimatorStateInfoを使う
        • Animator.GetCurrentAnimatorStateInfo(index)でAnimatorStateInfoクラス構造体にアクセスし、下記の手段で判別する。(参考
          • AnimatorStateInfo.fullPathHash == Animator.StringToHash("Base Layer.Run")
          • もしくは、AnimatorStateInfo.IsName("Run")。ただし、こちらは処理が遅いらしい。
        • GetCurrentAnimatorStateInfo(index)で指定するレイヤーのindexは、左から順に0,1,2,3...
        • 判別に使用するのはステート名(アニメーションクリップ名ではない)
        • 再生がブレンドされている場合、先に読み込んだデータが返ってくる。そのため、厳密に取得したい場合はAnimator側でアニメーションをブレンドしないようにする必要がある
      • AnimatorClipInfoを使う
        • この方法は見かけないが、Animator.GetCurrentAnimatorClipInfo(index)でも再生中のアニメーションは判別できた
        • 戻り値が配列なので、以下のようにする必要がある
          • AnimatorClipInfo [] clipInfo = animator.GetCurrentAnimatorClipInfo (0);
          • Debug.Log (clipInfo[0].clip);
        • clipの戻り値はアニメーションクリップ名(ファイル名)
        • 再生がブレンドされている場合、先に読み込んだデータが返ってくる(下図左下がDebug.Logで確認したもの)
        • GetCurrent〜は呼び出した時点の情報なので、常に状態を監視したい場合はUpdateなどで情報を毎回取得する必要がある
      • 追加】StateMachineBehaviourを使う
        • Unity5から追加された(参考
        • 引数にあるanimatorから呼び出し元のGameObjectを参照できる(参考

    • Transform.positonが足元にあるため起きる弊害を回避したい
      • 例)弾丸が足元から出る:発射位置に子オブジェクトを作る
      • 例)LookAtで足元を見る:見て欲しい場所に子オブジェクトを作る
      • 強引なようだが、公式チュートリアルもそうやっている

    • Vector3.Angleの仕様

      • 戻り値はオイラーであり、ラジアンではない
      • 方向ベクトル同士の角も、座標同士の角度も取得できる模様
      • あくまでベクトル間の角度であり、負の角度という概念がない(方向ベクトルに対して時計回りか反時計回りかという情報はない)
      • 回転の方向が必要な場合は、Mathf.Atanなど三角関数の概念を使う

    • Quaternion.AngleAxisの仕様

      • 角度はオイラーであり、ラジアンではない
      • 任意軸周りにθ°回したときのQuaternionを作る
      •  現在のtransform.rotationからθ°回す場合には、Quaternion同士の掛け算を使う(参考:Quaternion同士を掛けると角度成分が加算される)

    • Debug.DrawLineとDebug.DrawRayの違い

      • DrawLine:2点間に線を引く
      • DrawRay;位置と方向で線を引く
      • 参考

    • AssetStoreのアニメーションにおいて、アニメーションイベントが保存できない

      • ReadOnlyになっていることが原因
      • ProjectウィンドウでAnimationを複製すると解除できる
      • 複製の仕方はwindowsならcontrol+D, Macならcommand+D

      • プレハブの本体にスクリプト側で値を設定し、それをInstantiateで量産する場合の注意点

        • ここで言うプレハブの本体とは、HierarchyにCloneされたものではなくProjectのもの
        • 結論:おそらく非推奨。publicの場合プレハブの本体に値が設定される…ような振る舞いをする
        • Inspectorで指定したプレハブのプロパティに代入したのち、このプレハブをInstantiateすると値は代入されておらずNullになる
        • 今回の例の場合、下図のSpawnBehaviourのSpawnをpublicにすると、呼び出し元であるSpawnManagerのStartで代入した値のプレハブを量産できる
        •  privateにしてメソッドで値を渡した場合は、何故かNullとなる
        • 結論:スクリプトで値を設定したプレハブをInstantiateする場合、publicで変数を用意しておくか、InstantiateしたGameObjectをインスタンス化し、生成したオブジェクト毎に値を渡す参考)。
          • 後者の場合はas GameObjectを忘れないように注意
          • 前者については良く分かっていないので、詳しい方いましたらコメント下さい(汗

      • ProjectのプレハブにHierarchyのオブジェクトをInspectorから参照させる

        • できない参照
        • よって、下図のようなやり方で取得する。(下図は公式チュートリアルのSurvivaleShooter)
          • 現在は「FindGameObjectsWithTag」か「FindWithTag」を使う(参考:GameObjectのリファレンス)
        • 実質、Tagをつけるのはこのため
        • 弾丸などが毎回Findを使うのは如何なものか。いっそ、ヒエラルキー上にInstantiateしたいオブジェクトを非アクティブで置いておいて、それを量産したほうが処理が軽いかもしれない…?
          • 言うほど時間のかかる処理ではないので、Updateで毎フレーム呼び出さないのなら気にしなくても大丈夫そう。(参考

        • intの乱数を作る

          • Random.Rangeの引数はfloat型とあるが、これを全てint型にすると整数乱数になる(参考

        • OnTriggerEnter等で、接触したコライダーの子オブジェクトを参照する

          • 速度検証も含めた詳しい参照先はこちら
          • Collider.transform.Findでアクセス可能
            • 非アクティブの子オブジェクトも参照できる
            • GameObject.Findと違い、Updateでの呼び出しが非推奨となっていない
            • GameObject.FindWithTagより若干早い
            • 戻り値はGameObjectではなくTransform(GameObjectが欲しい場合は、transform.gameObjectでアクセス)
          • Collider.gameObject.FindやFindWithTagは不可能
            • インスタンスからは呼び出せない?

        • シーンのリスタート

          • Application.LoadLevel (Application.loadedLevel);で再読み込み
          • 公式チュートリアルのSurvivableShooterもこのやり方
          • 詳しくはこちら

        • プレハブの解除

          • Hierarchyの解除したいGameObjectを選択した状態で、上部メニューの「GameObject」にある「Break Prefab Instance」を選ぶと解除できる

        • Layout Groupの幅と高さの自動計算

          • Layout Groupをアタッチしたオブジェクトのtransformは、コンテンツの数やspacingを考慮した値になる
          • 親オブジェクトの幅や高さを計算するときに便利

        • Colorの一部の値を変える

          • できない
          • よって、new Colorで直接書き換える(参考
          • このほか、ベクトルのようにColorクラスで足し引きする方法もある(参考
          • なお、Colorの各成分値は0~1のfloat値であり、0~255のint値ではないので注意参考
          • 成分は0~1の範囲だが、この範囲に丸め込むという機能はない。100とか-200といった値を代入できるし、足し算で1以上の値を蓄積することもできるし、引き算でマイナスに振り切ることもあるので注意が必要
          • 足し引きでフェードイン、フェードアウトをやるなどでなければ、new Colorで書き換えたほうが無難

        • アニメーションが終わった後、何故か冒頭だけ再度読み込まれる

          • 自動的にモーションの切り替わりをブレンドしてくれるため
          • これにより、アニメーションイベントが重複して呼び出されることがある
          • アニメーターにて、問題のトランジションのインスペクタを開き、ループが不要なほど移行を早くすればOK

        • 3Dモデルの透過処理

          • 古来から処理がかなり難しい
          • シェーダーをいじることになるが、透過オブジェクトを使わない方法を考えたほうがいい

        • シーンタブのスピーカーについて

          • これのこと
          • マニュアルの「2D、ライティング、オーディオスイッチ」にさらっと書いていある(参考
          • 例えばPlay On Awakeにチェックを入れているAudioSourceがあったとする。そして、スピーカーのボタンを有効にしているとする。このとき次のようなことが起こる。
            • ゲームを再生していなくてもシーンタブ(シーンビュー)を開いていれば音楽が流れる
            • 「maximize on Play」を有効にしているときゲームを再生すると、シーンビューが画面から無くなるため音楽が再生されなくなる

        • WebPlayerが非推奨となる件について

          • セキュリィティの関係から、各種ブラウザがWebPlayerのようなNPAPIを廃止する動きが急速に始まっている
          • Unity側の発表は次の通り
          • 今後はWebGLを使うことになる
          • …全然関係ないけど、ニコニ立体とかにも影響あるのではないだろうか

          • Directional Light

            • 太陽光の概念
            • 均一に照らすので位置などを考えなくて良い
            • 向きを変えると影の向きが変わる

          • ScriptablObjectが簡単に作れるようになった

          • 配列のサイズをInspecterで変更する

            • 配列のサイズはInspecterのSizeで変更可能


          • Sprite Packerが使えない

            • Resources下では使えない
            • pngとjpegなど異種ファイルの混同はできない
            • 詳しくはこちら

          • 2Dゲームのスプライトの大きさが把握できない

            •  カメラの遠近感による問題
              • カメラのProjectionがPerspectiveになっている(参考
                • z軸等を調整し、イメージに合う距離にする
                • Orthographicに変更する(推奨
                  • 尚、Live2Dはこのモード前提で作られている
                  • これにより、描画領域も把握しやすくなる
            • 単位系の問題
              • Unityは元々3Dゲーム用の物理演算ソフトであり、オブジェクトの大きさはピクセルではなくメートル
              • スプライトのscaleは、Pixels per Unitに依存している(参考
              • デフォルトではPixels per Unit=100なので、この状態で高さ64ピクセルの画像をシーンに加えると、ゲーム内で高さ0.64mがscale 1である物体として扱われる
              • ピクセルで大きさを考える必要がある画像は、uGUIかスクリプトで管理する方がベター

          • 丸影をつけたい

            • StandardAssetsにあるPrefabを使うと良い(参考
            • これで影を落とせるのは3Dだけでかつ、影ができる場所のシェーダーがStandard である必要があると思う

          • 2Dゲームには3DでいうCubeとかのシンプルな素材はないの?

            • Unity5.3からSprite Creatorが追加された(参考
            • 3Dのプリミティブとは異なり、アセット扱いとなる

          • uGUIのRaw Imageとは何か?

            • Image
              • スプライトを表示するもの
              • スライスやタイリングが可能
            • Raw Image参考
              • テクスチャが表示可能
              • Imageにあったスライスやタイリングはできない
              • wwwから取ってきた写真などを直接表示可能
              • RenderTextureと組み合わせることで、Live2Dのモデルを表示可能(参考1参考2

          • Render Textureとは?(参考

            • Assets->Create->Render Texture から作成可能
            • これを活用するとゲーム内のパネルに、別のカメラが写した映像をリアルタイムで描画したりできる

                  • ちょっと詳しくないが…
                    • Mesh Render コンポーネントにRender TextureをアタッチするとMaterialが生成される
                    • Cameraの映像をRender Textureとして出力することができる
                    • これをMesh Render をアタッチしているオブジェクトのMaterialにすると、カメラの映像がTextureとして表示される
                    • 動画でもやっているように、Render Textureの設定は色々弄る必要があるので注意
                    • 出力先のオブジェクトが長方形だと映像が潰れて見える。Render Textureのサイズ比を変えても効果なし。できないはずはないと思うが調査中。

                • iPhoneなどで起動した際、縦に画面を固定したい

                  • PlayerSettingsのDefault Orientationを変更する(参考

                • アプリ起動時の無料板Unityロゴが消えてから処理を行いたい

                  • Application.isShowingSplashScreenで判定可能(参考
                  • これを使わないとロゴの裏で既にゲームが始まってしまっている

                • 3DプリミティブオブジェクトのPlaneとQuadの違い

                  • Quadは旧GUI用(参考
                  • uGUIが実装された今、Plane一択で良さそう

                • AnimatorにてTriggerがONのまま未処理か知りたい

                  • Triggerは1F後にON/OFFする機能を持たせたbool代数なので、getBool(トリガー名)で状態を把握できる

                • ファイル共有にてLibraryを対象から外したい

                  • Unityのsettingsを弄る必要がある模様(参考

                • アニメーションイベントで呼び出せないメソッドがある

                  • 同名のメソッドがある可能性(参考
                    • 普通なら呼び出せないのだが、後から同名のメソッドを追加した場合は処理が重複する。Debug.Logを仕込んでみても呼び出しは1回で行われるなど、厄介な状態になるので注意。

                • パーティクルで透過した画像を表示したい

                  • martialを作成した際、Shaderを「Particles/Alpha Blended」にする(参考

                • Canvas内にCanvasがある場合の描画順

                  • 現状、実質不明(参考
                  • なので個人的にはCanvasの入れ子はしないほうが無難だと思う

                • アニメーションで移動したい・させたくない

                  • Unity5で実装された「Apply Root Motion」を使う(参考

                • カリングマスク等をスクリプトから指定

                  • ビット演算子で1となる箇所のレイヤーが対象となる
                  • スクリプトからの指定にはビット演算子を使う(参考

                • unitypacageファイルをダブルクリックで開けなくなった

                  • Unity上部メニューのAssets>ImportPacage>CustomPacageで開ける(参考

                • アセットバンドルとは何か?

                  • アセットをひとまとめにしたもの
                  • 勉強に良さそうなサイト(参考

                • 再生されている端末が知りたい or エディタ時のみの処理がしたい

                  • 以下のような手段がある(参考
                    1. Platform Dependent Compilation
                    2. Application.platform
                    3. Debug.isDebugBuild

                • インスペクターで表示する項目をひとまとめにしたい

                  • クラス内クラスを作る(参考
                    • 注意点
                      • クラス内クラスには[System.Serializable]が必要
                      • クラス内クラスのインスタンス(メンバ変数)を用意する
                        *private等にしないこと

                • インスペクターに表示されるListの要素名に名前を付けたい

                  • 最初の文字列(string)の変数に格納された値が要素名と連動している
                    • privateだと機能しない
                    • [HideInInspector] public は有効
                    • 文字列が空だとElement0のように表示される

                      • Profilerに出るTextRendering.Cleanupを改善したい

                        • Profiler自身の処理によるものなので改善不能(参考

                      • ドット絵の色がちらつく

                        • 少し前までは、素材側のCompressedをtruecolorにすれば良かった
                        • 今はCompressionをNoneにすると良い

                      • spriteの描画順を管理したい

                        • sorting layerを使うと良さそう(参考

                      • インスペクターに自作クラスのインスタンスが表示されない

                        • 表示したいクラスに[Serializable]を付け忘れている(参考

                      • テクスチャとスプライトの違い

                        • Unityとは関係ないが、気になった人用
                        • テクスチャは画像データで、UV値を用いて画像データのどこの範囲を描画するか指定する
                        • スプライトは四角形による描画範囲が指定済みのテクスチャデータ

                      1 件のコメント: