unity零基础开始学习做游戏(三)鼠标输入,来个虚拟摇杆怎么样?

 

 

-------小基原创,转载请给我一个面子

  现在移动游戏越来越火,大家都拿手机平板玩游戏,没有键盘和手柄输入,所以就不得不看看虚拟摇杆怎么搞?(小基对于没有实体反馈不是很喜欢呢)

首先要清楚,鼠标操作输入,应该在2d的UI平面上做一个虚拟摇杆,如下图

Hierarchy面板下点Create创建一个UI里面的Image

会自动创建一个Canvas(画布),UI方面的东西都在这里面显示

我们再创建一个专门处理UI的摄像机(这个主要处理鼠标点击时候,获取屏幕坐标,来处理移动逻辑,如果使用默认的MainCamera的话,正交模式下,没法体现3D,投影模式下,鼠标点击输入坐标处理起来也有点恶心,这些坑我会单独在另一个技术文章里细说,对于新手来讲,先知道这里单做一个UICamera可以避免坑就行。踩坑的方式,花样可多了

Hierarchy面板下用Create创建一个UI里面的Camera,改名为UICamera

设置成这样,记得把AudioListener这个组件移除掉,因为MainCamera上面已经有一个接收声音的了。红框内切记,不然待会都找不到你的摇杆Orz

(具体参数细节这里不展开讲了,这个系列以实现功能为目标,讲原理的话,太枯燥了,怕不是看睡着了)

接下来是制作虚拟摇杆,两张图片,大圈里面放个小圈。

 

在Canvas下创建两个Image,分别起名,小圆作为大圆的子物体(这样就可以成为整体,一起移动了)

使用unity自带的图片凑合用,一个白色,一个红色,效果明显点

 

最后效果就是这样,好吧,原谅我的美术是体育老师教的XD

 接下来在创建一个空物体Main,用来挂脚本MyInput2(基于上一篇的控制移动,在加点东西就非常实用了)

下面上代码

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 
  5 public class MyInput2 : MonoBehaviour {
  6     //移动方向枚举
  7     enum MoveDir
  8     {
  9         None = 0,       //不动
 10         Up = 1,         //上8
 11         Down = -1,      //下2
 12         Left = 10,      //左4
 13         Right = -10,    //右6
 14         UL = 11,        //左上7
 15         UR = -9,        //右上9
 16         DL = 9,         //左下1
 17         DR = -11,       //右下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 int moveDirValue = 0;
 30     //按压记录
 31     private bool isUpPress = false;
 32     private bool isDownPress = false;
 33     private bool isLeftPress = false;
 34     private bool isRightPress = false;
 35 
 36     //是否可以移动
 37     private bool canMove = true;
 38     //右移动
 39     private Vector3 MOVE_RIGHT = new Vector3(1, 0, 0);
 40     //上移动
 41     private Vector3 MOVE_UP = new Vector3(0, 1, 0);
 42 
 43     //外部调控速度
 44     public float speed = 2f;
 45     //移动速度向量
 46     private Vector3 move_speed_dir = Vector3.zero;
 47     //移动距离
 48     private Vector3 move_dis = Vector3.zero;
 49 
 50     //控制目标
 51     public Transform target;
 52 
 53 
 54     //鼠标按下时的坐标
 55     private Vector3 mouseStartPos = Vector3.zero;
 56     //鼠标是否按下
 57     private bool isMousePress = false;
 58     //鼠标枚举
 59     const KeyCode INPUT_MOUSE = KeyCode.Mouse0;
 60     //鼠标拖动范围
 61     const float MOUSE_RADIUS = 20;
 62     //鼠标移动向量
 63     private Vector3 mouseDir = Vector3.zero;
 64     //鼠标速度衰减
 65     private float mouseSpeedRate = 0;
 66     //鼠标速度
 67     public float mouseSpeed = 2;
 68     //摇杆底
 69     public RectTransform joyStickDown;
 70     //摇杆顶
 71     public RectTransform joyStickUp;
 72     //摄像机
 73     public Camera camera;
 74 
 75 
 76     // Update is called once per frame
 77     void Update () {
 78         CheckInputKey();
 79         CheckMoveDir();
 80         CheckMouseDir();
 81     }
 82 
 83     void FixedUpdate()
 84     {
 85         CheckMove();
 86     }
 87 
 88     //检测输入按键
 89     void CheckInputKey()
 90     {
 91         //检测单一输入
 92         foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
 93         {
 94             if (Input.GetKeyDown(kcode))
 95             {
 96                 //Debug.Log("Single KeyCode Down: " + kcode);
 97                 ChangeKeyPressState(kcode, true);
 98             }
 99 
100             if (Input.GetKeyUp(kcode))
101             {
102                 //Debug.Log("Single KeyCode Up: " + kcode);
103                 ChangeKeyPressState(kcode, false);
104             }
105         }
106     }
107 
108     //记录按键的按压状态
109     void ChangeKeyPressState(KeyCode keyCode, bool isPress)
110     {
111         switch(keyCode)
112         {
113             case INPUT_UP:
114                 isUpPress = isPress;
115                 break;
116             case INPUT_DOWN:
117                 isDownPress = isPress;
118                 break;
119             case INPUT_LEFT:
120                 isLeftPress = isPress;
121                 break;
122             case INPUT_RIGHT:
123                 isRightPress = isPress;
124                 break;
125             case INPUT_MOUSE:
126                 MouseStateChange(isPress);
127                 break;
128         }
129     }
130 
131     //鼠标按键输入
132     void MouseStateChange(bool isPress)
133     {
134         isMousePress = isPress;
135         mouseStartPos = isPress ? Input.mousePosition : Vector3.zero;
136         joyStickDown.gameObject.SetActive(isPress);
137         joyStickDown.position = camera.ScreenToWorldPoint(mouseStartPos);
138     }
139 
140     //鼠标移动
141     void CheckMouseDir()
142     {
143         if(isMousePress)
144         {
145             mouseDir = Input.mousePosition - mouseStartPos;
146             mouseSpeedRate = Mathf.Min(mouseDir.magnitude / MOUSE_RADIUS, 1);
147             move_dis = mouseSpeed * mouseSpeedRate * Time.deltaTime * mouseDir.normalized;
148             target.position += move_dis;
149             joyStickUp.localPosition = mouseDir.normalized * mouseSpeedRate * MOUSE_RADIUS;
150         }
151     }
152 
153     //确定移动方向
154     void CheckMoveDir()
155     {
156         moveDirValue = 0;
157         //确定方向
158         if(isUpPress)
159         {
160             moveDirValue += (int)MoveDir.Up;
161         }
162         if (isDownPress)
163         {
164             moveDirValue += (int)MoveDir.Down;
165         }
166         if (isLeftPress)
167         {
168             moveDirValue += (int)MoveDir.Left;
169         }
170         if (isRightPress)
171         {
172             moveDirValue += (int)MoveDir.Right;
173         }
174     }
175 
176     //检测是否可以移动
177     void CheckMove()
178     {
179         //某些情况下可能禁止移动,例如暂停,播放CG等
180         if(canMove && moveDirValue != (int)MoveDir.None)
181         {
182             PlayerMove(target, speed);
183         }
184     }
185 
186     //移动
187     void PlayerMove(Transform target, float speed)
188     {
189         move_dis = speed * Time.deltaTime * GetSpeedDir();
190         target.position += move_dis;
191     }
192 
193     //速度向量
194     Vector3 GetSpeedDir()
195     {
196         switch(moveDirValue)
197         {
198             case (int)MoveDir.Up:
199                 move_speed_dir = MOVE_UP;
200                 break;
201             case (int)MoveDir.Down:
202                 move_speed_dir = -MOVE_UP;
203                 break;
204             case (int)MoveDir.Left:
205                 move_speed_dir = -MOVE_RIGHT;
206                 break;
207             case (int)MoveDir.Right:
208                 move_speed_dir = MOVE_RIGHT;
209                 break;
210             case (int)MoveDir.UL:
211                 move_speed_dir = MOVE_UP - MOVE_RIGHT;
212                 break;
213             case (int)MoveDir.UR:
214                 move_speed_dir = MOVE_UP + MOVE_RIGHT;
215                 break;
216             case (int)MoveDir.DL:
217                 move_speed_dir = -MOVE_UP - MOVE_RIGHT;
218                 break;
219             case (int)MoveDir.DR:
220                 move_speed_dir = -MOVE_UP + MOVE_RIGHT;
221                 break;
222         }
223         return move_speed_dir.normalized;
224     }
225 }

 在按键输入控制的基础上,加上鼠标输入就ok了

思路就是:按下时候记录此时坐标,然后拖动后的当前坐标与起始坐标的向量差值,就是物体应该移动的方向

先把变量都定义好

核心就是鼠标左键按下的记录状态(这里做了个有意思的处理,第一次按下的位置,摇杆就会出现在那个位置,拖动的时候,小圆在大圆内部移动)

接下来把脚本绑定好

运行游戏,类似于这个效果,鼠标移动,红圈在白圈内移动,移动方向就是白方块(主角)移动方向 

ok,通过两篇介绍,除了脚本稍稍有点难理解之外,其他应该都能一步一步做出来了,零基础的你看到自己做的“小游戏”,是不是已经成就感爆棚了?

最基本的控制移动都完成了,不如下篇博客小基介绍一下“打飞机”ლ(╹◡╹ლ)

emmm,小基是说如何发射子弹(¬_¬”)

做游戏,一定要有爱
原文地址:https://www.cnblogs.com/agamer/p/9002882.html