ラベル Unity の投稿を表示しています。 すべての投稿を表示
ラベル Unity の投稿を表示しています。 すべての投稿を表示

Error: Could not load signature of エラーの原因の1つはこれだった

Unityあるある。

FirebaseやAdMobなどdllを追加したり更新したりすると出るお馴染みのエラー。

Error: Could not load signature of ErrorProne.NET.ExceptionsAnalyzers.IfThrowPrecondition:.ctor due to: Could not load file or assembly 'Microsoft.CodeAnalysis.CSharp, Version=2.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. assembly:Microsoft.CodeAnalysis.CSharp, Version=2.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 type:<unknown type> member:(null) signature:<none>

今回は、これがRoslynAnalyzerを入れたときに発生した。 


で、これを起因に某広告SDK(AdMobではない)にもloadingエラーがエディタ起動時のコンソールに表示されたり、

FirebaseSDKも起動時にdllロードエラーが出るようになった。


【原因】

packages/下にインストールした「Roslyn Analyzer」がAssets下にもコピーしたのを失念していた。

要はプロジェクト内に同じdllが2つ存在していた。

RoslynAnalyzerは、Assets側を使いたかったので、packages下のdllを消して

再起動したら解決!





「DOTween」の警告を解消する

警告が出た

DOTweenを使用してロジックを組んでいた所、以下の警告が出て気になりました。

DOTWEEN ► This Tween has been killed and is now invalid

原因

すでにTweenの再生が終了しているものに対して、DOTween APIを使用すると発生するようです。

if (tween != null && tween.IsPlaying()) // ここで警告が出ている
{
    tween.Complete();
}

上記のような場合、tweenがもう再生済みでKillされているにも関わらず

「IsPlaying()」がコールされた事で警告が発生します。

対策

if (tween != null && tween.IsActive() && tween.IsPlaying())
{
    tween.Complete();
}

というように「IsActive()」を追加する事で警告なしでTweenがすでに無効化されているかを確認できます。

公式ドキュメントにも、以下のように記載されているので、意図した挙動となっています。

Returns FALSE if the tween has been killed.

Unityの「instantiate is null」エラーを解決する

問題点

インスペクタに正しく参照を設定しているにも関わらず、

ArgumentException: The Object you want to instantiate is null. UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) 

がコンソールに出ました。

なぜか未実行時にも出て、実行時にも当然出るのでおかしいなと思っていたのですが、
ステップ実行したら一瞬で原因がわかりました。

原因


- 「Awake」ではなく「クラスコンストラクタ」でInstantiateしていました。
- もともとピュアクラスだったものをビヘイビアに変えたときにコンストラクタをAwakeにするのを忘れていました。
- 「コンストラクタ」をやめて「Awake」内に入れて解決しました。

NG例:

public class YourClass : MonoBehaviour
{
    public YourClass() {
        var dest = Instantiate( sourcePrefab );
    }
}

OK例:

public class YourClass : MonoBehaviour
{
    private void Awake() {
        var dest = Instantiate( sourcePrefab );
    }
}


まとめ


クラスコンストラクタをAwakeに書き直してみましょう!

The Referenced Script On This Behaviour Is Missing を直す

しばらく放置していた古いプロジェクトを Unity2018 で開いたら

実行時に必ず「The Referenced Script On This Behaviour Is Missing」が出るようになった。

【解決方法】

・その警告が出るシーンのプレハブなど内容をすべてコピー

・新しいシーンを作成する

・新しいシーンのテンプレ内容(MainCameraとDirectinalLight)を消す

・コピーしていた内容を貼り付け

これで直る。ようなシーンファイルが壊れたって事ですな。

Unity終了時に必ずクラッシュするのを解決する

なんだか最近、Unityを終了する時に必ずクラッシュするようになったなぁと思ったら、

VSCodeプラグインが入っていると落ちる事が分かった。

Unity2017.x系どれでも起きている。おそらくUnity5.xでも起こると思う。

解決方法は、Plugin/VSCode.csを開き、

static void FixUnityPreferences()内にある

if ( EditorWindow.focusedWindow == null)
return;

を


if ( !EditorApplication.isPlaying || EditorWindow.focusedWindow == null)
return;

とすれば直る。

スプライトやテクスチャの端に余計な1ドットの線が入る訳

Unity のスプライトや、ゲーム開発においての初心者あるある。

主に2Dゲーを作ろうとしたときに、スプライトの端に隣のテクセルが見切れてしまうような現象に出会ってしまった場合、

テクスチャのサイズをPOW2(2累乗サイズ)にしていないかを確認しよう。

1 / 2 / 4 / 8 / 16 / 32 / 64 / 128 / 256 / 512 / 1024 / 2048 / 4096 など

POW2のサイズに余白を足してでもテクスチャを広げてみよう。

浮動小数が割り切れる数になるため、端数がでて変な見切れは発生しなくなる。

JsonUtility で Dictionary を使うとても簡単な方法

シリアライズの直前とデシリアライズ直後を拾えるインターフェースがあるので
それを加えた専用Dictionaryクラスを作ればよい。

If you want use Dictionary in JsonUtility.
Than make wrapper class. It is very simple!

[System.Serializable]
//==================================================================
/**
 * @brief Dictionary for JsonUtility
 */
//==================================================================
public class Dict : Dictionary, ISerializationCallbackReceiver
{
 [SerializeField] private List keys = new List();
 [SerializeField] private List vals = new List();

 public void OnBeforeSerialize()
 {
  keys.Clear();
  vals.Clear();

  var e = GetEnumerator();

  while ( e.MoveNext() )
  {
   keys.Add( e.Current.Key );
   vals.Add( e.Current.Value );
  }
 }

 public void OnAfterDeserialize()
 {
  this.Clear();

  int cnt = ( keys.Count<=vals.Count )? keys.Count : vals.Count;
  for (int i=0; i<cnt; ++i )
   this[keys[i]] = vals[i];

 }
}

// あとはDictionaryをDictに置き換えるだけで簡単にJsonUtility対応になる
// You only be replace Dictionary to Dict, then Easy use JsonUtility with Dictionary!
public class DictTest : MonoBehaviour {

 Dict<string,int> test = new Dict<string, int>{
  { "ABC", 123},
  { "DEFGHI", 456},
  { "JKL", 7891011}
 };
 
 string s = string.Empty;
 // Update is called once per frame
 void Update () {
  if( Input.GetKeyDown(KeyCode.T) ){
   s = JsonUtility.ToJson(test);
   Debug.Log("<color=#FF0000>" + s + "</color>");
  }
  
  if( Input.GetKeyDown(KeyCode.F) ){
   var d = JsonUtility.FromJson<Dict>(s);
   foreach( var _ in d ){
    Debug.Log("<color=#00FFFF>[" + _.Key + "]</color>" + _.Value);
   }
  }
 }
}

uGUI でドラッグやクリックされている間を判定する

uGUI のコンポーネントをドラッグやクリックしている最中かを判定したい時がある。

そんな時は、以下のようにすれば検知できるので、あとはコール先でフラグを立てるなりすればよい。

[方法]

・検知したい uGUI コンポーネントに「Inspector」から「AddComponent」で「Event>EventTrigger」を付与
 (Scriptから付けても構わない)

・Inspector の 「AddNewEventType」から取りたいタイミングを選択し、イベント発生時にコールしたいメソッドを設定する

Parent of RectTransform is being set with parent property. の警告対策

Unity5.5f3 にて uGUI を使用していると以下の警告が出た。


Parent of RectTransform is being set with parent property. Consider using the SetParent method instead, with the worldPositionStays argument set to false. This will retain local orientation and scale rather than world orientation and scale, which can prevent common UI scaling issues.



[原因]
uGUI のパーツは「Transform」ではなく「RectTransform」をコンポーネントに持っている。

それゆえ、普段のように

uguiObject.transform.parent = newParentObj;

とかしてしまうと「transform」で parent を決めるな!

RectTransform使え! と怒られるのである。




[対策]

警告の通り、

RectTransform を取得した上で「SetParent」メソッド+第二引数に「false」を設定して解決。

