かつて代官山らへんで働いてたengineerのUnityブログ

サーバサイドやってきたエンジニアがUnityとか触って遊ぶだけのブログ

【Unity】ボタンを押下させる間隔を制限する【連打防止】

ボタン押下時にデータをリストで取得するなどの重めの通信を走らせてたりすると、連打制限したいなって時ありますよね 絶対連打する人いるし....
最低限で簡単な実装ですが、今後も使いまわせそうなので載せておきます
アレンジして使っていきましょう

// ボタン押下許可フラグ
private bool isPushReloadButton = false;

// ボタンが押されてから次にまた押せるまでの時間(秒)
private TimeSpan allowTime = new TimeSpan(0, 0, 3);

// 前回ボタンが押された時点と現在時間との差分を格納
private TimeSpan pastTime;




void Update ()
{
	// 3秒後にボタン押下を許可
	if (isPushReloadButton) {
		pastTime = DateTime.Now - this.reloadTime;
		if(pastTime > allowTime){
			isPushReloadButton = false;
		}
	}
}

//ボタンイベント
public void OnClickButton ()
{
	if ( isPushReloadButton ) return;
	isPushReloadButton = true;
		
	// ここに通信処理などを書く

	//現在の時間をセット
	this.reloadTime = DateTime.Now;
}

もちろんですが、端末の時間を利用して秒をカウントしているので
動作が重い端末だと時間が変わってしまうのかも
そこは要検証ですが、ボタン連打制限ならアバウトでもきっとだいじょうぶでしょ

Unityエディタ拡張でシーン内のオブジェクトに関連付けられたコンポーネント内の変数を取得する

タイトルめっちゃ長い

シーン内の変数一覧が欲しくなったのでエディタ拡張から取得出来ないか頑張ってみました
本当は値も欲しかったのだけど、今回とれたのは変数名一覧だけでした

using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;


public class EditorExWindow : EditorWindow
{


	[MenuItem("Window/EditorEx")]
	static void Open()
	{
		EditorWindow.GetWindow<EditorExWindow>( "EditorEx" );
	}

	string textArea = "";

	void OnGUI()
	{
		if( GUILayout.Button("Caputure") )
		 	Find();
		GUILayout.Label( "TextArea" );
		textArea = GUILayout.TextArea( textArea );

	}

	 

	private void Find (){
		// TextAreaクリア
		textArea = "";

		List<GameObject> AllObjects =  new List<GameObject>();
		List<MonoBehaviour> allMonobehaviourList = new List<MonoBehaviour> ();

		foreach (GameObject obj in UnityEngine.Resources.FindObjectsOfTypeAll(typeof(GameObject)))
		{
			// アセットからパスを取得.シーン上に存在するオブジェクトの場合,シーンファイル(.unity)のパスを取得.
			string path = AssetDatabase.GetAssetOrScenePath(obj);
			// シーン上に存在するオブジェクトかどうか文字列で判定.
			bool isScene = path.Contains(".unity");
			// シーン上に存在するオブジェクトならば処理.
			if (isScene)
			{
				AllObjects.Add (obj);
			}
		}

		allMonobehaviourList.AddRange (GetComponentsInList<MonoBehaviour> (AllObjects));

		foreach(var componentData in allMonobehaviourList){
			foreach(MemberInfo mi in componentData.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance |  BindingFlags.DeclaredOnly)){
				textArea += mi.Name + "\n";
			}
		}
	}

	public static IEnumerable<T> GetComponentsInList<T> (IEnumerable<GameObject> gameObjects ) where T : Component 
	{
		var componentList = new List<T> ();

		foreach (var obj in gameObjects) {
			var components = obj.GetComponents<T> ();
			if (components != null) {
				foreach(var component in components){
					componentList.Add (component);
				}
			}
		}
		return componentList;
	}
}

変数名が取れたんだから中身も取れると思うんだけど...
もうちょっとがんばろう


github.com

Unityエディタ拡張を作ってみる

やっとUnityの記事が書ける
エディタ拡張だけど

というわけでエディタ拡張のサンプルを作ってみました
元々サーバの方の人間なのでUnityって作業の自動化とか効率化ってどうやってるのっていうのはずっと気になってました

参考にさせてもらったのはケットシーウェアさんのサイト
【エディタ拡張徹底解説】初級編①:ウィンドウを自作してみよう【Unity】 | ケットシーウェア


僕がなに書いても意味ないくらい超丁寧でわかりやすかったです
それで出来たのがこちら

using UnityEngine;
using UnityEditor;
using System.Collections;

public class EditorExWindow : EditorWindow
{
	[MenuItem("Window/EditorEx")]
	static void Open()
	{
		EditorWindow.GetWindow<EditorExWindow>( "EditorEx" );
	}

	string textArea = "";

	void OnGUI()
	{
		if( GUILayout.Button("Find  Objects") )
		 	Find();
		GUILayout.Label( "TextArea" );
		textArea = GUILayout.TextArea( textArea );

	}

	private void Find (){
		// TextAreaクリア
		textArea = "";
		foreach (GameObject obj in UnityEngine.Resources.FindObjectsOfTypeAll(typeof(GameObject)))
		{
			// アセットからパスを取得.シーン上に存在するオブジェクトの場合,シーンファイル(.unity)のパスを取得.
			string path = AssetDatabase.GetAssetOrScenePath(obj);
			// シーン上に存在するオブジェクトかどうか文字列で判定.
			bool isScene = path.Contains(".unity");
			// シーン上に存在するオブジェクトならば処理.
			if (isScene)
			{
				// GameObjectの名前を表示.
				Debug.Log(obj.name);
				textArea += obj.name + "\n";
			}
		}
	}
}


Unityエディタから表示してみるとこんな感じになります
f:id:chroske:20150608202732p:plain

やってることは
①Findボタンが押されたらイベント実行
②イベントからResources.FindObjectsOfTypeAllでシーン内のオブジェクトを全て取得
③TextAreaに書き込む
これだけです

これで何が出来るってわけでもないけど
なにが出来そうっていうのはなんとなくわかったのではなかろうか
もちろん取得だけじゃなくて操作や生成も行える
すばらしい、夢が広がるね
なにか実用的なものができたらまた載せようと思う