zoukankan      html  css  js  c++  java
  • UGUI实现街机摇杆及技能判定

    本文首发自蛮牛网

    http://www.unitymanual.com/thread-41713-1-1.html?_dsign=4e15f5e6

          应朱迪之邀,有幸在蛮牛分享一些心得体会,本章主要阐述了 实现一个属于自己的摇杆的必要性,街机摇杆的判定原理,如何去实现一个摇杆以及技能判定,你可通过本文学会做一个基本的方向摇杆以及技能摇杆,如有兴趣请继续阅读


    一 . 在阅读本篇以前我们先看下两个小菜问题
    1.为什么要自己去实现摇杆而不是使用easytouch之类的插件 ?
    答:因为这类插件太厚重,自己去改源码往往又会面临改出bug的窘况
    2.举几个操纵摇杆发技能的栗子
    答:拳皇系列,三国系列 等等,人物发招都是通过摇杆加指令键 发出,如果你没有玩过这类游戏,推荐你去下一个拳皇玩玩
    二 . 街机摇杆判定的原理
    图1中左边为摇杆,中间一点为摇杆的中心点 坐标为(0,0,0),右边为技能键,当玩家的摇杆偏离中心点并且开始运动,如果 玩家手指滑动到这个蓝圈之外(本文 我称之为有2D0ff">效判定区),这时手指所处位置正是箭头所在位置,恰好角度为90度,我所说的这个90度是相对的,各位不必深究。我在本文称这个角度为 有效判定角度,也就是现在有两个条件构成了摇杆判定生效的前提
          1.手指当前所在位置与圆心的直径必须大于有限判定区域
          2.在手指当前所在位置与圆心的的连线,角度必须处于有效判定角度,这个角度是一个阀值如80度至100度,相对于90度的有效判定而言多了一些余地,而这个区间的调整,直接影响到摇杆的整个手感,更直观的感受是该放技能的时候技能放不出
         简单的单点判定也说到这儿也就说完了,如果要说是更复杂的技能释放,那也就是在简单的判定加上 有效数据(我在本篇中将手指连续滑过的满足两个条件的点累计记录,直到按下技能键结算滑过的点,这些点的集合被称之为有效数据),结算有效数据的方式多样
         1.按下技能键结算
         2.实时监测有效数据结算
         3.手指松开结算有效数据
         4…..
         原理说道这儿我想也就说完了,大家思索一下便也能明白过来,后文开始写代码
    三. 动手实现一个街机摇杆
    我们最终将通过摇杆的有效数据,判定一个八神庵技能 百式·鬼燃烧 ,为了简单明了判定键被省去,当玩家手指移开摇杆则开始判定。此技能判定数据为 后 下 前,也就是逆时针下半圈 。
    1.需要获取摇杆被点击事件    

    public void StartLisener ()
    {
       TouchLock = true;
    }
    public void StopLisener ()
    {
       TouchLock = false;
    }

    2.在Update中监听事件的触发
    void Update ()
        {
            if (TouchLock) {
                Tumb.localPosition = GetLocalPosition ();
            } else {
                Tumb.localPosition = Vector3.zero;
            }
        }


    3.实现获取摇杆中心位置 也就是手指当前位置,并且记录有效数据,这里的角度阀值是可调控的这给出了20度的阀值

    Vector3 GetPos ()
        {
            #if UNITY_EDITOR
            return Input.mousePosition;
            #endif
        }
    
        protected Vector3 GetLocalPosition ()
        {
            //手指坐标转ugui相对坐标
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle (transform as RectTransform, GetPos (), currentCanvas.worldCamera, out pos)) {
                //这里我们事先计算了半径的距离,如果手指的距离超过半径的距离则开始判定
                if (pos.sqrMagnitude >= TempSqrDiameter) {
                    //为了不让摇杆的原点图标超出摇杆的圆框,这里我们计算手指的归一化向量乘以圆的半径
                    pos = pos.normalized * Diameter;
    
                    //这段代码比较重要 为了计算简便 我使用了vector2.angle函数,假定up方向角度为0,右为正方向,则可将此圆看作 0度-359.9度
                    angle = pos.x > 0 ? Vector2.Angle (Vector2.up, pos) : 360f - Vector2.Angle (Vector2.up, pos);
    
                    //这里我们假定这个阀值为20度,并且将摇杆简单划分为 上 下 左 右 四个方向
                    //上所正对应 0 度 下所对应的是180 左对应270 右对应90
    
                    if (angle > 350 || angle < 10) {
                        //若是有效数据则添加
                        if (!ValidData.Contains ("1")) {
                            ValidData.Add ("1");
                        }
                    }
                    if (angle > 80 && angle < 100) {
                        if (!ValidData.Contains ("2")) {
                            ValidData.Add ("2");
                        }
                    }
                    if (angle > 170 && angle < 190) {
                        if (!ValidData.Contains ("3")) {
                            ValidData.Add ("3");
                        }
                    }
                    if (angle > 260 && angle < 280) {
                        if (!ValidData.Contains ("4")) {
                            ValidData.Add ("4");
                        }
                    }
                    
                } else {
                    //若为达到有限判定距离则忽略
                    angle = pos.x > 0 ? Vector2.Angle (Vector2.up, pos) : 360f - Vector2.Angle (Vector2.up, pos);
                }
                return new Vector3 (pos.x, pos.y, 0);
            }
            return Vector3.zero;
        }

    4.进行有效数据的判定,当然这里的判定是活的 你完全可以做一个技能数据的列表 代替 下文的 “432” 实现匹配数据释放不同的技能

    public void StopLisener ()
        {
            TouchLock = false;
        
            //TODO: 判断有效数据
            ValidData.ForEach (x => tempStr += x);
            Debug.Log ("Log Total Point" + tempStr);
    
            //如果有效数据为 技能指令 ‘432’ 则触发技能
            if (tempStr == "432") {
                ani.SetTrigger ("Skill");
            }
    
            tempStr = string.Empty;
            ValidData.Clear ();
        }

    话说到这里代码也就写完了,讲了一堆原理 代码也不过寥寥几行便也实现了所谓街机摇杆,当然 实际运用中你需要考虑的更多,比如实现技能CD与技能数据的匹配 等等。借以此文抛砖引玉,相信你能活学活在开发中帮助到你。

  • 相关阅读:
    C#
    数据库SQL Server
    JavaScript题目
    vscode: Visual Studio Code 常用快捷键
    jQuery教程
    JavaScript快速排序
    JS编程艺术
    JS
    linux 笔记
    积累的各种资源
  • 原文地址:https://www.cnblogs.com/Keyle/p/4698953.html
Copyright © 2011-2022 走看看