Last active
November 23, 2019 12:35
-
-
Save anzfactory/f9a7ef0591e2cb19ea1de7b76e9ecc1b to your computer and use it in GitHub Desktop.
会話イベントをタイムライン風に表示するやーつ http://anz-note.tumblr.com/post/145359548501
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
/********************************* | |
* 会話イベントをタイムライン風に表示するやーつ | |
* 参考:http://tsubakit1.hateblo.jp/entry/2015/10/19/022720 | |
*********************************/ | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
public class Talk : MonoBehaviour | |
{ | |
[SerializeField] private RectOffset elementPadding; | |
[SerializeField] private float elementSpace = 5f; | |
[SerializeField] private Sprite iconFrame; | |
[SerializeField] private Vector2 iconSize = new Vector2(40, 40); | |
[SerializeField] private Vector2 iconPadding = new Vector2(2, 2); | |
[SerializeField] private Sprite messageFrame; | |
[SerializeField] private Font messageFont; | |
[SerializeField] private Color messageColor = Color.white; | |
[SerializeField] private int messageFontSize = 14; | |
[SerializeField] private RectOffset messagePadding; | |
private RectTransform rectTransform; | |
private TalkItem talkItemTemplate; | |
private List<TalkItem> talkItems; | |
private void Awake() | |
{ | |
this.rectTransform = this.gameObject.GetComponent<RectTransform>(); | |
this.talkItems = new List<TalkItem>(); | |
} | |
private void Start() | |
{ | |
// 自動サイズ調整に必要なコンポーネントをセットしていく | |
var verticalLayout = this.gameObject.AddComponent<VerticalLayoutGroup>(); | |
verticalLayout.childForceExpandHeight = false; | |
verticalLayout.padding = this.elementPadding; | |
verticalLayout.spacing = this.elementSpace; | |
var contentSizeFitter = this.gameObject.AddComponent<ContentSizeFitter>(); | |
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; | |
// テンプレートアイテム作成 | |
this.talkItemTemplate = CreateTemplate(); | |
} | |
/// <summary> | |
/// メッセージ追加(アイコン無し。地の文とか用) | |
/// </summary> | |
/// <returns>The message.</returns> | |
/// <param name="message">Message.</param> | |
public GameObject AddMessage(string message) | |
{ | |
return AddMessage(message, null, TalkItem.ItemTypes.IconNone, false); | |
} | |
/// <summary> | |
/// メッセージ追加(アイコンは左指定) | |
/// </summary> | |
/// <returns>The message.</returns> | |
/// <param name="message">Message.</param> | |
/// <param name="icon">Icon.</param> | |
public GameObject AddMessage(string message, Sprite icon) | |
{ | |
return AddMessage(message, icon, TalkItem.ItemTypes.IconLeft, false); | |
} | |
/// <summary> | |
/// メッセージ追加 | |
/// </summary> | |
/// <returns>The message.</returns> | |
/// <param name="message">Message.</param> | |
/// <param name="icon">Icon.</param> | |
/// <param name="itemType">Item type.</param> | |
public GameObject AddMessage(string message, Sprite icon, TalkItem.ItemTypes itemType) | |
{ | |
return AddMessage(message, icon, itemType, false); | |
} | |
public GameObject AddMessage(string message, Sprite icon, TalkItem.ItemTypes itemType, bool isIconFlip) | |
{ | |
GameObject newTalkItemObject = Instantiate(this.talkItemTemplate.gameObject) as GameObject; | |
newTalkItemObject.transform.SetParent(this.gameObject.transform); | |
newTalkItemObject.SetActive(true); | |
TalkItem newTalkItem = newTalkItemObject.GetComponent<TalkItem>(); | |
newTalkItem.ItemType = itemType; | |
if (itemType != TalkItem.ItemTypes.IconNone) { | |
if (isIconFlip) { | |
newTalkItem.Icon.rectTransform.Rotate(new Vector3(0f, 180f, 0f)); | |
} | |
newTalkItem.Icon.sprite = icon; | |
} | |
newTalkItem.Message.text = message; | |
this.talkItems.Add(newTalkItem); | |
return newTalkItemObject; | |
} | |
/// <summary> | |
/// 全メッセージクリア | |
/// </summary> | |
public void Clear() | |
{ | |
foreach (var item in this.talkItems) { | |
Destroy(item.gameObject); | |
} | |
this.talkItems.Clear(); | |
} | |
/// <summary> | |
/// テンプレート作成 | |
/// </summary> | |
/// <returns>The template.</returns> | |
private TalkItem CreateTemplate() | |
{ | |
var gameObject = new GameObject("Template"); | |
gameObject.transform.SetParent(this.gameObject.transform); | |
var rectTransform = gameObject.AddComponent<RectTransform>(); | |
rectTransform.sizeDelta = new Vector2( | |
this.rectTransform.rect.width, // 横幅いっぱい | |
this.iconSize.y // 高さはとりあえずアイコンで | |
); | |
rectTransform.localPosition = new Vector2(0f, 0f); | |
// 必要なデータを渡して作成 | |
TalkItem.Param param = new TalkItem.Param(); | |
param.FullRect = this.rectTransform.rect; | |
param.IconSize = this.iconSize; | |
param.IconFrame = this.iconFrame; | |
param.IconPadding = this.iconPadding; | |
param.MessagePadding = this.messagePadding; | |
param.MessageFont = this.messageFont; | |
param.MessageFontSize = this.messageFontSize; | |
param.MessageColor = this.messageColor; | |
param.MessageFrame = this.messageFrame; | |
TalkItem item = gameObject.AddComponent<TalkItem>(); | |
item.Build(param); | |
gameObject.SetActive(false); // テンプレートなので非活性 | |
return item; | |
} | |
} |
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
/********************************* | |
* 会話イベントをタイムライン風に表示するやーつ(要素) | |
* http://tsubakit1.hateblo.jp/entry/2015/10/19/022720 | |
*********************************/ | |
using UnityEngine; | |
using UnityEngine.UI; | |
public class TalkItem : MonoBehaviour | |
{ | |
public enum ItemTypes | |
{ | |
IconLeft, | |
IconRight, | |
IconNone | |
} | |
[SerializeField] private Image iconFrame; | |
[SerializeField] private Image icon; | |
[SerializeField] private Text message; | |
[SerializeField] private Image messageFrame; | |
public Image IconFrame { | |
get { return this.iconFrame; } | |
} | |
public Image Icon { | |
get { return this.icon; } | |
} | |
public Text Message { | |
get { return this.message; } | |
} | |
public Image MessageFrame { | |
get { return this.messageFrame; } | |
} | |
private ItemTypes itemType; | |
public ItemTypes ItemType { | |
get { return this.itemType; } | |
set { | |
this.itemType = value; | |
SwitchType(this.itemType); | |
} | |
} | |
/// <summary> | |
/// まっさらなGameObjectにTalkItemとしてアイコン/メッセージなど作成 | |
/// </summary> | |
/// <param name="param">Parameter.</param> | |
public void Build(Param param) { | |
var horizontalLayout = this.gameObject.AddComponent<HorizontalLayoutGroup>(); | |
horizontalLayout.spacing = 3f; | |
horizontalLayout.childForceExpandWidth = false; | |
horizontalLayout.childForceExpandHeight = false; | |
// icon frame | |
var iconFrameObject = CreateGameObject("IconFrame", gameObject); | |
var iconFrameRect = iconFrameObject.AddComponent<RectTransform>(); | |
iconFrameRect.sizeDelta = new Vector2(param.IconSize.x, param.IconSize.y); | |
iconFrameRect.localPosition = new Vector2( | |
(param.FullRect.width * -0.5f) + (param.IconSize.x * 0.5f), | |
0f | |
); | |
this.iconFrame = iconFrameObject.AddComponent<Image>(); | |
this.iconFrame.type = Image.Type.Sliced; | |
this.iconFrame.sprite = param.IconFrame; | |
var iconLayoutElement = iconFrameObject.AddComponent<LayoutElement>(); | |
iconLayoutElement.minWidth = param.IconSize.x; | |
iconLayoutElement.minHeight = param.IconSize.y; | |
// icon | |
var iconObject = CreateGameObject("Icon", iconFrameObject); | |
var iconRect = iconObject.AddComponent<RectTransform>(); | |
iconRect.anchorMin = Vector2.zero; | |
iconRect.anchorMax = new Vector2(1f, 1f); | |
iconRect.sizeDelta = new Vector2( | |
param.IconPadding.x * -2f, | |
param.IconPadding.y * -2f | |
); | |
iconRect.localPosition = Vector2.zero; | |
this.icon = iconObject.AddComponent<Image>(); | |
// message frame | |
var messageFrameObject = CreateGameObject("MessageFrame", gameObject); | |
var messageFrameRect = messageFrameObject.AddComponent<RectTransform>(); | |
messageFrameRect.sizeDelta = new Vector2( | |
param.FullRect.width - param.IconSize.x, | |
param.IconSize.y // 高さはとりあえずアイコンに合わせておく | |
); | |
messageFrameRect.localPosition = new Vector2( | |
(param.FullRect.width * 0.5f) - (messageFrameRect.rect.width * 0.5f), | |
0f | |
); | |
var verticalLayout = messageFrameObject.AddComponent<VerticalLayoutGroup>(); | |
verticalLayout.padding = param.MessagePadding; | |
this.messageFrame = messageFrameObject.AddComponent<Image>(); | |
this.messageFrame.type = Image.Type.Sliced; | |
if (param.MessageFrame != null) { | |
this.messageFrame.sprite = param.MessageFrame; | |
} else { | |
this.messageFrame.enabled = false; | |
} | |
// message | |
var messageObject = CreateGameObject("Message", messageFrameObject); | |
var messageRect = messageObject.AddComponent<RectTransform>(); | |
messageRect.localPosition = Vector2.zero; | |
this.message = messageObject.AddComponent<Text>(); | |
this.message.font = param.MessageFont; | |
this.message.fontSize = param.MessageFontSize; | |
this.message.color = param.MessageColor; | |
} | |
/// <summary> | |
/// GameObject作成&親設定 | |
/// </summary> | |
/// <returns>The game object.</returns> | |
/// <param name="name">Name.</param> | |
/// <param name="parent">Parent.</param> | |
private GameObject CreateGameObject(string name, GameObject parent) | |
{ | |
var gameObject = new GameObject(name); | |
gameObject.transform.SetParent(parent.transform); | |
return gameObject; | |
} | |
/// <summary> | |
/// ItemTypeが切り替わった時の要素変更 | |
/// </summary> | |
/// <param name="newType">New type.</param> | |
private void SwitchType(ItemTypes newType) | |
{ | |
switch (newType) { | |
case ItemTypes.IconLeft: | |
var newMessageFrame = Instantiate(this.messageFrame) as Image; | |
Destroy(this.messageFrame.gameObject); | |
newMessageFrame.gameObject.transform.SetParent(this.gameObject.transform); | |
this.messageFrame = newMessageFrame; | |
this.message = newMessageFrame.transform.GetChild(0).GetComponent<Text>(); | |
break; | |
case ItemTypes.IconRight: | |
var newIconFrame = Instantiate(this.iconFrame) as Image; | |
Destroy(this.iconFrame.gameObject); | |
newIconFrame.gameObject.transform.SetParent(this.gameObject.transform); | |
this.iconFrame = newIconFrame; | |
this.icon = newIconFrame.transform.GetChild(0).GetComponent<Image>(); | |
break; | |
case ItemTypes.IconNone: | |
Destroy(this.iconFrame.gameObject); | |
this.messageFrame.enabled = false; | |
break; | |
} | |
} | |
/// <summary> | |
/// データやり取り用 | |
/// </summary> | |
public struct Param { | |
public Rect FullRect; | |
public Vector2 IconSize; | |
public Sprite IconFrame; | |
public Vector2 IconPadding; | |
public Sprite MessageFrame; | |
public RectOffset MessagePadding; | |
public Font MessageFont; | |
public int MessageFontSize; | |
public Color MessageColor; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment