1. 程式人生 > >【Unity 3D】學習筆記四十六:輸入與控制——鍵盤事件

【Unity 3D】學習筆記四十六:輸入與控制——鍵盤事件

在遊戲中,玩家控制主角移動,按鍵攻擊,選擇行走。都需要在程式中監聽玩家的輸入。unity為開發者提供了input庫,來支援鍵盤事件,滑鼠事件以及觸控事件。本文主要回顧鍵盤事件,以後會逐文複習滑鼠以及觸控事件。

鍵盤事件

一般的PC鍵盤有104個不同的按鍵,在程式中通過監聽這些按鍵事件,從而進一步執行邏輯操作。如:射擊遊戲中,W表示前進,S表示後退,A表示左移,D表示右移。

按下事件

在指令碼中,用input。GetKeyDown( )方法將按鍵值作為引數,監聽此按鍵是否被按下。按下返回true,否者返回false。

using UnityEngine;
using System.Collections;

public class Script_07_01 : MonoBehaviour
{

	void Update () 
	{
		if (Input.GetKeyDown (KeyCode.W))
		{
			Debug.Log("您按下了W鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.S))
		{
			Debug.Log("您按下了S鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.A))
		{
			Debug.Log("您按下了A鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.D))
		{
			Debug.Log("您按下了D鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.Space))
		{
			Debug.Log("您按下了空格鍵");
		}
	}
}

執行:


擡起事件

擡起事件完全依賴與按下事件,因為只有按下才有擡起。我們用Input.GetKeyUp( )方法監聽擡起事件,按鍵擡起後,返回true,否則返回false。

using UnityEngine;
using System.Collections;

public class Script_07_02 : MonoBehaviour
{

	void Update () 
	{
		//按下事件
		if (Input.GetKeyDown (KeyCode.W))
		{
			Debug.Log("您按下了W鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.S))
		{
			Debug.Log("您按下了S鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.A))
		{
			Debug.Log("您按下了A鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.D))
		{
			Debug.Log("您按下了D鍵");
		}
		
		if (Input.GetKeyDown (KeyCode.Space))
		{
			Debug.Log("您按下了空格鍵");
		}
		
		//擡起按鍵
		if (Input.GetKeyUp (KeyCode.W))
		{
			Debug.Log("您擡起了W鍵");
		}
		
		if (Input.GetKeyUp (KeyCode.S))
		{
			Debug.Log("您擡起了S鍵");
		}
		
		if (Input.GetKeyUp (KeyCode.A))
		{
			Debug.Log("您擡起了A鍵");
		}
		
		if (Input.GetKeyUp (KeyCode.D))
		{
			Debug.Log("您擡起了D鍵");
		}
		
		if (Input.GetKeyUp (KeyCode.Space))
		{
			Debug.Log("您擡起了空格鍵");
		}
	
	}
}
執行:
長按事件 長按事件是監聽某一按鍵是否處於一直按下的狀態,通過Input.GetKey( )來判斷鍵盤中某一按鍵是否被一直按著。
using UnityEngine;
using System.Collections;

public class Script_07_03 : MonoBehaviour 
{
	//記錄某按鍵按下的幀數
	int keyFrame = 0;
	

	void Update ()
	{
	
		if (Input.GetKeyDown (KeyCode.A))
		{
			Debug.Log("A按下一次");
		}	
		if (Input.GetKey (KeyCode.A))
		{
			//記錄按下的幀數
			keyFrame++;
			Debug.Log("A連按:" + keyFrame+"幀");
		}
		if (Input.GetKeyUp (KeyCode.A))
		{
			//擡起後清空幀數
			keyFrame=0;
			Debug.Log("A按鍵擡起");
		}	
	}
}

執行:



任意鍵事件 在程式中還可以監聽按鍵中的任意按鍵是否被按下,常見於載入完遊戲後,按任意鍵進入。
using UnityEngine;
using System.Collections;

public class Script_07_04 : MonoBehaviour 
{

	//記錄某按鍵按下的幀數
	int keyFrame = 0;
	
	// Update is called once per frame
	void Update ()
    {
		if(Input.anyKeyDown)
		{
			//清空按下幀數
			keyFrame=0;
			Debug.Log("任意鍵被按下");
		}
		
		
		if(Input.anyKey)
		{
			keyFrame++;
			Debug.Log("任意鍵被長按"+keyFrame+"幀");
		}
	
	}
}
執行:

例項——組合按鍵

在經典的格鬥遊戲中,會有組合鍵發出牛逼的大招,而這個功能的事件思路其實不難:在玩家按下某一鍵後,便開始時間記數,在某一時間內按出所需要的鍵便發出大招。
using UnityEngine;
using System.Collections.Generic;
using System;

public class Script_07_05 : MonoBehaviour 
{

    //方向鍵上的貼圖
	public Texture imageUp;
	//方向鍵下的貼圖
	public Texture imageDown;
	//方向鍵左的貼圖
	public Texture imageLeft;
	//方向鍵右的貼圖
	public Texture imageRight;
	//按鍵成功的貼圖
	public Texture imageSuccess;
    
    //自定義方向鍵的儲存值
	public const int KEY_UP = 0;
	public const int KEY_DOWN = 1;
	public const int KEY_LEFT = 2;
	public const int KEY_RIGHT = 3;
	public const int KEY_FIRT = 4;
	
	//連續按鍵的事件限制
	public const int FRAME_COUNT = 100;
	//倉庫中儲存技能的數量
	public const int SAMPLE_SIZE = 3;
	//每組技能的按鍵數量
	public const int SAMPLE_COUNT = 5;
	//技能倉庫
	int[,] Sample = 
	{
	    //下 + 前 + 下 + 前 + 拳
		{KEY_DOWN,KEY_RIGHT,KEY_DOWN,KEY_RIGHT,KEY_FIRT},
		//下 + 前 + 下 + 後 + 拳
		{KEY_DOWN,KEY_RIGHT,KEY_DOWN,KEY_LEFT,KEY_FIRT},
		//下 + 後 + 下 + 後 + 拳
		{KEY_DOWN,KEY_LEFT,KEY_DOWN,KEY_LEFT,KEY_FIRT},
	};
	
	//記錄當前按下按鍵的鍵值
	int  currentkeyCode =0;
	//標誌是否開啟監聽按鍵
	bool startFrame = false;
	//記錄當前開啟監聽到現在的時間
	int  currentFrame = 0;
	//儲存一段時間內玩家輸入的按鍵組合
	List<int> playerSample;
	//標誌完成操作
	bool isSuccess= false;
	
	void Start()
	{
	    //初始話按鍵組合連結串列
		playerSample  = new List<int>();
	}
	
	void OnGUI()
	{
		//獲得按鍵組合連結串列中儲存按鍵的數量
		int size = playerSample.Count;
		//遍歷該按鍵組合連結串列
		for(int i = 0; i< size; i++)
		{
			//將按下按鍵對應的圖片顯示在螢幕中
			int key = playerSample[i];
			Texture temp = null;
			switch(key)
			{
			case KEY_UP:
				temp = imageUp;
				break;
			case KEY_DOWN:
				temp = imageDown;
				break;
			case KEY_LEFT:
				temp = imageLeft;
				break;
			case KEY_RIGHT:
				temp = imageRight;
				break;
			}
			if(temp != null)
			{
				GUILayout.Label(temp);
			}
		}
		
		if(isSuccess)
		{
			//顯示成功貼圖
			GUILayout.Label(imageSuccess);
		}
		//預設提示資訊
		GUILayout.Label("連續組合按鍵1:下、前、下、前、拳");
		GUILayout.Label("連續組合按鍵2:下、前、下、後、拳");
		GUILayout.Label("連續組合按鍵2:下、後、下、後、拳");
	}
	
	void Update () 
	{
		//更新按鍵
		UpdateKey();
		
		if(Input.anyKeyDown)
		{
			
			if(isSuccess)
			{
				//按鍵成功後重置
				isSuccess = false;
				Reset();
			}
			
			if(!startFrame)
			{
				//啟動時間計數器
				startFrame = true;
			}
			
			//將按鍵值新增如連結串列中
			playerSample.Add(currentkeyCode);
			//遍歷連結串列
			int size = playerSample.Count;
			if(size == SAMPLE_COUNT)
			{
				for(int i = 0; i< SAMPLE_SIZE; i++)
				{
					int SuccessCount = 0;
					for(int j = 0; j< SAMPLE_COUNT; j++)
					{
						int temp = playerSample[j];
						if(temp== Sample[i,j]){
							SuccessCount++;
						}
					}
					//玩家按下的組合按鍵與倉庫中的按鍵組合相同表示釋放技能成功
					if(SuccessCount ==SAMPLE_COUNT)
					{
						isSuccess = true;
						break;
					}
				}
				
			}
		}
		
		if(startFrame)
		{
			//計數器++
			currentFrame++;
		}
		
		if(currentFrame >= FRAME_COUNT)
		{
			//計數器超時
			if(!isSuccess)
			{
				Reset();
			}
		}
	}
	
	 void Reset ()
	 {
	 	//重置按鍵相關資訊
	 	currentFrame = 0;
		startFrame = false;
		playerSample.Clear();
	 }
	
	void UpdateKey()
	{
		//獲取當前鍵盤的按鍵資訊
		if (Input.GetKeyDown (KeyCode.W))
		{
			currentkeyCode = KEY_UP;
		}
		if (Input.GetKeyDown (KeyCode.S))
		{
			currentkeyCode = KEY_DOWN;
		}
		if (Input.GetKeyDown (KeyCode.A))
		{
			currentkeyCode = KEY_LEFT;
		}
		if (Input.GetKeyDown (KeyCode.D))
		{
			currentkeyCode = KEY_RIGHT;
		}
		if (Input.GetKeyDown (KeyCode.Space))
		{
			currentkeyCode = KEY_FIRT;
		}
	}
	
}
按s,d,s,d,空格: