facebook twitter hatena line email

「Unity/UIImage/Mask」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(画面を覆うmaskサンプル)
 
(同じ利用者による、間の8版が非表示)
行16: 行16:
  
 
参考:https://kan-kikuchi.hatenablog.com/entry/UnmaskForUGUI
 
参考:https://kan-kikuchi.hatenablog.com/entry/UnmaskForUGUI
 +
 +
==画面を覆うmaskサンプル==
 +
UnmaskImageをResourcesへおいて、
 +
UnmaskImage/Unmaskが、○のUnmask
 +
UnmaskImage/Imageが、マスクされる画像
 +
 +
UnmaskCoverImageのプレハブにUnmaskCoverImage.csを追加
 +
 +
UnmaskCoverImage.cs
 +
<pre>
 +
using UnityEngine;
 +
using DG.Tweening;
 +
 +
/**
 +
* Cover開閉
 +
* UnmaskForUGUIのplugin必須
 +
* DoTweenのplugin必須
 +
* e.g.
 +
    UnmaskCoverImage unmaskCoverImage;
 +
    GameObject prefab = (GameObject)Resources.Load("UnmaskCoverImage");
 +
    GameObject canvasObj = GameObject.Find("/Canvas");
 +
    unmaskCoverImageObj = Instantiate(prefab, Vector3.zero, Quaternion.identity, canvasObj.transform);
 +
    unmaskCoverImageObj.name = "UnmaskCoverImage";
 +
    unmaskCoverImageObj.transform.localPosition = Vector3.zero;
 +
    unmaskCoverImageObj.transform.localRotation = Quaternion.Euler(0, 0, 0);
 +
    unmaskCoverImage = unmaskCoverImageObj.GetComponent<UnmaskCoverImage>();
 +
    unmaskCoverImage.Init();
 +
    unmaskCoverImage.Open(); // 開く場合
 +
    unmaskCoverImage.Close(); // 閉じる場合
 +
Canvasから比率を計算してるのでRenderModeがWorldSpaceなCanvasが必須
 +
*/
 +
public class UnmaskCoverImage : MonoBehaviour
 +
{
 +
    // UnmaskCoverImageのprefabの値で上書きされる
 +
    GameObject canvasObj;
 +
    float canvasWidth;
 +
    float canvasHeight;
 +
 +
    public void Init()
 +
    {
 +
        canvasObj = GameObject.Find("/Canvas");
 +
        canvasWidth = canvasObj.GetComponent<RectTransform>().sizeDelta.x;
 +
        canvasHeight = canvasObj.GetComponent<RectTransform>().sizeDelta.y;
 +
        float maxWH = Mathf.Max(canvasWidth, canvasHeight);
 +
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
 +
        unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWH, maxWH);
 +
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
 +
    }
 +
    public void Close()
 +
    {
 +
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
 +
        GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject;
 +
        unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
 +
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
 +
        float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x;
 +
        float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y;
 +
        float fromMaxWH = Mathf.Max(fromWidth, fromHeight);
 +
        float toHeight = 1f;
 +
        // 中央から画面角までの距離(三平方の定理
 +
        float centerLength = Mathf.Sqrt(Mathf.Pow(fromWidth, 2f) + Mathf.Pow(fromHeight, 2f));
 +
        float centerScale = centerLength / fromMaxWH;
 +
        float scale = toHeight / fromMaxWH * centerScale;
 +
        unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f);
 +
    }
 +
    public void Open()
 +
    {
 +
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
 +
        GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject;
 +
        unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
 +
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
 +
        unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(1f, 1f);
 +
        float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x;
 +
        float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y;
 +
        float fromMaxWH = Mathf.Max(fromWidth, fromHeight);
 +
        float toHeight = canvasHeight;
 +
        // 中央から画面角までの距離(三平方の定理
 +
        float centerLength = Mathf.Sqrt(Mathf.Pow(fromWidth, 2f) + Mathf.Pow(fromHeight, 2f));
 +
        float centerScale = centerLength / fromMaxWH;
 +
        float scale = toHeight / fromMaxWH * centerScale;
 +
        unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f);
 +
    }
 +
 +
}
 +
 +
</pre>
 +
 +
==unity2021のiOSで輪郭ががたがたになる問題==
 +
SpliteMeshにチェックを入れると良い。

