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是一门面向 ...
随机推荐
- CMake设置FOLDER失败及解决
CMake可以设置FOLDER属性,用来分目录组织VC中的多个工程. FOLDER: Set the folder name. Use to organize targets in an IDE. T ...
- Cytoscape源码下载地址和编译办法
开发环境:Windows2008 R2 64位+Jdk1.7+Maven3.2.3 前提条件:安装好JDK1.7到C:\Program Files\Java\jdk1.7.0_67,下载好Maven并 ...
- Uva - 1589 - Xiangqi
Xiangqi is one of the most popular two-player board games in China. The game represents a battle bet ...
- 《java入门第一季》之HashSet存储自定义对象问题以及注意事项
上一篇http://blog.csdn.net/qq_32059827/article/details/51578158 写到存储字符串类型的时候出现了无序,而且这个无序不是随机那种无序,它是有一定存 ...
- EBS DBA指南笔记(三)
第五章 patching patch的作用:解决应用代码的问题:安装新的特征:更新technology stack组件.打patch不是一个简单的过程,但我们也没必要深究里面每个细节. EBS的p ...
- Red Hat Enterprise Linux 5 64-bit chinese language support config steps
Red Hat Enterprise Linux 5 64-bit 系统下安装中文语言支持方法 测试环境:Windows2012+Vmvare9.0+Red Hat Enterprise Linux ...
- UIViewController/ApplicationSequ…
UIViewController ApplicationSequence UI-03 注意: NSLog(@"%s %d",__FUNCTION__,__LINE__); // ...
- JavaScript进阶(七)JS截取字符串substr 和 substring方法的区别
JS截取字符串substr 和 substring方法的区别 substr方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参 ...
- android 向webview传值
android中可以使用WebView加载网页,同时Android端的java代码可以与网页上的javascript代码之间相互调用. 效果图: (一)Android部分: 布局代码: <spa ...
- apktool动态破解apk
那么今天我们就用另外一种方式来破解apk:动态方式,关于动态方式其实很广义的,因为动态方式相对于静态方式来说,难度大一点,但是他比静态方式高效点,能够针对更过的破解范围.当然动态方式很多,所以这里就分 ...