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

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

首先双击unity

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

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

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

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

下面上代码

 using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MyInput : MonoBehaviour {
//移动方向枚举(这里列举8方向的移动,注释里面的数字是用小键盘数字的物理位置指代方向,格斗游戏术语)
enum MoveDir
{
None, //不动
Up, //上8
Down, //下2
Left, //左4
Right, //右6
UL, //左上7
UR, //右上9
DL, //左下1
DR, //右下3
} //输入按键常量(之后走配置)
const KeyCode INPUT_UP = KeyCode.W;
const KeyCode INPUT_DOWN = KeyCode.S;
const KeyCode INPUT_LEFT = KeyCode.A;
const KeyCode INPUT_RIGHT = KeyCode.D; //默认移动方向
private MoveDir moveDir = MoveDir.None;
//按压记录
private bool isUpPress = false;
private bool isDownPress = false;
private bool isLeftPress = false;
private bool isRightPress = false; //是否可以移动
private bool canMove = true;
//右移动
private Vector3 MOVE_RIGHT = new Vector3(, , );
//上移动
private Vector3 MOVE_UP = new Vector3(, , ); //外部调控速度(为了方便看效果)
public float speed = 2f;
//移动速度向量
private Vector3 move_speed_dir = Vector3.zero;
//移动距离
private Vector3 move_dis = Vector3.zero; //控制目标
public Transform target; // Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
CheckInputKey();
CheckMoveDir();
} void FixedUpdate()
{
CheckMove();
} //检测输入按键
void CheckInputKey()
{
//检测单一输入
foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kcode))
{
Debug.Log("Single KeyCode: " + kcode);
ChangeKeyPressState(kcode, true);
} if (Input.GetKeyUp(kcode))
{
Debug.Log("Single KeyCode: " + kcode);
ChangeKeyPressState(kcode, false);
}
}
} //记录按键的按压状态
void ChangeKeyPressState(KeyCode keyCode, bool isPress)
{
switch(keyCode)
{
case INPUT_UP:
isUpPress = isPress;
break;
case INPUT_DOWN:
isDownPress = isPress;
break;
case INPUT_LEFT:
isLeftPress = isPress;
break;
case INPUT_RIGHT:
isRightPress = isPress;
break;
}
} //确定移动方向
void CheckMoveDir()
{
//确定方向
if(isUpPress && isLeftPress)
{
moveDir = MoveDir.UL;
}
else if(isUpPress && isRightPress)
{
moveDir = MoveDir.UR;
}
else if (isDownPress && isLeftPress)
{
moveDir = MoveDir.DL;
}
else if (isDownPress && isRightPress)
{
moveDir = MoveDir.DR;
}
else if(isUpPress)
{
moveDir = MoveDir.Up;
}
else if (isDownPress)
{
moveDir = MoveDir.Down;
}
else if (isLeftPress)
{
moveDir = MoveDir.Left;
}
else if (isRightPress)
{
moveDir = MoveDir.Right;
}
else
{
moveDir = MoveDir.None;
}
} //检测是否可以移动
void CheckMove()
{
//某些情况下可能禁止移动,例如暂停,播放CG等
if(canMove && moveDir != MoveDir.None)
{
PlayerMove(target, speed);
}
} //移动
void PlayerMove(Transform target, float speed)
{
move_dis = speed * Time.deltaTime * GetSpeedDir();
target.position += move_dis;
} //速度向量
Vector3 GetSpeedDir()
{
switch(moveDir)
{
case MoveDir.Up:
move_speed_dir = MOVE_UP;
break;
case MoveDir.Down:
move_speed_dir = -MOVE_UP;
break;
case MoveDir.Left:
move_speed_dir = -MOVE_RIGHT;
break;
case MoveDir.Right:
move_speed_dir = MOVE_RIGHT;
break;
case MoveDir.UL:
move_speed_dir = MOVE_UP - MOVE_RIGHT;
break;
case MoveDir.UR:
move_speed_dir = MOVE_UP + MOVE_RIGHT;
break;
case MoveDir.DL:
move_speed_dir = -MOVE_UP - MOVE_RIGHT;
break;
case MoveDir.DR:
move_speed_dir = -MOVE_UP + MOVE_RIGHT;
break;
}
return move_speed_dir.normalized;
}
}

!!!!网上有很多讲输入控制如何移动,但是多数都是讲单一按下,对于同时按下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,点击三角开始按钮(变为蓝色表示运行)
试试单一按键,两个按键一起按下,都能正常移动 --------------------------------------另一种思路解决多按键同时按下控制移动----------------------------------------------------
上面那种方法,判断按下按键转换方向时,只处理了一个按键按下,和两个按键同时按下,那么如果我同时按下三个按键或者四个按键时候就会出问题
下面上代码,区别看下面解释
 using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MyInput2 : MonoBehaviour {
//移动方向枚举
enum MoveDir
{
None = , //不动
Up = , //上8
Down = -, //下2
Left = , //左4
Right = -, //右6
UL = , //左上7
UR = -, //右上9
DL = , //左下1
DR = -, //右下3
} //输入按键常量(之后走配置)
const KeyCode INPUT_UP = KeyCode.W;
const KeyCode INPUT_DOWN = KeyCode.S;
const KeyCode INPUT_LEFT = KeyCode.A;
const KeyCode INPUT_RIGHT = KeyCode.D; //默认移动方向
private MoveDir moveDir = MoveDir.None;
//按压值
private int moveDirValue = ;
//按压记录
private bool isUpPress = false;
private bool isDownPress = false;
private bool isLeftPress = false;
private bool isRightPress = false; //是否可以移动
private bool canMove = true;
//右移动
private Vector3 MOVE_RIGHT = new Vector3(, , );
//上移动
private Vector3 MOVE_UP = new Vector3(, , ); //外部调控速度
public float speed = 2f;
//移动速度向量
private Vector3 move_speed_dir = Vector3.zero;
//移动距离
private Vector3 move_dis = Vector3.zero; //控制目标
public Transform target; // Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
CheckInputKey();
CheckMoveDir();
} void FixedUpdate()
{
CheckMove();
} //检测输入按键
void CheckInputKey()
{
//检测单一输入
foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kcode))
{
Debug.Log("Single KeyCode: " + kcode);
ChangeKeyPressState(kcode, true);
} if (Input.GetKeyUp(kcode))
{
Debug.Log("Single KeyCode: " + kcode);
ChangeKeyPressState(kcode, false);
}
}
} //记录按键的按压状态
void ChangeKeyPressState(KeyCode keyCode, bool isPress)
{
switch(keyCode)
{
case INPUT_UP:
isUpPress = isPress;
break;
case INPUT_DOWN:
isDownPress = isPress;
break;
case INPUT_LEFT:
isLeftPress = isPress;
break;
case INPUT_RIGHT:
isRightPress = isPress;
break;
}
} //确定移动方向
void CheckMoveDir()
{
moveDirValue = ;
//确定方向
if(isUpPress)
{
moveDirValue += (int)MoveDir.Up;
}
if (isDownPress)
{
moveDirValue += (int)MoveDir.Down;
}
if (isLeftPress)
{
moveDirValue += (int)MoveDir.Left;
}
if (isRightPress)
{
moveDirValue += (int)MoveDir.Right;
}
} //检测是否可以移动
void CheckMove()
{
//某些情况下可能禁止移动,例如暂停,播放CG等
if(canMove && moveDirValue != (int)MoveDir.None)
{
PlayerMove(target, speed);
}
} //移动
void PlayerMove(Transform target, float speed)
{
move_dis = speed * Time.deltaTime * GetSpeedDir();
target.position += move_dis;
} //速度向量
Vector3 GetSpeedDir()
{
switch(moveDirValue)
{
case (int)MoveDir.Up:
move_speed_dir = MOVE_UP;
break;
case (int)MoveDir.Down:
move_speed_dir = -MOVE_UP;
break;
case (int)MoveDir.Left:
move_speed_dir = -MOVE_RIGHT;
break;
case (int)MoveDir.Right:
move_speed_dir = MOVE_RIGHT;
break;
case (int)MoveDir.UL:
move_speed_dir = MOVE_UP - MOVE_RIGHT;
break;
case (int)MoveDir.UR:
move_speed_dir = MOVE_UP + MOVE_RIGHT;
break;
case (int)MoveDir.DL:
move_speed_dir = -MOVE_UP - MOVE_RIGHT;
break;
case (int)MoveDir.DR:
move_speed_dir = -MOVE_UP + MOVE_RIGHT;
break;
}
return move_speed_dir.normalized;
}
}
 

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

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

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

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

