時間をエディタ上で操作したい、ということはままあると思う。
- プログラムではDateTimeで扱いたい
- ただそのままだとDateTimeはシリアライズ出来ないので、文字列で定義してDateTimeへパースする
- もしくはエディタ拡張で時間操作可能なGUIを表示する、等
ずっとなんかスマートに出来ないかなぁ、と思ってたので、「エディタ上では文字列で操作出来て」「プログラムではDateTimeをそのまま使える」クラスを作ってみた。
SerializableDateTime.cs
using UnityEngine;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
[Serializable]
public class SerializableDateTime : ISerializationCallbackReceiver
{
const string Format = "yyyy-MM-dd HH:mm:ss";
public DateTime Value;
[SerializeField] string text;
public SerializableDateTime() : this(new DateTime()) { }
public SerializableDateTime(DateTime value)
{
Set(value);
}
public static implicit operator SerializableDateTime(DateTime value)
{
return new SerializableDateTime(value);
}
void Set(DateTime value)
{
Value = value;
text = ToString();
}
public void OnAfterDeserialize()
{
DateTime newValue;
if(DateTime.TryParse(text, out newValue))
{
Set(newValue);
}
else
{
Set(Value);
}
}
public void OnBeforeSerialize() { }
public override string ToString()
{
return Value.ToString(Format);
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(SerializableDateTime))]
class SerializableDateTimeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.PropertyField(position, property.FindPropertyRelative("text"), label);
}
}
#endif
Test.cs
using UnityEngine;
using System;
public class Test : MonoBehaviour
{
[SerializeField] SerializableDateTime startTime = new DateTime(2018, 3, 9);
[SerializeField] SerializableDateTime endTime = new DateTime(2018, 9, 2);
void Start()
{
DateTime t0 = startTime.Value;
DateTime t1 = endTime.Value;
}
}
原理としては、文字列のシリアライズ変数(text)を定義して、エディタ拡張でそれを操作するGUIを表示する。
textの値がエディタ上で変更された場合、クラスのシリアライズ処理が呼ばれるので、そのコールバック内でDateTimeの値を更新する。
ISerializationCallbackReceiver がシリアライズ時に呼ばれるコールバックインターフェイス。
型変換演算子(implicit)を定義してるので、定義時にDateTimeをそのまま使えるようにしてる。
ValueがDateTimeの値。
エディタ上では時間にパース可能な文字列が指定された場合は変更される。
変な文字列を入力した場合は、変更不可能(変更前の値に戻す)。
最後に
全然関係ないけど、最近Go言語を触ってて、これが結構いい感じ♪
GAEとGo言語でアプリのサーバを作ってみようかと考えてるこの頃(´・ω・`)
〜オセロを作りながらゲームのプログラムを学ぼう〜