RectTransform rt = uguiObj.GetComponent();
if( rt )
rt.SetParent( newParentObj, false );


Unity で importing small assets と出て起動しなくなる

2DToolKitのサンプルプロジェクトを開いてから、「importing small assets」のプログレスが消えず

プロジェクトを開けなくなってしまったが、以下で解決。

1. alt を押しながら Unity を起動

2. 空のプロジェクトを適当に新規作成し、2D ToolKitをインポート

3. メニューの「2Dtoolkit」>「Preferences」を選択し、「Auto Rebuild」のチェックを外す

4. 上記設定さえ出来れば、空のプロジェクトは保存しないで後で消してしまって良い

5. OpenProject で起動しなくなっていたプロジェクトを開きなおして解決

Unity MonoDevelopで変なビルドエラーが出る

NGUI や 2DToolkit、WWW などさっきまで動いていたクラス名がどどっとエラーになってコンパイルされた時は、

MonoDevelop のビルドから一度クリーンをし終了する。

次に Unity のメニューから Assets > Sync MonoDevelop Project から

MonoDevelop を起動してやると大体直る。

C# で SJIS を UTF-8 にエンコードする方法

今回は Unity でテキスト(ShiftJIS)を読み込んだけど、UTF-8にしたかったというケースでの例
byte[] loadData;
   
using(FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read)){ 
 loadData = new byte[fileStream.Length];
 fileStream.Read(loadData , 0, loadData .Length);
}

Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
string sjisstr = sjisEnc.GetString(loadData);
byte[] bytesData = System.Text.Encoding.UTF8.GetBytes(sjisstr);
Encoding utf8Enc = Encoding.GetEncoding("UTF-8");
string utf = utf8Enc.GetString(bytesData);

Debug.Log ("Test = " + utf);

Texture の Tiling と Offset についてのメモ

Tiling は、テクスチャ全体を何枚表示するかを設定する。

X も Y も 2 とすれば、テクスチャ全体が縦横 2 回繰り返され計 4 枚に見える。

逆に X と Y を 0.5 とすれば、左下から半分までの表示となる。


スプライトのような 1 枚をアトラスとして、一部を切り出し UV をセットしたい場合は、

そのスプライトサイズに見合った値を入れる。

例)

128 x 128 のテクスチャに 16 x 16 ピクセルが 1 スプライトのアトラスを作った場合、

スプライトは、横 8 パターン 縦 8 パターン存在する事になる。

ここで、左から3つめ、上から1つめ(下から7つめ)のスプライトのUVをオフセットとタイリングで設定したい場合は、

Tiling は、 XY ともに 0.125 (1 / 横スプライト数8、縦も同様)

Offset は、 X = 0.25 (0.125*2)、 Y = 0.75 (0.125 * 6) となる。

オフセットは左下が原点なので Y を注意すること。





couldn't be created because there is no script with that name. が出る理由

Editor クラスを継承したクラスのコードが、

Assets/Editor 下にないと表示される。

該当ファイルは Editorフォルダを作成し、その中に入れるべし。

error CS1010: Newline in constant

文字コードを変更して保存できるテキストエディタ( Terapad 等)で

文字コードを UTF-8 (BOMなし) にして保存すれば直る。

UTF-8N ではエラーが出たのでメモ。

なお、改行コードは関係ないようだ。

GameView内のマウス座標を得る方法

GameView はサイズによってマウス座標の値も変動するようで、

640*960 のプロジェクトをテストする際、GameView のサイズを狭くしてテストすると

マウス座標もそのサイズに依存して変わっているような状態になって困ったのでメモ。



// カメラオブジェクトを取得する
// 今回の例は NGUIのカメラを指定しているが、他のカメラの時も名前を合わせればよい
GameObject obj  = transform.Find("/UI Root (2D)/Camera").gameObject;

// マウス座標を縦横各種 0~1.0f の範囲に変換
Vector3    mpos = (obj.GetComponent<Camera>()).ScreenToViewportPoint ( Input.mousePosition );

// スクリーンサイズにその範囲をかければスクリーン上の座標が求まる
float xpos = mpos.x * PlayerSettings.defaultScreenWidth;
float ypos = mpos.y * PlayerSettings.defaultScreenHeight;


こうすると GameView のリサイズを気にしないでも大丈夫っぽい。

UnityEditor 内のクラスを使用しているが、iOS 実機でも動くのかは未検証。

NGUI の UIPanel のサイズを知る方法

Unity 上の Clipping の Size に当たる部分は、


UIPanel  panel = (UIPanel) GameObject.Find("YourObj").GetComponent("UIPanel");

float    pw    = panel.clipRange.w;
float    ph    = panel.clipRange.z;


で取得する。

You can't place widgets on a layer different than the UIPanel that manages them. を解決する方法

スクリプトでアトラスプレハブを読み込み、

それを作成したスプライトに割り当てようとしたら

以下の警告が出たが、解決したのでメモ。

[Warning]
-----------------------------------------
You can't place widgets on a layer different than the UIPanel that manages them.
If you want to move widgets to a different layer, parent them to a new panel instead.
-----------------------------------------




// このコードは警告が表示される (This code is displayed warning.)
//---------------------------------------------------------------

GameObject obj = new GameObject ("SpriteObjName");
UISprite sp = obj.AddComponent <uisprite> ();

sp.atlas  = yourLoadedAtlas;
sp.spriteName  = "yourSpriteName";

obj.transform.parent = GameObject.Find("yourParentOfTheSprite").transform;



// このコードは大丈夫 (This code have not warning.)
//---------------------------------------------------------------
UISprite sp = NGUITools.AddSprite ( GameObject.Find("yourParentOfTheSprite"), yourLoadedAtlas, "SpriteObjName" );
sp.spriteName  ="yourSpriteName";

スプライトを作る時は NGUITools.AddSprite を使おう。

NGUI のアトラスプレハブをスクリプトから読み込む時


NGUI の AtlasMaker でアトラスとスプライトを作成すると、

プレハブとシェーダと統合画像が同名になる為、



GameObject prefab = GameObject.Instantiate ( Resources.Load("your atlas" );
のようにすると、Unity が正しく認識できない場合がある。

なので、この場合は
GameObject prefab = GameObject.Instantiate ( Resources.Load("your atlas", typeof (GameObject) );
と、後ろに GameObject の型指定のパラメータを付けてやる。

NGUI で新しいスプライトをアトラスに登録する方法

※ この記事を書いた時点での NGUI のバージョンは、「 2.6.4 」



1. 「メニュー」の「NGUI」 > 「Open the Atlas Maker」を選択。



2. 「Create」ボタンの右のテキストフォームに新しく作りたいアトラスセットの名前を入力し

「Create」ボタンを押すと、それ用のプレハブが作成される。



3. 自分でアトラス化した画像を使うのではなく、

このアトラスセットに画像 1 つ 1 つを登録すると NGUI 側で 1 枚のスプライトにまとめてくれる。

また、PNG で逐一用意せずとも、PSD ファイルのままで良い。



4. 「Project」ビューから追加したい画像をクリックすると、

AtlasMaker ウィンドウの下部にそのスプライト名が表示され、

緑の「Add/Update All」ボタンが出現するので、このボタンを押す事で

そのスプライトがアトラスセットに追加される。



5. UV などテクスチャ座標はNGUIがざっくり決めてくれるが、別途変更したい場合は、

Projectビューのアトラスのプレハブ( 立方体を斜め絡みたようなアイコン )をクリックし、

Inspectorの下の方にある「Dimensions」で設定する。

その下にある「Border」は Sliced スプライトにしたい時の境界線を決める。

「Sprite ▼」を押すと、アトラスセットに追加したスプライトの中から、

どのスプライトの情報を変更するかが選択できる。

なお、各数値はまとめられた画像に合わせたものとなる。元画像の座標云々は登録後は関係ない。

まとめられた画像を PhotoShop 等で開いて確認したければ、

「~~ atlas」というプレハブと同じ名前で画像も作成されているので、

Projectビューのそれを右クリックし、「Show in Explorer」した後、他のツールで開く事ができる。



これを繰り返して自分好みのアトラスセットを作成していく。