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(基于上一篇的控制移动,在加点东西就非常实用了)
下面上代码
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; //鼠标按下时的坐标
private Vector3 mouseStartPos = Vector3.zero;
//鼠标是否按下
private bool isMousePress = false;
//鼠标枚举
const KeyCode INPUT_MOUSE = KeyCode.Mouse0;
//鼠标拖动范围
const float MOUSE_RADIUS = ;
//鼠标移动向量
private Vector3 mouseDir = Vector3.zero;
//鼠标速度衰减
private float mouseSpeedRate = ;
//鼠标速度
public float mouseSpeed = 2;
//摇杆底
public RectTransform joyStickDown;
//摇杆顶
public RectTransform joyStickUp;
//摄像机
public Camera camera; // Update is called once per frame
void Update () {
CheckInputKey();
CheckMoveDir();
CheckMouseDir();
} void FixedUpdate()
{
CheckMove();
} //检测输入按键
void CheckInputKey()
{
//检测单一输入
foreach (KeyCode kcode in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kcode))
{
//Debug.Log("Single KeyCode Down: " + kcode);
ChangeKeyPressState(kcode, true);
} if (Input.GetKeyUp(kcode))
{
//Debug.Log("Single KeyCode Up: " + 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;
case INPUT_MOUSE:
MouseStateChange(isPress);
break;
}
} //鼠标按键输入
void MouseStateChange(bool isPress)
{
isMousePress = isPress;
mouseStartPos = isPress ? Input.mousePosition : Vector3.zero;
joyStickDown.gameObject.SetActive(isPress);
joyStickDown.position = camera.ScreenToWorldPoint(mouseStartPos);
} //鼠标移动
void CheckMouseDir()
{
if(isMousePress)
{
mouseDir = Input.mousePosition - mouseStartPos;
mouseSpeedRate = Mathf.Min(mouseDir.magnitude / MOUSE_RADIUS, );
move_dis = mouseSpeed * mouseSpeedRate * Time.deltaTime * mouseDir.normalized;
target.position += move_dis;
joyStickUp.localPosition = mouseDir.normalized * mouseSpeedRate * MOUSE_RADIUS;
}
} //确定移动方向
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;
}
}
在按键输入控制的基础上,加上鼠标输入就ok了
思路就是:按下时候记录此时坐标,然后拖动后的当前坐标与起始坐标的向量差值,就是物体应该移动的方向
先把变量都定义好
核心就是鼠标左键按下的记录状态(这里做了个有意思的处理,第一次按下的位置,摇杆就会出现在那个位置,拖动的时候,小圆在大圆内部移动)
接下来把脚本绑定好
运行游戏,类似于这个效果,鼠标移动,红圈在白圈内移动,移动方向就是白方块(主角)移动方向
ok,通过两篇介绍,除了脚本稍稍有点难理解之外,其他应该都能一步一步做出来了,零基础的你看到自己做的“小游戏”,是不是已经成就感爆棚了?
最基本的控制移动都完成了,不如下篇博客小基介绍一下“打飞机”ლ(╹◡╹ლ)
emmm,小基是说如何发射子弹(¬_¬”)
unity零基础开始学习做游戏(三)鼠标输入,来个虚拟摇杆怎么样?的更多相关文章
- unity零基础开始学习做游戏(五)看看你的完成度,进度条了解一下?
-------小基原创,转载请给我一个面子 上回书说道,英雄和魔王都做完了,子弹也能发射了,就是不知道啥时候能干死魔王.那小基得做个血条来展示一下,他离死不远了(•౪• ) 其实血条也可以看作是进度条 ...
- unity零基础开始学习做游戏(一)为了实现你的游戏,你需要提前做的准备工作
-------小基原创,转载请给我一个面子 正所谓,工欲善其事,必现准备好电脑.接下来跟着小基一步一步来搭建你的开发环境吧 1.下载安装unity 上面的那个是破解软件,下面是unity5.5.6的安 ...
- unity零基础开始学习做游戏(四)biu~biu~biu发射子弹打飞机
-------小基原创,转载请给我一个面子 主角都能移动了,那不得做点什么伸张正义,守护世界和平的事嘛,拿起家伙biu~biu~biu~ 首先得做一个好人和一个坏人 老规矩,Canvas下创建两个Im ...
- unity零基础开始学习做游戏(二)让你的对象动起来
-------小基原创,转载请给我一个面子 小基认为电子游戏与电影最重要的区别就是交互,如果电子游戏没有让你输入的交互功能的话,全程都"只可远观,而不可鼓捣"的话,你可能是在看视频 ...
- unity零基础开始学习做游戏(六)背景给我“滚”~
-------小基原创,转载请给我一个面子 一望无际的...空旷场景,看着实在是难受,不如添加些背景吧.如果要真的想好好设计关卡背景的话,最好是做一个地图编辑器,不过做开发工具毕竟有点点复杂且枯燥,以 ...
- javascript入门视频第一天 小案例制作 零基础开始学习javascript
JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...
- 零基础如何学习 Web 安全?(转)
在网上看了一篇文章<零基础如何学习 Web 安全?>,虽然很多东西的都不是很懂,感觉挺好的copy过来,慢慢消化: 文章地址:https://www.zhihu.com/question/ ...
- 大牛整理最全Python零基础入门学习资料
大牛整理最全Python零基础入门学习资料 发布时间:『 2017-11-12 11:56 』 帖子类别:『人工智能』 阅读次数:3504 (本文『大牛整理最全Python零基础入门学习资料 ...
- 零基础如何学习java更有效呢?
零基础学java,不知道该如何入手?也不知道学习的方向,很多人会问零基础怎么样学习,有没有什么入门的书籍推荐:只要方法正确,零基础学好java也是有机会的哦. 一.理解Java思想 Java是一门面向 ...
随机推荐
- UNIX网络编程——TCP输出,UDP输出
TCP输出 每一个TCP套接字有一个发送缓冲区,我们可以使用SO_SNDBUF套接字选项来更改该缓冲区的大小.当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到(或是应用程序的缓 ...
- Java中封装性的使用
//Java面对对象基本特性之一:封装性 //作用:保护某些属性和方法不被外部所看见 //封装的实现:通过关键字private声明 //鼠标右键--->Source---->Generat ...
- python 内存数据库与远程服务
python 内存数据库与远程服务 需要import的python 内存数据库代码参考下面的链接: http://blog.csdn.net/ubuntu64fan/article/details/5 ...
- LocalBroadcastManager—创建更高效、更安全的广播
前言 在写Android应用时候,有时候或多或少的需要运用广播来解决某些需求,我们知道广播有一个特性,就是使用sendBroadcast(intent);发送广播时,手机内所有注册了Broadcast ...
- HTTP 消息结构
HTTP 消息结构 HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议. 一个HTTP"客户端"是一个应用程序(Web浏览 ...
- 【Unity Shaders】Reflecting Your World —— Unity3D中简单的Cubemap反射
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- iOS 远程消息推送,原理和开发详解篇(新手推荐)
1.APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Servic ...
- 面向对象编程(OOP)的五大特征-java学习之旅(1)
这是Alan Kay关于第一个成功的面向对象语言SmallTalk的总结: 1.所有的东西都是对象.可将对象想象成一种新型的变量:它保存着数据,但是可要求它对自身进行操作,理论上讲,可从要解决的问题身 ...
- 关于CKEditor4.5.6的使用,自定义toolbar配置,上传图片案例(SpringMVC+MyBatis案例),自定义行高,去编辑器的中内容,将编辑器中内容设置到指定的位置等
关于CKEditor的一个配置整理,改文件为config.js: 文件内容如下: /** * @license Copyright (c) 2003-2016, CKSource - Frede ...
- 分布式进阶(十一) Docker 常见错误汇总
NO.1 以上添加网桥的命令在Ubuntu14.04中是不可行的.正确的命令如下: brctl addbr br0 ifconfig br0 192.168.1.188 netmask 255.255 ...