[Unity] SpriteEditor上で設定したpivotをImageコンポーネントにおけるSprite差し替え時に適応する

## ユースケース
- 同一のImageコンポーネントを使用して複数のSpriteを差し替えたい
- SpriteはAssetBundleもしくはResources等を利用して動的に取得するものとする
- どのSpriteにおいても、常に顔が同じ位置に存在してほしい

### OK (顔の位置を中心点とした場合)
![ok_change_image.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/98ead98d-02e7-eb72-b4c2-053dd33aaeda.gif)

### NG (Spriteの中心をそのまま中心点とした場合)
![ng_change_image.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/c8a200cc-6d62-dcd1-1e71-af184fbedbfc.gif)

### 元の画像
- 顔の位置がそれぞれ左右に存在している
- そのためspriteの差し替えのみの対応だと画像の中心が顔の位置とならない

![image](https://qiita-image-store.s3.amazonaws.com/0/102664/fc539339-b4b3-bebc-db91-62fb7fd46fbc.png)

## 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 の範囲で指定する

![spriteeditor.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/04f468e9-12a6-a09e-9ae8-48d613c0ee9d.gif)


### 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
```

### サンプルコード
- 参考: [[Unity] 1枚の画像を用途毎にサイズを指定して分割したい(SpriteEditor/エディタ拡張)](http://qiita.com/lycoris102/items/ee046b44578c8f6fb748#%E3%82%B3%E3%83%BC%E3%83%89) から抜粋

```csharp
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) を求めた上で代入する必要がある点に注意


![sprite_pivot.png](https://qiita-image-store.s3.amazonaws.com/0/102664/63fecf46-9838-79b7-8fb8-c5fd6f32c4c1.png)

### サンプルコード
```csharp
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
        );
    }
}
```

![ok_change_image.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/98ead98d-02e7-eb72-b4c2-053dd33aaeda.gif)

---

<div><img src="http://unity-chan.com/images/imageLicenseLogo.png" alt="ユニティちゃんライセンス"><p>この作品は<a href="http://unity-chan.com/contents/license_jp/" target="_blank">ユニティちゃんライセンス条項</a>の元に提供されています</p></div>