zoukankan      html  css  js  c++  java
  • 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,小基是说如何发射子弹(¬_¬”)

    做游戏,一定要有爱
  • 相关阅读:
    requests模块
    Flask框架 之 上下文管理前戏
    Flask框架 之 学生管理分析
    Flask框架 之 路由和视图详解
    数据库连接池DBUtils
    C++中endl和cout语句
    Linux如何在一个文件中写入内容
    C++常量
    Linux重启命令
    Linux命令1
  • 原文地址:https://www.cnblogs.com/agamer/p/9002882.html
Copyright © 2011-2022 走看看