首页 > 代码库 > 【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,空格: