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

  现在移动游戏越来越火,大家都拿手机平板玩游戏,没有键盘和手柄输入,所以就不得不看看虚拟摇杆怎么搞?(小基对于没有实体反馈不是很喜欢呢)

首先要清楚,鼠标操作输入,应该在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零基础开始学习做游戏(三)鼠标输入,来个虚拟摇杆怎么样?的更多相关文章

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

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

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

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

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

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

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

    -------小基原创,转载请给我一个面子 小基认为电子游戏与电影最重要的区别就是交互,如果电子游戏没有让你输入的交互功能的话,全程都"只可远观,而不可鼓捣"的话,你可能是在看视频 ...

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

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

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

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

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

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

  8. 大牛整理最全Python零基础入门学习资料

    大牛整理最全Python零基础入门学习资料 发布时间:『 2017-11-12 11:56 』     帖子类别:『人工智能』  阅读次数:3504 (本文『大牛整理最全Python零基础入门学习资料 ...

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

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

随机推荐

  1. const引用

    在C++中可以声明const引用 const Type& name = var: const引用让变量拥有只读属性 const int &a = b const int &a ...

  2. Oracle Apps DBA 常用命令

    数据库启动监听 addlnctl.sh start instance 启动数据库 addbctl.sh start 启动应用服务器 adstrtal.sh 停止应用服务器 adstpall.sh -- ...

  3. Java中引用传递

    //Java中的引用传递 class Ref1{ int temp = 10 ; String Str = "hello"; } public class HelloWorld { ...

  4. Android数据库框架——GreenDao轻量级的对象关系映射框架,永久告别sqlite

    Android数据库框架--GreenDao轻量级的对象关系映射框架,永久告别sqlite 前不久,我在写了ORMLite这个框架的博文 Android数据库框架--ORMLite轻量级的对象关系映射 ...

  5. Chapter 3 Protecting the Data(4):创建和使用应用程序角色

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/39927713,专题目录:http://blog.csdn.net/dba_huangzj ...

  6. Dynamics CRM2013 更新用户数据主要电子邮件字段报数据加密错误

    今天在更新用户数据中的主要邮件字段时报数据 可以进系统设置-数据管理-数据加密中开启,但前提是必须启用https访问而不能用http,在第二个框内输入秘钥点击激活就行了,我这边已经激活过了所以显示的是 ...

  7. Swing——动作(Action)

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41258997 Action接口扩展于ActionListe ...

  8. Chipmunk僵尸物理对象的出现和解决(四)

    接上一篇,我们看看五角星和反弹棒碰撞时的代码: -(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair star:(CCNode * ...

  9. VC2010工程依赖不再自动链接

    发现 VC2010 Express  设置了 Project Dependencies 之后并没有自动链接. 而在VC2008中工程依赖不仅影响构建顺序,也会自动链接依赖项. 具体说明见: http: ...

  10. Android增量升级的方法和原理

    总结: 我们使用delta编码算法减少Android应用升级程序的大小.我们通过bsdiff和bspatch工具在android上实现delta编码算法.服务器软件和android应用已经部署.当前, ...