ユースケース
- 同一のImageコンポーネントを使用して複数のSpriteを差し替えたい
- SpriteはAssetBundleもしくはResources等を利用して動的に取得するものとする
- どのSpriteにおいても、常に顔が同じ位置に存在してほしい
OK (顔の位置を中心点とした場合)
NG (Spriteの中心をそのまま中心点とした場合)
元の画像
- 顔の位置がそれぞれ左右に存在している
- そのためspriteの差し替えのみの対応だと画像の中心が顔の位置とならない
Spriteに対してpivot (中心点) を設定する
SpriteEditor上で設定する
- https://docs.unity3d.com/ja/current/Manual/SpriteEditor.html
-
(1) Pivot の種別を選択する
- 予め Center / Top Left ... etc といったpivot位置が用意されている
- この中の Custom を選択すれば任意の位置を指定することが出来る
-
(2) pivotの位置を指定する
- PivotをCustomに指定した上で、Editor上の矩形内の青丸を中心点に指定したい位置に合わせる
- もしくは CustomPivotの値を 0~1 の範囲で指定する
Editor拡張で設定する
- https://docs.unity3d.com/jp/current/ScriptReference/SpriteMetaData.html
- https://docs.unity3d.com/jp/current/ScriptReference/SpriteMetaData-alignment.html
- SpriteMetaDataを生成する際に、alignmentおよびpivotを設定する
- alignmentは整数で指定する必要がある
Center = 0、TopLeft = 1、TopCenter = 2、TopRight = 3、LeftCenter = 4、RightCenter = 5、BottomLeft = 6、BottomCenter = 7、BottomRight = 8、Custom = 9
サンプルコード
public static void Separate(string texturePath)
{
TextureImporter importer = TextureImporter.GetAtPath(texturePath) as TextureImporter;
// Update textureType
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Multiple;
importer.filterMode = FilterMode.Point;
EditorUtility.SetDirty(importer);
AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
// 別途 static な定義ファイルか csv 等にまとめると良い
SpriteMetaData[] sprites = new SpriteMetaData[]
{
new SpriteMetaData
{
name = "hoge",
rect = new Rect(0, 0, 100, 100),
alignment = 9,
pivot = new Vector2(0.5f, 0.5f)
}
};
importer.spritesheet = sprites;
EditorUtility.SetDirty(importer);
AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
}
RectTransformのpivotに適応する
- https://docs.unity3d.com/ja/current/ScriptReference/RectTransform.html
- RectTransform.pivotに0-1までの範囲を代入することにより、PosX/PosYを変更すること無く画像の中心点を変更することが出来る
注意点
- https://docs.unity3d.com/ja/current/ScriptReference/Sprite-pivot.html
- Sprite.pivotは0-1までの範囲ではなく、 設定した座標で返る という点に注意
- 使用するSpriteのサイズを (Sprite.rect.width / Sprite.rect.height) を使用して割合 (0-1) を求めた上で代入する必要がある点に注意
サンプルコード
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
[RequireComponent(typeof(Button))]
public class ChangeImage : MonoBehaviour
{
public Image image;
public string spriteName;
private Button button;
void Start()
{
this.button = this.GetComponent<Button>();
this.button.onClick.AddListener(Change);
}
void Change()
{
Sprite sprite = Resources.Load<Sprite>(this.spriteName);
this.image.sprite = sprite;
this.image.SetNativeSize();
this.image.GetComponent<RectTransform>().pivot = new Vector2(
sprite.pivot.x / sprite.rect.width,
sprite.pivot.y / sprite.rect.height
);
}
}
この作品はユニティちゃんライセンス条項の元に提供されています