3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】Scene や Prefab の編集中だけ Addressables な Sprite を Image にアタッチするコンポーネント

Last updated at Posted at 2023-09-04

概要

埋め込みの Scene や Prefab の Image に Addressables な Sprite を使いたいとき、直接参照すると Sprite は二重に保存されてしまいます。
そのため LocalizeSpriteEvent などで動的に Sprite を読み込み表示する必要がありますが、編集中に Sprite が表示されないため不便です。
対象の Sprite を一時的に参照して編集が終わったら外す方法もありますが、手間と外し忘れの恐れがあります。

そこで、Scene や Prefab の編集中だけ Addressables な Sprite を Image にアタッチする Editor 用のコンポーネントを作りました。
Scene, Prefab の保存中に Sprite を取り除き、保存後に Addressables のパスから Sprite を読み込んで実現しています。

コード

使い方

  1. 対象の Image にAddressableImageViewerEditorを追加
  2. AddressableImageViewerEditor の SpriteRef に Addressables な Sprite を追加

※既に Sprite がアタッチされている Image にAddressableImageViewerEditorを追加した際は、Sprite を Addressables 化します

image.png

プロパティ 説明
Image Sprite を反映する Image です
null のとき同じ gameObject に Image があったら自動で追加します
SpriteRef 表示する Sprite です
Image の SourceImage を変えると、SpriteRef も変わります
SpriteRef を変えると、Image の SourceImage も変わります
ClearSpriteButton SourceImage と SpriteRef を null にするボタンです
EditorXXX 実装の都合で SerializeField にした変数です
編集すると不具合の原因になります

実装メモ

前提として[ExecuteAlways]を有効にしています。

編集中だけアタッチする方法

PrefabStage.prefabSaving, EditorSceneManager.sceneSaving でアタッチを外し、PrefabStage.prefabSaved, EditorSceneManager.sceneSaved で再度アタッチしています。
Scene, Prefab の編集開始時は、Update() で editorIsNotReflected フラグを利用してアタッチしています。

Start() ではなく Update() を使う理由

Scene 上の GameObject から Prefab を作成すると、オリジナルの GameObject は消えて Prefab の Instance が生成されます。その Instance は Start() の後に Prefab の値を反映するようなので、Update() でアタッチしています。

保存中に OnValidate() を止める方法

OnValidate() は PrefabStage.prefabSaving と PrefabStage.prefabSaved の間にも呼ばれます。
つまり、prefabSaving 中に値を変更しても OnValidate() によって値が変わる恐れがあります。
そこで、prefabSaving で editorIsNotReflected フラグを有効に、prefabSaved でフラグを無効にして OnValidate() にフラグを使った早期リターンを作ることで値が変わらないようにしました。

その他

Prefab Variant による ImageSource の override はPrefabUtility.RevertPropertyOverride()で対処しています。
Prefab の生成直前に ImageSource を空にする事は難しいので、AssetPostprocessor.OnPostprocessAllAssets()で生成された Prefab を編集して ImageSource を空にしています。これにより Prefab の Import が僅かに遅くなる恐れがあります。
本当に ImageSource が空になっているか怪しい際は Scene, Prefab をテキストエディタで確認してください。不具合がありましたらコメントをいただけると助かります。

3
2
0

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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?