LoginSignup
1
0

More than 3 years have passed since last update.

Unityで画像をソース上で動的に切り替える方法を色々試したけど、縮尺が変になる挙動が直らない

Posted at

Unity2019.3.0.a2と2018.4.0f1

2Dの話です。

画像が歪む

まずは画像を見てもらえると分かるのですが盾の画像がおかしなことになっています。
4つの盾は本来みんな同じ画像です。

2019.3.0.a2
unity_tate_2019.png

仕様

盾を表示するロジックとしては画像下部の装備欄をクリックするとアイテム欄(CardBoardという名前をつけています)が出てきて、選択すると装備欄に反映されます。
selected_card.png

ですが、この装備を何度か繰り返すと装備欄の画像の縮尺が変になってしまう不具合です。

原因調査

当然、ロジックがおかしいのか暗黙的に数値が変わっているのかと思いましたのでそのあたりを色々と試しました。

階層

動的に画像を切り替えるために以下のような階層にしました。

CanvasUI
  EquipmentCardField
    EquipmentCardBox0
      ImageInvisibleSprite
    EquipmentCardBox1
      ImageInvisibleSprite
    EquipmentCardBox2
      ImageInvisibleSprite
    EquipmentCardBox3
      ImageInvisibleSprite

CanvasUIが画面全体のCanvasです。
EquipmentCardFieldが画像下部の装備欄です。
EquipmentCardBox0,1,2,3が画像の下地になっているImageです。
ImageInvisibleSpriteはImageですがアルファ値をいじって透明になっています。画像はemptyという真っ白なものを初期でセットしています。

基本的にはImageInvisibleSpriteの画像emptyを別な画像に切り替えてアルファ値を1.0にして透明じゃなくす方法を取っています。

動的に画像を変更する

直接画像ファイルを読み込んで画像を変更する

EquipmentCardBox equipmentCardBox = _equipmentCardBoxs[index];
equipmentCardBox.Equip(actionCard);
GameObject childGameObject = _equipmentCardBoxs[index].transform.Find("ImageInvisibleSprite").gameObject;
Sprite sprite = Resources.Load<Sprite>(equipmentCardBox.GetImageFilePath());
Image childImage = childGameObject.GetComponent<Image>();
childImage.sprite = sprite;
childImage.SetAlpha( 1.0f );

_equipmentCardBoxsは長さ4のEquipmentCardBoxの配列です。
EquipmentCardBoxはEquipmentCardBox0~3に一つずつ関連付けています。
equipmentCardBoxが装備を行う欄の一つになります。
.Equip()で装備を行っています。
画面に表示されている拳や盾などはCardという名称をつけています。
ActionCardはCardBoardでクリックしたCardです。

childGameObjectがImageInvisibleSpriteのGameObjectになります。
Resources.Loadメソッドで画像ファイルのパスを指定してSpriteとして読み込んでいます。
childImage.sprite = sprite で画像の切り替えを行っています。
その下のchildImage.SetAlpha( 1.0f );でアルファ値を切り替えています。SetAlphaは拡張メソッドです。
名前の通りアルファ値を変えるためのメソッドです。

この方式で試したところ装備欄の画像は歪みました。

Texture2Dから新規にSpriteを生成して画像を変更する

EquipmentCardBox equipmentCardBox = _equipmentCardBoxs[index];
equipmentCardBox.Equip(actionCard);
GameObject childGameObject = _equipmentCardBoxs[index].transform.Find("ImageInvisibleSprite").gameObject;
Texture2D tex2d = Resources.Load(equipmentCardBox.GetImageFilePath()) as Texture2D;
Image childImage = childGameObject.GetComponent<Image>();
childImage.sprite =  Sprite.Create(tex2d, new Rect(0,0,tex2d.width,tex2d.height), Vector2.zero);
childImage.SetAlpha( 1.0f );

Resources.Load()でTexture2Dに変換してspriteの代入箇所でSprite.create()で新しいスプライトを生成しています。

この方式で試したところ装備欄の画像は歪みました。

GameObjectのコンポーネントのspriteを代入する

EquipmentCardBox equipmentCardBox = _equipmentCardBoxs[index];
equipmentCardBox.Equip(actionCard);
GameObject childGameObject = _equipmentCardBoxs[index].transform.Find("ImageInvisibleSprite").gameObject;
Image childImage = childGameObject.GetComponent<Image>();
childImage.sprite =  actionCard.gameObject.GetComponent<Image>().sprite;
childImage.SetAlpha( 1.0f );

直接Resourcesフォルダの画像を読むのを止めてクリックしたCardのGameObjectからspriteを取り出して代入させてます。

この方式で試したところ装備欄の画像は歪みました。

ScaleやSetNativeSizeを使う

childImage.rectTransform.localScale = new Vector3(1,1,1);
childImage.transform.localScale = new Vector3(1,1,1);
childImage.SetNativeSize();

上記の画像を切り替える方法でこれらのソースを組み合わせたパターンを試しましたがどれも同じ結果になりました。
装備欄の画像は歪みます。

数値を確認する

暗黙的にwidthやheight,scaleの数値が変わっているのかと思いPlayer再生中に値を確認したところ、何の変化もありませんでした。
見えてる値と実際の値が食い違っている可能性も考えてDebug.Log()で出力してみたところ、何の変化もありませんでした。

その他

他にも色々と試しましたが割愛します。

LTSを使ってみることに

UnityのLTSを調べてみました。一番新し目なLTSは2018.4.0f1でしたのでそこにパッケージをインポートして再作成。

何だか出来た。

2018.4.0f1
unity_tate_2018.png

色々装備を変更してこねくり回しても期待どおりの動作をしました。
満足。

左のウィンドウの色が変わっているのは単純に変えたものをキャプチャしただけです

まとめ

最新版を使うときは予期せぬ不具合があるかもしれないので気をつけたほうが良いかもしれないです。
本当は私の知らない仕様があってそういう挙動になっていしまっているのかもしれません。
私が分かったのはUnity 2018.4.0f1にしたら求めていた挙動になったということだけです。

分かりきったことではありますが、自分が詳しくないものを利用するときはLTSか安定版を使うのが無難ですね。

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0