-------小基原创,转载请给我一个面子
网上有很多讲输入控制如何移动,但是多数都是讲单一按下,对于同时按下2个或2个以上按键并没有说明怎么解决,这里小基研究了一下方便大家
(如果你直接写input.GetKey去读输入,直接执行物体移动的话,判断格个方向时逻辑时,如果使用if-elseif这种的话,多按键输入时候,必定只能执行其中一个方向。
如果用if判断各个方向,那么当“上”方向和“右”方向同时按下时,物理轨迹是“右上”方向,而你单个方向速度如果都是v的话,合速度方向为√2,相当于斜着走速度会变快,这两个方式都不能接受)
所以解决思路是当按键按下时,记录状态,抬起时重置状态,根据当前所有输入的按键状态,统一处理得出一个合方向,并且对合速度处理
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class MyInput : MonoBehaviour { 6 //移动方向枚举 7 enum MoveDir 8 { 9 None, //不动 10 Up, //上8 11 Down, //下2 12 Left, //左4 13 Right, //右6 14 UL, //左上7 15 UR, //右上9 16 DL, //左下1 17 DR, //右下3 18 } 19 20 //输入按键常量(之后走配置) 21 const KeyCode INPUT_UP = KeyCode.W; 22 const KeyCode INPUT_DOWN = KeyCode.S; 23 const KeyCode INPUT_LEFT = KeyCode.A; 24 const KeyCode INPUT_RIGHT = KeyCode.D; 25 26 //默认移动方向 27 private MoveDir moveDir = MoveDir.None; 28 //按压记录 29 private bool isUpPress = false; 30 private bool isDownPress = false; 31 private bool isLeftPress = false; 32 private bool isRightPress = false; 33 34 //是否可以移动 35 private bool canMove = true; 36 //右移动 37 private Vector3 MOVE_RIGHT = new Vector3(1, 0, 0); 38 //上移动 39 private Vector3 MOVE_UP = new Vector3(0, 1, 0); 40 41 //外部调控速度 42 public float speed = 2f; 43 //移动速度向量 44 private Vector3 move_speed_dir = Vector3.zero; 45 //移动距离 46 private Vector3 move_dis = Vector3.zero; 47 48 //控制目标 49 public Transform target; 50 51 // Use this for initialization 52 void Start () { 53 54 } 55 56 // Update is called once per frame 57 void Update () { 58 CheckInputKey(); 59 CheckMoveDir(); 60 } 61 62 void FixedUpdate() 63 { 64 CheckMove(); 65 } 66 67 //检测输入按键 68 void CheckInputKey() 69 { 70 //检测单一输入 71 foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode))) 72 { 73 if (Input.GetKeyDown(kcode)) 74 { 75 //Debug.Log("Single KeyCode: " + kcode); 76 ChangeKeyPressState(kcode, true); 77 } 78 79 if (Input.GetKeyUp(kcode)) 80 { 81 //Debug.Log("Single KeyCode: " + kcode); 82 ChangeKeyPressState(kcode, false); 83 } 84 } 85 } 86 87 //记录按键的按压状态 88 void ChangeKeyPressState(KeyCode keyCode, bool isPress) 89 { 90 switch(keyCode) 91 { 92 case INPUT_UP: 93 isUpPress = isPress; 94 break; 95 case INPUT_DOWN: 96 isDownPress = isPress; 97 break; 98 case INPUT_LEFT: 99 isLeftPress = isPress; 100 break; 101 case INPUT_RIGHT: 102 isRightPress = isPress; 103 break; 104 } 105 } 106 107 //确定移动方向 108 void CheckMoveDir() 109 { 110 //确定方向 111 if(isUpPress && isLeftPress) 112 { 113 moveDir = MoveDir.UL; 114 } 115 else if(isUpPress && isRightPress) 116 { 117 moveDir = MoveDir.UR; 118 } 119 else if (isDownPress && isLeftPress) 120 { 121 moveDir = MoveDir.DL; 122 } 123 else if (isDownPress && isRightPress) 124 { 125 moveDir = MoveDir.DR; 126 } 127 else if(isUpPress) 128 { 129 moveDir = MoveDir.Up; 130 } 131 else if (isDownPress) 132 { 133 moveDir = MoveDir.Down; 134 } 135 else if (isLeftPress) 136 { 137 moveDir = MoveDir.Left; 138 } 139 else if (isRightPress) 140 { 141 moveDir = MoveDir.Right; 142 } 143 else 144 { 145 moveDir = MoveDir.None; 146 } 147 } 148 149 //检测是否可以移动 150 void CheckMove() 151 { 152 //某些情况下可能禁止移动,例如暂停,播放CG等 153 if(canMove && moveDir != MoveDir.None) 154 { 155 PlayerMove(target, speed); 156 } 157 } 158 159 //移动 160 void PlayerMove(Transform target, float speed) 161 { 162 move_dis = speed * Time.deltaTime * GetSpeedDir(); 163 target.position += move_dis; 164 } 165 166 //速度向量 167 Vector3 GetSpeedDir() 168 { 169 switch(moveDir) 170 { 171 case MoveDir.Up: 172 move_speed_dir = MOVE_UP; 173 break; 174 case MoveDir.Down: 175 move_speed_dir = -MOVE_UP; 176 break; 177 case MoveDir.Left: 178 move_speed_dir = -MOVE_RIGHT; 179 break; 180 case MoveDir.Right: 181 move_speed_dir = MOVE_RIGHT; 182 break; 183 case MoveDir.UL: 184 move_speed_dir = MOVE_UP - MOVE_RIGHT; 185 break; 186 case MoveDir.UR: 187 move_speed_dir = MOVE_UP + MOVE_RIGHT; 188 break; 189 case MoveDir.DL: 190 move_speed_dir = -MOVE_UP - MOVE_RIGHT; 191 break; 192 case MoveDir.DR: 193 move_speed_dir = -MOVE_UP + MOVE_RIGHT; 194 break; 195 } 196 return move_speed_dir.normalized; 197 } 198 }