2022年7月3日 (日) 12:17時点における最新版

UIImageでマスクを使うサンプル

  1. Imageを作成して、"MaskImage"と名前に変更
  2. 上記オブジェクトをAddCompornentで、Maskを追加
  3. Maskされる画像を、Imageで作成して、階層を、"MaskImage"の子供とする

参考:https://kan-kikuchi.hatenablog.com/entry/Mask

公式UIでは、一部分だけを切り取るようなマスクはできない。

UIImageで逆マスクを使うサンプル

  1. githubにあるpluginをダウンロード、https://github.com/mob-sakai/UnmaskForUGUI
  2. DLした、UnmaskForUGUI-mainをまるっとAssetsの下へ
  3. 上のUIImageでマスクを使うサンプルを作る。
  4. MaskImageの下に、空のGameObjectを作り、ImageとUnmaskをAddCompornentする。

参考:https://kan-kikuchi.hatenablog.com/entry/UnmaskForUGUI

画面を覆うmaskサンプル

UnmaskImageをResourcesへおいて、 UnmaskImage/Unmaskが、○のUnmask UnmaskImage/Imageが、マスクされる画像

UnmaskCoverImageのプレハブにUnmaskCoverImage.csを追加

UnmaskCoverImage.cs

using UnityEngine;
using DG.Tweening;

/**
 * Cover開閉
 * UnmaskForUGUIのplugin必須
 * DoTweenのplugin必須
 * e.g.
    UnmaskCoverImage unmaskCoverImage;
    GameObject prefab = (GameObject)Resources.Load("UnmaskCoverImage");
    GameObject canvasObj = GameObject.Find("/Canvas");
    unmaskCoverImageObj = Instantiate(prefab, Vector3.zero, Quaternion.identity, canvasObj.transform);
    unmaskCoverImageObj.name = "UnmaskCoverImage";
    unmaskCoverImageObj.transform.localPosition = Vector3.zero;
    unmaskCoverImageObj.transform.localRotation = Quaternion.Euler(0, 0, 0);
    unmaskCoverImage = unmaskCoverImageObj.GetComponent<UnmaskCoverImage>();
    unmaskCoverImage.Init();
    unmaskCoverImage.Open(); // 開く場合
    unmaskCoverImage.Close(); // 閉じる場合
 Canvasから比率を計算してるのでRenderModeがWorldSpaceなCanvasが必須
*/
public class UnmaskCoverImage : MonoBehaviour
{
    // UnmaskCoverImageのprefabの値で上書きされる
    GameObject canvasObj;
    float canvasWidth;
    float canvasHeight;

    public void Init()
    {
        canvasObj = GameObject.Find("/Canvas");
        canvasWidth = canvasObj.GetComponent<RectTransform>().sizeDelta.x;
        canvasHeight = canvasObj.GetComponent<RectTransform>().sizeDelta.y;
        float maxWH = Mathf.Max(canvasWidth, canvasHeight);
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
        unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWH, maxWH);
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
    }
    public void Close()
    {
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
        GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject;
        unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
        float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x;
        float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y;
        float fromMaxWH = Mathf.Max(fromWidth, fromHeight);
        float toHeight = 1f;
        // 中央から画面角までの距離(三平方の定理
        float centerLength = Mathf.Sqrt(Mathf.Pow(fromWidth, 2f) + Mathf.Pow(fromHeight, 2f));
        float centerScale = centerLength / fromMaxWH;
        float scale = toHeight / fromMaxWH * centerScale;
        unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f);
    }
    public void Open()
    {
        this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
        GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject;
        unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight);
        GameObject unmaskObj = this.transform.Find("Unmask").gameObject;
        unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(1f, 1f);
        float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x;
        float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y;
        float fromMaxWH = Mathf.Max(fromWidth, fromHeight);
        float toHeight = canvasHeight;
        // 中央から画面角までの距離(三平方の定理
        float centerLength = Mathf.Sqrt(Mathf.Pow(fromWidth, 2f) + Mathf.Pow(fromHeight, 2f));
        float centerScale = centerLength / fromMaxWH;
        float scale = toHeight / fromMaxWH * centerScale;
        unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f);
    }

}

unity2021のiOSで輪郭ががたがたになる問題

SpliteMeshにチェックを入れると良い。