「Unity/UIImage/Mask」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→UIImageで逆マスクを使うサンプル) |
(→画面を覆うmaskサンプル) |
||
(同じ利用者による、間の7版が非表示) | |||
行21: | 行21: | ||
UnmaskImage/Unmaskが、○のUnmask | UnmaskImage/Unmaskが、○のUnmask | ||
UnmaskImage/Imageが、マスクされる画像 | UnmaskImage/Imageが、マスクされる画像 | ||
+ | |||
+ | UnmaskCoverImageのプレハブにUnmaskCoverImage.csを追加 | ||
+ | |||
+ | UnmaskCoverImage.cs | ||
<pre> | <pre> | ||
− | public class | + | 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() | |
− | + | ||
− | void | + | |
{ | { | ||
− | + | canvasObj = GameObject.Find("/Canvas"); | |
− | + | canvasWidth = canvasObj.GetComponent<RectTransform>().sizeDelta.x; | |
− | + | canvasHeight = canvasObj.GetComponent<RectTransform>().sizeDelta.y; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
float maxWH = Mathf.Max(canvasWidth, canvasHeight); | float maxWH = Mathf.Max(canvasWidth, canvasHeight); | ||
− | GameObject unmaskObj = | + | GameObject unmaskObj = this.transform.Find("Unmask").gameObject; |
unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWH, maxWH); | unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWH, maxWH); | ||
− | + | this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | |
} | } | ||
− | void | + | public void Close() |
{ | { | ||
− | + | this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | |
− | + | GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | GameObject unmaskImageImageObj = | + | |
unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | ||
− | + | GameObject unmaskObj = this.transform.Find("Unmask").gameObject; | |
− | GameObject unmaskObj = | + | |
float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x; | float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x; | ||
float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y; | float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y; | ||
float fromMaxWH = Mathf.Max(fromWidth, fromHeight); | float fromMaxWH = Mathf.Max(fromWidth, fromHeight); | ||
float toHeight = 1f; | float toHeight = 1f; | ||
− | float scale = toHeight / fromMaxWH * | + | // 中央から画面角までの距離(三平方の定理 |
+ | 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); | unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f); | ||
− | |||
} | } | ||
− | void | + | public void Open() |
{ | { | ||
− | + | this.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | |
− | + | GameObject unmaskImageImageObj = this.transform.Find("Image").gameObject; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | GameObject unmaskImageImageObj = | + | |
unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | unmaskImageImageObj.GetComponent<RectTransform>().sizeDelta = new Vector2(canvasWidth, canvasHeight); | ||
− | + | GameObject unmaskObj = this.transform.Find("Unmask").gameObject; | |
− | GameObject unmaskObj = | + | unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2(1f, 1f); |
− | unmaskObj.GetComponent<RectTransform>().sizeDelta = new Vector2( | + | |
float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x; | float fromWidth = unmaskObj.GetComponent<RectTransform>().sizeDelta.x; | ||
float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y; | float fromHeight = unmaskObj.GetComponent<RectTransform>().sizeDelta.y; | ||
float fromMaxWH = Mathf.Max(fromWidth, fromHeight); | float fromMaxWH = Mathf.Max(fromWidth, fromHeight); | ||
float toHeight = canvasHeight; | float toHeight = canvasHeight; | ||
− | float scale = toHeight / fromMaxWH * | + | // 中央から画面角までの距離(三平方の定理 |
+ | 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); | unmaskObj.transform.DOScale(new Vector3(scale, scale, 0f), 0.3f); | ||
} | } | ||
} | } | ||
+ | |||
</pre> | </pre> | ||
+ | |||
+ | ==unity2021のiOSで輪郭ががたがたになる問題== | ||
+ | SpliteMeshにチェックを入れると良い。 |
2022年7月3日 (日) 12:17時点における最新版
UIImageでマスクを使うサンプル
- Imageを作成して、"MaskImage"と名前に変更
- 上記オブジェクトをAddCompornentで、Maskを追加
- Maskされる画像を、Imageで作成して、階層を、"MaskImage"の子供とする
参考:https://kan-kikuchi.hatenablog.com/entry/Mask
公式UIでは、一部分だけを切り取るようなマスクはできない。
UIImageで逆マスクを使うサンプル
- githubにあるpluginをダウンロード、https://github.com/mob-sakai/UnmaskForUGUI
- DLした、UnmaskForUGUI-mainをまるっとAssetsの下へ
- 上のUIImageでマスクを使うサンプルを作る。
- 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にチェックを入れると良い。