unity零基础开始学习做游戏(二)让你的对象动起来的更多相关文章

  1. unity零基础开始学习做游戏(五)看看你的完成度,进度条了解一下?

    -------小基原创,转载请给我一个面子 上回书说道,英雄和魔王都做完了,子弹也能发射了,就是不知道啥时候能干死魔王.那小基得做个血条来展示一下,他离死不远了(•౪• ) 其实血条也可以看作是进度条 ...

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

    -------小基原创,转载请给我一个面子 现在移动游戏越来越火,大家都拿手机平板玩游戏,没有键盘和手柄输入,所以就不得不看看虚拟摇杆怎么搞?(小基对于没有实体反馈不是很喜欢呢) 首先要清楚,鼠标操作 ...

  3. unity零基础开始学习做游戏(一)为了实现你的游戏,你需要提前做的准备工作

    -------小基原创,转载请给我一个面子 正所谓,工欲善其事,必现准备好电脑.接下来跟着小基一步一步来搭建你的开发环境吧 1.下载安装unity 上面的那个是破解软件,下面是unity5.5.6的安 ...

  4. unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机

    -------小基原创,转载请给我一个面子 主角都能移动了,那不得做点什么伸张正义,守护世界和平的事嘛,拿起家伙biu~biu~biu~ 首先得做一个好人和一个坏人 老规矩,Canvas下创建两个Im ...

  5. unity零基础开始学习做游戏(六)背景给我“滚”~

    -------小基原创,转载请给我一个面子 一望无际的...空旷场景,看着实在是难受,不如添加些背景吧.如果要真的想好好设计关卡背景的话,最好是做一个地图编辑器,不过做开发工具毕竟有点点复杂且枯燥,以 ...

  6. 零基础入门学习Python(36)--类和对象:给大家介绍对象

    知识点 Python3 面向对象 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前 ...

  7. javascript入门视频第一天 小案例制作 零基础开始学习javascript

    JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...

  8. 零基础如何学习 Web 安全?(转)

    在网上看了一篇文章<零基础如何学习 Web 安全?>,虽然很多东西的都不是很懂,感觉挺好的copy过来,慢慢消化: 文章地址:https://www.zhihu.com/question/ ...

  9. 零基础如何学习java更有效呢?

    零基础学java,不知道该如何入手?也不知道学习的方向,很多人会问零基础怎么样学习,有没有什么入门的书籍推荐:只要方法正确,零基础学好java也是有机会的哦. 一.理解Java思想 Java是一门面向 ...

随机推荐

  1. 高性能nosql ledisdb设计与实现(1)

    ledisdb是一个用go实现的基于leveldb的高性能nosql数据库,它提供多种数据结构的支持,网络交互协议参考redis,你可以很方便的将其作为redis的替代品,用来存储大于内存容量的数据( ...

  2. java设计模式---备忘录模式

    一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...

  3. iOS开发基础block的形式讲解

    前几个星期,我利用通知写了一个仿京东选择地址的Demo(http://blog.csdn.net/hbblzjy/article/details/52212879),后来看过一篇文章说,尽量少用通知, ...

  4. Android的原始资源Raw和Assert资源的使用-android学习之旅(五十七)

    代码示例 public class MainActivity extends Activity{ MediaPlayer mediaPlayer1,mediaPlayer2; @Override pr ...

  5. CodePen最佳实例分享

    原文地址: Chris Coyier's Favorite CodePen Demos 原文日期: 2013年8月13日 翻译日期: 2013年8月21日 CodePen: Build, Explor ...

  6. STL:STL各种容器的使用时机详解

    C++标准程序库提供了各具特长的不同容器.现在的问题是:该如何选择最佳的容器类别?下表给出了概述. 但是其中有些描述可能不一定实际.例如:如果你需呀处理的元素数量很少,可以虎落复杂度,因为线性算法通常 ...

  7. 【嵌入式开发】 Linux Kernel 下载 配置 编译 安装 及 驱动简介

    作者 : 韩曙亮 转载请出名出处 : http://blog.csdn.net/shulianghan/article/details/38636827 一. Linux 内核简介 1. 内核功能简介 ...

  8. mixer: mysql协议分析

    综述 要实现一个mysql proxy,首先需要做的就是理解并实现mysql通讯协议.这样才能通过proxy架起client到server之间的桥梁. mixer的mysql协议实现主要参考mysql ...

  9. leetcode 104 Maximum Depth of Binary Tree二叉树求深度

    Maximum Depth of Binary Tree Total Accepted: 63668 Total Submissions: 141121 My Submissions Question ...

  10. 详解ebs接口之客户配置文件导入(一)

    DECLARE l_rec_profile_t hz_customer_profile_v2pub.customer_profile_rec_type; l_rec_profile hz_custom ...