• unity零基础开始学习做游戏(二)让你的对象动起来


     

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

      小基认为电子游戏与电影最重要的区别就是交互,如果电子游戏没有让你输入的交互功能的话,全程都“只可远观,而不可鼓捣”的话,你可能是在看视频,怕不是玩了假游戏。所以小基来讲讲如何输入并控制物体移动

    首先双击unity

     点击NEW,给你的工程(游戏)起个有意思的名字(突发发现小基随便起的这个Test1856有《教团1886》的既视感XD

    创建之后就是一个空场景,右上角的布局小基习惯用2by3这种风格,你可以自行选择。

    点击create,里面可以创建各种基本的物体(2d,3d等)这里随便创建一个3d的cube

    之后在Project下,选中Assets,点击create创建一个C#Script脚本,起名叫做MyInput好了

    下面上代码

      1 using System.Collections;
      2 using System.Collections.Generic;
      3 using UnityEngine;
      4 
      5 public class MyInput : MonoBehaviour {
      6     //移动方向枚举(这里列举8方向的移动,注释里面的数字是用小键盘数字的物理位置指代方向,格斗游戏术语)
      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 }

    !!!!网上有很多讲输入控制如何移动,但是多数都是讲单一按下,对于同时按下2个或2个以上按键并没有说明怎么解决,这里小基研究了一下方便大家!!!!!

    (如果你直接写input.GetKey去读输入,直接执行物体移动的话,判断格个方向时逻辑时,如果使用if-elseif这种的话,多按键输入时候,必定只能执行其中一个方向。
    如果用if判断各个方向,那么当“上”方向和“右”方向同时按下时,物理轨迹是“右上”方向,而你单个方向速度如果都是v的话,合速度方向为√2,相当于斜着走速度会变快,这两个方式都不能接受)
    update()里面每帧检测CheckInputKey(),是否有按键按下或者抬起,ChangeKeyPressState()这个方法里面记下来当前有哪些按键输入。
    CheckMoveDir()这个方法就是专门为了根据按下的按键的值来判断,合方向是枚举中的哪一种(这个有另一种思路,后面单独说)
    CheckMove(),PlayerMove()这两个方法就是检测当前能不能移动,能移动的话就移动

    target.position += move_dis;这个代码意思是把target这个物体的位置移动到新位置,a += b就相当于a = a + b,理解为在原来位置基础上再偏移move_dis就好
    GetSpeedDir()这个方法里面就是根据方向枚举,确定移动的方向向量,确定完合方向后,记得要用.normalized取单位长度,这样就能保证斜方向速度与正交方向速度相同。
     
    接下来把MyInput脚本拖到cube上,Target也绑定cube,设置好speed,点击三角开始按钮(变为蓝色表示运行)
    试试单一按键,两个按键一起按下,都能正常移动

    --------------------------------------另一种思路解决多按键同时按下控制移动----------------------------------------------------
    上面那种方法,判断按下按键转换方向时,只处理了一个按键按下,和两个按键同时按下,那么如果我同时按下三个按键或者四个按键时候就会出问题
    下面上代码,区别看下面解释
      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     // Use this for initialization
     54     void Start () {
     55         
     56     }
     57     
     58     // Update is called once per frame
     59     void Update () {
     60         CheckInputKey();
     61         CheckMoveDir();
     62     }
     63 
     64     void FixedUpdate()
     65     {
     66         CheckMove();
     67     }
     68 
     69     //检测输入按键
     70     void CheckInputKey()
     71     {
     72         //检测单一输入
     73         foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
     74         {
     75             if (Input.GetKeyDown(kcode))
     76             {
     77                 Debug.Log("Single KeyCode: " + kcode);
     78                 ChangeKeyPressState(kcode, true);
     79             }
     80 
     81             if (Input.GetKeyUp(kcode))
     82             {
     83                 Debug.Log("Single KeyCode: " + kcode);
     84                 ChangeKeyPressState(kcode, false);
     85             }
     86         }
     87     }
     88 
     89     //记录按键的按压状态
     90     void ChangeKeyPressState(KeyCode keyCode, bool isPress)
     91     {
     92         switch(keyCode)
     93         {
     94             case INPUT_UP:
     95                 isUpPress = isPress;
     96                 break;
     97             case INPUT_DOWN:
     98                 isDownPress = isPress;
     99                 break;
    100             case INPUT_LEFT:
    101                 isLeftPress = isPress;
    102                 break;
    103             case INPUT_RIGHT:
    104                 isRightPress = isPress;
    105                 break;
    106         }
    107     }
    108 
    109     //确定移动方向
    110     void CheckMoveDir()
    111     {
    112         moveDirValue = 0;
    113         //确定方向
    114         if(isUpPress)
    115         {
    116             moveDirValue += (int)MoveDir.Up;
    117         }
    118         if (isDownPress)
    119         {
    120             moveDirValue += (int)MoveDir.Down;
    121         }
    122         if (isLeftPress)
    123         {
    124             moveDirValue += (int)MoveDir.Left;
    125         }
    126         if (isRightPress)
    127         {
    128             moveDirValue += (int)MoveDir.Right;
    129         }
    130     }
    131 
    132     //检测是否可以移动
    133     void CheckMove()
    134     {
    135         //某些情况下可能禁止移动,例如暂停,播放CG等
    136         if(canMove && moveDirValue != (int)MoveDir.None)
    137         {
    138             PlayerMove(target, speed);
    139         }
    140     }
    141 
    142     //移动
    143     void PlayerMove(Transform target, float speed)
    144     {
    145         move_dis = speed * Time.deltaTime * GetSpeedDir();
    146         target.position += move_dis;
    147     }
    148 
    149     //速度向量
    150     Vector3 GetSpeedDir()
    151     {
    152         switch(moveDirValue)
    153         {
    154             case (int)MoveDir.Up:
    155                 move_speed_dir = MOVE_UP;
    156                 break;
    157             case (int)MoveDir.Down:
    158                 move_speed_dir = -MOVE_UP;
    159                 break;
    160             case (int)MoveDir.Left:
    161                 move_speed_dir = -MOVE_RIGHT;
    162                 break;
    163             case (int)MoveDir.Right:
    164                 move_speed_dir = MOVE_RIGHT;
    165                 break;
    166             case (int)MoveDir.UL:
    167                 move_speed_dir = MOVE_UP - MOVE_RIGHT;
    168                 break;
    169             case (int)MoveDir.UR:
    170                 move_speed_dir = MOVE_UP + MOVE_RIGHT;
    171                 break;
    172             case (int)MoveDir.DL:
    173                 move_speed_dir = -MOVE_UP - MOVE_RIGHT;
    174                 break;
    175             case (int)MoveDir.DR:
    176                 move_speed_dir = -MOVE_UP + MOVE_RIGHT;
    177                 break;
    178         }
    179         return move_speed_dir.normalized;
    180     }
    181 }
     

    枚举方向定义了不同的值,这样同时按下三个按键的时候,必定有两个方向时一对相反的,那么求“合”速度时候,就可以抵消掉。如果四个方向同时按下,就相当于不动了,问题搞定!

    没有经验的同学按照这个流程一步一步做,应该也能实现移动物体这个效果的。

    顺便祝愿你们都有三次元会动的“对象”(来自单身狗的真诚祝福)

    工程下载https://pan.baidu.com/s/1opWziUOW7QdzMpn3hcaQ4A

    做游戏,一定要有爱
  • 相关阅读:
    线程高级应用-心得2-同步锁讲解及面试题案例分析
    线程高级应用-心得1-传统线程和定时器讲解及案例分析
    Map拷贝 关于对象深拷贝 浅拷贝的问题
    HashMap对象的深层克隆
    java Collections.sort()实现List排序自定义方法
    java中观察者模式Observable和Observer
    mysql字符串函数(转载)
    CSS的三种样式表和优先级
    Android之微信支付
    Android之扫描二维码和根据输入信息生成名片二维码
  • 原文地址:https://www.cnblogs.com/agamer/p/9000310.html
Copyright © 2020-2023  润新知