Instantly share code, notes, and snippets.
Last active
June 4, 2016 04:39
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save anzfactory/9cd17f02386b2708e99c9b783b60ea1e to your computer and use it in GitHub Desktop.
タップすると子ボタンを展開して表示するやつ http://anz-note.tumblr.com/post/145208947906
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
* フロートメニューっていうかあれの展開(笑) | |
* with DOTween | |
*********************************/ | |
using System; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using UnityEngine.Events; | |
using DG.Tweening; | |
[RequireComponent(typeof(Image))] | |
public class ExpandButton : MonoBehaviour | |
{ | |
/// <summary> | |
/// 展開時の画像(optional) | |
/// </summary> | |
[SerializeField] private Sprite expandedImage; | |
/// <summary> | |
/// 小ボタンの設定 | |
/// </summary> | |
[SerializeField] private Setting[] settings; | |
private RectTransform rectTransform; | |
private Image image; | |
private List<GameObject> children; | |
private bool isExpanded = false; | |
private Sprite sourceImage; | |
/// <summary> | |
/// 子ボタンの設定 | |
/// </summary> | |
/// <value>The settings.</value> | |
public Setting[] Settings { | |
get { return this.settings; } | |
set { | |
this.settings = value; | |
BuildChildren(); | |
} | |
} | |
/// <summary> | |
/// メニュー展開済みか | |
/// </summary> | |
/// <value><c>true</c> if this instance is expanded; otherwise, <c>false</c>.</value> | |
public bool IsExpanded { | |
get { return this.isExpanded; } | |
} | |
private void Awake() | |
{ | |
this.rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
this.image = this.gameObject.GetComponent<Image>(); | |
this.children = new List<GameObject>(); | |
} | |
private void Start() | |
{ | |
this.sourceImage = this.image.sprite; | |
BuildChildren(); | |
} | |
/// <summary> | |
/// タップ時にトグルさせる | |
/// </summary> | |
public void OnTap() | |
{ | |
if (!this.isExpanded) { | |
Expand(); | |
} else { | |
Collapse(); | |
} | |
} | |
/// <summary> | |
/// 子ボタン展開 | |
/// </summary> | |
public void Expand() | |
{ | |
if (this.isExpanded) { | |
return; | |
} | |
this.isExpanded = true; | |
for (int i = 0; i < this.children.Count; i++) { | |
this.children[i].SetActive(true); | |
var seq = DOTween.Sequence(); | |
seq.Append( | |
this.children[i].GetComponent<RectTransform>() | |
.DOLocalMoveY(this.rectTransform.rect.height * (i + 1), 0.3f) | |
.SetEase(Ease.OutCirc) | |
); | |
var img = this.children[i].GetComponent<Image>(); | |
seq.Join( | |
DOTween.To( | |
() => img.color, | |
c => img.color = c, | |
new Color(1, 1, 1, 1), | |
0.2f | |
).SetEase(Ease.OutCirc) | |
); | |
} | |
// 展開時の画像が設定されていたら差し替える | |
if (this.expandedImage != null) { | |
this.image.sprite = this.expandedImage; | |
} | |
} | |
/// <summary> | |
/// 子ボタン閉じる | |
/// </summary> | |
public void Collapse() | |
{ | |
if (!this.isExpanded) { | |
return; | |
} | |
this.isExpanded = false; | |
for (int i = this.children.Count - 1; i >= 0; i--) { | |
var child = this.children[i]; | |
var seq = DOTween.Sequence(); | |
seq.Append( | |
child.GetComponent<RectTransform>() | |
.DOLocalMoveY(0, 0.2f) | |
.SetEase(Ease.OutCirc) | |
.OnComplete(()=>{ | |
child.SetActive(false); | |
}) | |
); | |
var img = this.children[i].GetComponent<Image>(); | |
seq.Join( | |
DOTween.To( | |
() => img.color, | |
c => img.color = c, | |
new Color(1, 1, 1, 0), | |
0.15f | |
).SetEase(Ease.OutCirc) | |
); | |
} | |
// 展開時の画像が設定されていたら差し替えられているので戻す | |
if (this.expandedImage) { | |
this.image.sprite = this.sourceImage; | |
} | |
} | |
/// <summary> | |
/// 子ボタンを指定された設定にしたがって構築 | |
/// </summary> | |
private void BuildChildren() | |
{ | |
ClearAll(); | |
// 先に設定されたものを全面にしたいので | |
// 逆(後ろ)から作っていく | |
for (int i = this.settings.Length - 1; i >= 0; i--) { | |
var setting = this.settings[i]; | |
var gameObject = new GameObject("Child Button"); | |
// サイズ | |
var rectTransform = gameObject.AddComponent<RectTransform>(); | |
rectTransform.position = this.rectTransform.position; | |
rectTransform.sizeDelta = new Vector2( | |
this.rectTransform.rect.width * setting.Scale, | |
this.rectTransform.rect.height * setting.Scale | |
); | |
// 画像 | |
var image = gameObject.AddComponent<Image>(); | |
image.sprite = setting.Image; | |
image.color = new Color(1, 1, 1, 0); | |
// タップイベント | |
var button = gameObject.AddComponent<Button>(); | |
button.targetGraphic = image; | |
button.onClick.AddListener(delegate { | |
OnTapChild(setting); | |
}); | |
gameObject.transform.SetParent(this.gameObject.transform); | |
gameObject.SetActive(false); | |
this.children.Add(gameObject); | |
} | |
this.children.Reverse(); | |
} | |
/// <summary> | |
/// 子ボタンを全クリ | |
/// </summary> | |
private void ClearAll() | |
{ | |
foreach (var gameObject in this.children) { | |
Destroy(gameObject); | |
} | |
this.children.Clear(); | |
} | |
/// <summary> | |
/// 子ボタンタップ時のハンドリング | |
/// </summary> | |
/// <param name="setting">Setting.</param> | |
private void OnTapChild(Setting setting) | |
{ | |
if (setting.OnTap != null) { | |
setting.OnTap.Invoke(); | |
} | |
Collapse(); | |
} | |
} | |
[Serializable] | |
public class Setting | |
{ | |
public Sprite Image; | |
public float Scale = 1.0f; | |
public UnityEvent OnTap; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment