Unity 使用有限状态机 完美还原 王者荣耀 虚拟摇杆

效果如图所示


摇杆的UI组成

如图所示 简单的可以认为摇杆由1、2、3贴图组成

  1. 为摇杆的底座
  2. 为摇杆的
  3. 为摇杆的指向

可以理解这就是街机上的摇杆


详解---摇杆显示规则

如图所示

  • 最外面绿色的矩形为可点击区域
  • 黑色矩形为摇杆的显示区域
  1. 摇杆在操作结束后会回到抬起位置(如图状态)

  2. 摇杆的可点击区域有限制(如图绿色框)

  3. 摇杆的显示区域有限制(如图黑色框 作用:防止摇杆一半在屏幕外 )

  4. 摇杆的中心位置随点击位置改变(如果在显示区域外则取临界值

更据上面的规则定义public变量可以方便策划大佬运行状态随时修改


详解---操作摇杆的几种动作、状态

首先我们把摇杆系统分解成状态、动作

  • 闲置(状态)
  • 按下(动作)
  • 抬起(动作)
  • 准备(状态)
  • 拖动(状态)

动作、状态区别重点

  • 动作:一旦执行完毕就结束了(调用一次
  • 状态:如果没有外部条件的触发,一个状态会一直持续下去(不停的调用

  • 闲置---状态

    • 不需要做任何处理

  • 按下---动作(手指按下屏幕 触发)

    • 获取手指按下坐标
    • 设置摇杆的位置(如左图)
    • 如果坐标在显示区域外,则取临界值(如右图)
    • UI、特效的显示或隐藏

  • 抬起---动作(手指离开屏幕 触发)

    • 摇杆回到抬起位置
    • UI、特效的显示或隐藏

  • 准备---状态(手指按下屏幕动作完成 触发)

    • 获取手指的实时坐标
    • 如果实时坐标按下坐标的距离大于设定值则切换到拖动状态
    • UI、特效的显示或隐藏

  • 拖动---状态(手指滑动 触发)

    • 获取手指的实时坐标
    • 获取实时坐标与摇杆的坐标的距离P
    • 设置杆的位置
      • 如果杆的位置超过可拖动的最大值则取最大值
  • 设置指向的位置
    • 如果距离P大于显示指向最小值则显示指向同时
    • 否则隐藏指向

这些动作、状态是我边测试边写代码总结出来的

使用枚举定义摇杆的几种状态、动作

可源代码中找到对应的方法


详解---几种状态、动作之间切换

  • 手指按下切换到---按下动作

  • 手指抬起切换到---抬起动作

  • 按下动作执行完成切换到---准备状态

  • 准备状态达成条件切换到---拖动状态



使用到的API和方法

如果你理解了摇杆系统,但遇到了一些技术上的问题,下面的方法可能帮助你

  • 计算两个坐标的距离
        float distance = Vector3.Distance(Vec0, Vec1);
  • 获取手指按下位置
        Vector3 mousePosition = UICamera.currentTouch.pos;
  • 计算手指按下相对于摇杆的位置
        //转换为世界坐标
mousePosition = UICamera.currentCamera.ScreenToWorldPoint(mousePosition);
//转换为本地坐标
mousePosition = transform.InverseTransformPoint(mousePosition);
  • 设置摇杆指向的角度
        //mouseLocalPosition手指按下相对于摇杆的坐标
//background摇杆
//direction指向
Double angle = Math.Atan2((mouseLocalPosition.y - background.localPosition.y), (mouseLocalPosition.x - background.localPosition.x)) * 180 / Math.PI;
//设置摇杆指向的角度
direction.eulerAngles = new Vector3(0, 0, (float)angle);

如果有更好的办法 求大佬赐教


老规矩工程链接:https://github.com/QiangZou/Joystick

UI、适配由NGUI实现,需要导入NGUI到工程中(NGUI有点大,没上传)

Unity 使用有限状态机 完美还原 王者荣耀 虚拟摇杆的更多相关文章

  1. Unity 使用 陀螺仪 实现 《王者荣耀》 登入界面 背景动态效果

    在 <王者荣耀> 登入界面 左右上下晃动手机(有些手机不支持)可以看到背景在变化 我使用的是iPhone SE 效果如下: 对比两张图片的左下角 可以看到差异 至于为什么要这么做: 1.使 ...

  2. Unity3d项目入门之虚拟摇杆

    Unity本身不提供摇杆的组件,开发者可以使用牛逼的EasyTouch插件或者应用NGUI实现相关的需求,下面本文通过Unity自身的UGUI属性,实现虚拟摇杆的功能. 主参考 <Unity:使 ...

  3. Unity制作王者荣耀商业级手游

    <王者荣耀>这种现象级手机游戏是如何制作出来的呢?本文以<王者荣耀>MOBO类型的多人在线战术竞技游戏为入口,覆盖Unity游戏制作开发前端与Node.js服务器端的开发必备知 ...

  4. 《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了

    如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...

  5. 【转】《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了

    如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...

  6. 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍

    在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...

  7. 基于NABCD评论作业-王者荣耀交流协会PSP DAILY

    一.根据(不限于)NABCD评论作品的选题   N(Need,需求):在我知道PSP DAILY这款软件的时候,就认为这款软件对于学习软件工程课的学生来说有很大的需要.对于需求来说,软件工程课程中的学 ...

  8. [0]尝试用Unity3d制作一个王者荣耀(持续更新)->游戏规划

    太得闲了于是想写个农药,虽然可能会失败但是还是要试一试. 因为是自学的不是Unity专业的可能表达语言会有些不标准!望见谅! 结构: 以组件式(比如说摇杆控制和玩家部分的编写是分离的,可以自由拼装)作 ...

  9. 当会打王者荣耀的AI学会踢足球,一不小心拿下世界冠军!

    难得的元旦小假期,没有什么比得上在慵懒的冬日艳阳下放松自己,拿起手机,叫上了许久未一起作战的小伙伴,到王者荣耀中激战了一番,仿佛又回到了当年那个年轻的自己. 厉害不,毕竟当年DD也是王者五十星的水平, ...

随机推荐

  1. 向文件写入一个数据块---write

    函数原型:ssize_t write(int fd,const void *buf,size_t count); 参数说明:fd:文件描述符,buf:写入数据的缓冲区,count:写入数据的最大长度. ...

  2. (二进制 异或)Team Formation --ZOJ --3870

    链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3870 http://acm.hust.edu.cn/vjudge/ ...

  3. mac与win7(台式电脑)共享文件

    人生处处又都坑,自己走过了,所以记下来. mac共享文件,win7访问: 1.系统偏好设置-共享-都选中就行.一般都会这样说. 2.系统偏好设置-用户与群组-解锁-客人用户-允许客人用户连接到共享文件 ...

  4. 基于Maven的S2SH(Struts2+Spring+Hibernate)框架搭建

    1. 前言 基于Maven的开发方式开发项目已经成为主流.Maven能很好的对项目的层次及依赖关系进行管理.方便的解决大型项目中复杂的依赖关系.S2SH(Struts2+Spring+Hibernat ...

  5. IllegalArgumentException: requirement failed: Corrupt index found

    今天突然接到客户反映线上服务器发送消息异常,登录服务器查看是kafka服务出现了问题,想重启一下服务,结果重启出现一下报错 [2017-06-30 19:29:13,708] FATAL Fatal ...

  6. 在ContextLoaderListener中使用注解注入的类和job中使用注解注入的类

    场景:在ContextLoaderListener子类中加载job,为JobFactory的实现类声明@Component后,在ContextLoaderListener子类中为scheduler设置 ...

  7. jQuery基础【1】

    jQuery 是一个“写的更少,但做的更多”的轻量级 JavaScript 库.jQuery 极大地简化了 JavaScript 编程.jQuery 很容易学习.jQuery 库位于一个 JavaSc ...

  8. LeetCode149:Max Points on a Line

    题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight li ...

  9. AbpZero后台模块化(1)

    AbpZero的精髓就在于多租户模块化加载,如果不做到这两种的话,就没必要使用这个框架. 1.首先,我们得新建一个类库,用于存放我们写的业务代码.       在类库下分别建立三个类文件:TestAp ...

  10. java poi 获取单元格值时间

    完整帮助类:JAVA poi 帮助类 /* * poi特殊日期格式:数字格式化成-yyyy年MM月dd日,格式 * */ private static ArrayList<String> ...