Vertx » Unity – Time PropertyDrawer
MENU
+61430642190

Unity – Time PropertyDrawer

I wanted an attribute to display time values so I coded one. It should cull irrelevant larger input fields if your specified maximum is lower than the values required in them.

The usage is with floats that represent seconds.

timer

//
using UnityEngine;
using System.Collections;

public class TimeAttribute : PropertyAttribute {
	public float clampMin;
	public float clampMax;

	public float clampMaxHours;
	public float clampMaxMins;
	public float clampMaxSecs;
	public float clampMaxMilli;

	public TimeAttribute (float minTimeSec, float maxTimeSec) {
		#region Clamp values
		if(!float.IsPositiveInfinity(maxTimeSec)){
			clampMaxHours = Mathf.FloorToInt(maxTimeSec / (float) (60 * 60));
			clampMaxMins = Mathf.FloorToInt(maxTimeSec / (float) (60));
			clampMaxSecs = Mathf.FloorToInt(maxTimeSec);
			clampMaxMilli = Mathf.FloorToInt(maxTimeSec*1000);
		} else {
			clampMaxHours = maxTimeSec;
			clampMaxMins = maxTimeSec;
			clampMaxSecs = maxTimeSec;
			clampMaxMilli = maxTimeSec;
		}

		clampMin = minTimeSec;
		clampMax = maxTimeSec;
		#endregion
	}
}
//
//
using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomPropertyDrawer(typeof(TimeAttribute))]
public class TimeAttributeDrawer : PropertyDrawer {
	public override void OnGUI (Rect position, SerializedProperty property, GUIContent label){
		TimeAttribute tA = attribute as TimeAttribute;
		DoTime (label, position, property, tA);
	}

	void DoTime (GUIContent label, Rect position, SerializedProperty property, TimeAttribute tA){
		#region Label
		float width = EditorGUIUtility.labelWidth;
		position.width -= width;
		Rect labelLeft = new Rect (position.x, position.y, width, position.height);
		EditorGUI.LabelField (labelLeft, label);
		#endregion

		#region Layout
		int c = 1;
		if (tA.clampMaxHours >= 1)
			c = 4;
		else if (tA.clampMaxMins >= 1)
			c = 3;
		else if (tA.clampMaxSecs >= 1)
			c = 2;
		float wLabel = 20;
		float w = ((position.width - wLabel*c) / (float)c);
		#endregion

		#region draw labels
		position = new Rect (labelLeft.xMax, position.y, w, position.height);
		int hoursLast = Mathf.FloorToInt (property.floatValue / (float)(60 * 60));
		int hours = hoursLast;
		if (c >= 4) {
			hours = (int)Mathf.Min (EditorGUI.IntField (position, hours), tA.clampMaxHours);
			position = new Rect (position.x + w, position.y, wLabel, position.height);
			GUI.Label (position, "h");
			position = new Rect (position.x + wLabel, position.y, w, position.height);
		}

		int minsLast = Mathf.FloorToInt (property.floatValue / (float)(60)) - (hoursLast * 60);
		int mins = minsLast;
		if (c >= 3) {
			mins = (int)Mathf.Min (EditorGUI.IntField (position, mins),  tA.clampMaxMins);
			position = new Rect (position.x + w, position.y, wLabel, position.height);
			GUI.Label (position, "m");
			position = new Rect (position.x + wLabel, position.y, w, position.height);
		}

		int secsLast = Mathf.FloorToInt (property.floatValue) - (hoursLast * 60 * 60) - (minsLast * 60);
		int secs = secsLast;
		if (c >= 2) {
			secs = (int)Mathf.Min (EditorGUI.IntField (position, secs), tA.clampMaxSecs);
			position = new Rect (position.x + w, position.y, wLabel, position.height);
			GUI.Label (position, "s");
			position = new Rect (position.x+wLabel, position.y, w, position.height);
		}

		float millisecs = Mathf.FloorToInt(property.floatValue * 1000) - (hoursLast * 60 * 60 * 1000) - (minsLast * 60 * 1000) - (secsLast * 1000);
		millisecs = Mathf.Min(EditorGUI.FloatField (position, millisecs), tA.clampMaxMilli);
		position = new Rect (position.x+w, position.y, wLabel+5, position.height);
		GUI.Label (position, "ms");
		#endregion

		float timeTotal = Mathf.Clamp( (hours * 60 * 60) + (mins * 60) + secs + (millisecs / 1000f), tA.clampMin, tA.clampMax);
		property.floatValue = timeTotal;
	}
}
//

Sorry, the comment form is closed at this time.