unity3d滑动操作判断条件

2017-06-29 22:17:47 yzx5452830 阅读数 14796
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

 private Vector2 st = Vector2.zero; //手指开始按下的位置  
    private Vector2 end = Vector2.zero; //手指拖动的位置  
    enum slideVector { nullVector,up,down, left, right }; //上下左右四个方向
    private slideVector currentVector = slideVector.nullVector; //默认是null
    private float timer;//时间计数器  
    public float offsetTime = 0.01f;//判断的时间间隔  

    void OnGUI()
    {
        if (Event.current.type == EventType.MouseDown)//判断当前手指是按下事件  
        {
            st = Event.current.mousePosition;//记录开始按下的位置  
        }
        if (Event.current.type == EventType.MouseDrag)//判断当前手指是拖动事件  

        {
            timer += Time.deltaTime;  //计时器

            if (timer > offsetTime)
            {
                end = Event.current.mousePosition; //记录结束下的位置
                Vector2 slideDirection = st - end;
                float x = slideDirection.x;
                float y = slideDirection.y;

                if (y < x && y > -x)
                {
                    if (currentVector == SlideVector.left) //判断当前方向
                    {
                        return;
                    }                  
                    Debug.Log("left");
                    currentVector = SlideVector.left; //设置方向
                }
                else if (y > x && y < -x)
                {
                    if (currentVector == SlideVector.right)
                    {
                        return;
                    }
                    Debug.Log("right");                  
                    currentVector = SlideVector.right;
                }
                else if (y > x && y > -x)
                {
                    if (currentVector == SlideVector.up)
                    {
                        return;
                    }
                    Debug.Log("up");               
                    currentVector = SlideVector.up;
                }
                else if (y < x && y < -x)
                {
                    if (currentVector == SlideVector.down)
                    {
                        return;
                    }
                    Debug.Log("down");                 
                    currentVector = SlideVector.down;
                }
                timer = 0;
                st = end;//初始化位置
               
            }        
        }
        if (Event.current.type == EventType.MouseUp)
        {
            currentVector = slideVector.nullVector;       //初始化方向  
        }
    }

 

2017-07-05 更新   

添加了一个滑动距离 不然手指刚刚触碰上去就开始判断了滑动  

我个人默认距离是80  滑动距离超过80的时候才开始执行方法

 

    enum slideVector { nullVector, up, down, left, right };
    private Vector2 touchFirst = Vector2.zero; //手指开始按下的位置
    private Vector2 touchSecond = Vector2.zero; //手指拖动的位置
    private slideVector currentVector = slideVector.nullVector;//当前滑动方向
    private float timer;//时间计数器  
    public float offsetTime = 0.1f;//判断的时间间隔 
    public float SlidingDistance = 80f;

    void OnGUI()   // 滑动方法02
    {
        if (Event.current.type == EventType.MouseDown)
        //判断当前手指是按下事件 
        {
            touchFirst = Event.current.mousePosition;//记录开始按下的位置
        }
        if (Event.current.type == EventType.MouseDrag)
        //判断当前手指是拖动事件
        {
            touchSecond = Event.current.mousePosition;

            timer += Time.deltaTime;  //计时器

            if (timer > offsetTime)
            {
                touchSecond = Event.current.mousePosition; //记录结束下的位置
                Vector2 slideDirection = touchFirst - touchSecond;
                float x = slideDirection.x;
                float y = slideDirection.y;

                if (y + SlidingDistance < x && y > -x - SlidingDistance)
                {

                    if (currentVector == slideVector.left)
                    {
                        return;
                    }

                    Debug.Log("right");
                 
                    currentVector = slideVector.left;
                }
                else if (y > x + SlidingDistance && y < -x - SlidingDistance)
                {
                    if (currentVector == slideVector.right)
                    {
                        return;
                    }

                    Debug.Log("left");
       
                    currentVector = slideVector.right;
                }
                else if (y > x + SlidingDistance && y - SlidingDistance > -x)
                {
                    if (currentVector == slideVector.up)
                    {
                        return;
                    }

                    Debug.Log("up");
                  
                    currentVector = slideVector.up;
                }
                else if (y + SlidingDistance < x && y < -x - SlidingDistance)
                {
                    if (currentVector == slideVector.down)
                    {
                        return;
                    }

                    Debug.Log("Down");
                   
                    currentVector = slideVector.down;
                }

                timer = 0;
                touchFirst = touchSecond;
            }
            if (Event.current.type == EventType.MouseUp)
            {//滑动结束  
                currentVector = slideVector.nullVector;
            }
        }   // 滑动方法
    }  

 

 

 

 

 

2016-01-13 20:15:21 tom_221x 阅读数 4353
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

 这里的多点触摸实现方式具有通用性,在提供触摸事件调用和触摸点数据的情况下都可实现。首先,我们需要继承复写ScrollRect的OnDrag方法,让其在一个触摸点的情况下,使用原有拖拽功能,在两个点的情况下,滑动缩放。


		private int touchNum = 0;
		public override void OnBeginDrag (PointerEventData eventData)
		{
			if(Input.touchCount > 1) 
			{
				return;
			}

			base.OnBeginDrag(eventData);
		}

		public override void OnDrag (PointerEventData eventData)
		{
			if (Input.touchCount > 1)
			{
				touchNum = Input.touchCount;
				return;
			}
			else if(Input.touchCount == 1 && touchNum > 1)
			{
				touchNum = Input.touchCount;
				base.OnBeginDrag(eventData);
				return;
			}

			base.OnDrag(eventData);
		}


使用unity自己的触摸判断,Input.touchCount,在正常情况下调用SrollRect自己的方法处理。否则,执行自己的处理。OnDrag中touchCout从多个变回一个的时候,我们首先需要调用一下OnBeginDrag,然后下一帧在执行一个点的逻辑。在实测用,这是为了解决从多个点变回一个点,但这个点是后触摸的点,会造成跳动的问题。



多点滑动的逻辑是写在Update方法里面。经过测试,发现如果写在OnDrag方法里面。会出现放到最大继续快速滑动,或是最小在快速缩小,出现突然缩放的情况。而实际上应该不能继续放大或缩小。


		private float preX;
		private float preY;

		private void Update()
		{
		   if (Input.touchCount == 2)
			{
				Touch   t1   = Input.GetTouch(0);
				Touch   t2   = Input.GetTouch(1);
  
				Vector3 p1   = t1.position;
				Vector3 p2   = t2.position;

				float   newX = Mathf.Abs(p1.x - p2.x);
				float   newY = Mathf.Abs(p1.y - p2.y);

				if (t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began)
				{
					preX = newX;
					preY = newY;
				}
				else if (t1.phase == TouchPhase.Moved && t2.phase == TouchPhase.Moved)
				{	
					RectTransform rt    = base.content;
					float         scale = (newX + newY - preX - preY) / (rt.rect.width * 0.25f) + rt.localScale.x;

					if (scale > 1.0f && scale < 2.5f)
					{		
						float ratio   = scale / rt.localScale.x;

						rt.localScale = new Vector3(scale, scale, 0);

						float maxX    = base.content.rect.width  * scale / 2 - this.viewRect.rect.width  / 2;
						float minX    = -maxX;

						float maxY    = base.content.rect.height * scale / 2 - this.viewRect.rect.height / 2;
						float minY    = -maxY;

						Vector3 pos   = rt.position * ratio;

						if (pos.x > maxX)
						{
							pos.x = maxX;
						}
						else if (pos.x < minX)
						{
							pos.x = minX;
						}

						if (pos.y > maxY)
						{
							pos.y = maxY;
						}
						else if (pos.y < minY)
						{
							pos.y = minY;
						}

						rt.position = pos;
					}
				}

				preX = newX;
				preY = newY;
			}
		}


float newX = Mathf.Abs(p1.x - p2.x); 

float newY = Mathf.Abs(p1.y - p2.y);

这里我们计算的是两个触摸点坐标差值的绝对值。用来粗略的判断两个点的位置关系。


t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began

这个条件判断是为了,在移动条件达成时候,初始化前一个坐标点的数据。


float scale = (newX + newY - preX - preY) / (rt.rect.width * 0.25f) + rt.localScale.x;

这是一个粗略的判断算法。用新的xy差值减去上次的xy差值,这个结果反映了两个手指的距离变化。然后除以rt.rect.width,得到这个距离变化与缩放目标宽度的比例。0.25f是一个调整系数,用来控制scale的变化率。这里的数值就是根据手势得到的缩放率,然后加上原有的缩放数值,得到的scale就是最终需要缩放的数值。


scale > 1.0f && scale < 2.5f

这个条件约束了,最终的缩放的范围。


后面的算法,做了两个事情。

设置最终的缩放,然后计算边界的约束,让缩放后位置仍然在边界内。不然,我放大拖到边界,然后缩小就会越界的情况。

根据缩放的倍率,来设置新的位置。比如,原有位置不在00点,缩放了,那么位置也缩放同一个倍率,就能让缩放中心同步出现在手势操作位置上,而不是物体中心。


float ratio   = scale / rt.localScale.x;

这里新的缩放值除以原有缩放值,得到的就是缩放的倍率。


Vector3 pos = rt.position * ratio;

用原有的位置坐标乘以缩放倍率,得到新的位置。



float maxX = base.content.rect.width * scale / 2 - this.viewRect.rect.width / 2; 

float minX = -maxX;

float maxY = base.content.rect.height * scale / 2 - this.viewRect.rect.height / 2; 

float minY = -maxY;

这里是计算位置的边界。



if (pos.x > maxX) {

      pos.x = maxX;

 } else if (pos.x < minX) { 

     pos.x = minX;

 } 


if (pos.y > maxY) { 

    pos.y = maxY;

 }  else if (pos.y < minY)  {

    pos.y = minY;

 }

 rt.position = pos;


根据边界计算新的位置坐标。




2017-04-20 21:18:57 yongh701 阅读数 6654
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

血条是在游戏中非常常见的东西,和Cocos2dx中《【Cocos2dx】利用音量螺旋控件控制血量条 》(点击打开链接)一样,Unity3D的血条也其实就是用一个slider就能做完的事情。同时,本文也将继《【Unity3D】用鼠标点击事件、AddForce完成跳跃与二段跳》(点击打开链接)说明鼠标点击屏幕屏幕进一步说明鼠标点击任一物体的监听。

下面将举一个例子说明这个物体,如图,血条代表10格血,如果球被点一下,则扣1格血,点屏幕其它地方不扣血。


一、场景布置

1、这部分主要叙述怎么将Slider改成血条的。开始先放个球、调整下照相机,在球中放个灯光看起来更好看,就不赘述了。


2、如同《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)中所有UI一样,一旦用到UGUI,先要添加一个Canvas,之后再于Canvas上整个Slider。Slider添加完毕,直接将Handle SliderArea去掉,也就是那个滑动杆、滑块。


同时在Slider的Inspector中是不可交互的,以为不允许用户自行滑动滑块。


3、修改Background的背景色为黑色,Fill Area的Fill填充色为红色,如图所示。


4、弄好之后,发现血条并未被填满。其实空出来这部分原本就是留给被我们去掉的Handle SliderArea的。


现在选择Fill Area在Inspector面板中修改Rect Transform中个属性,将Left、Right的值都设为0,至此一个简单的血条就制作完成了,或者你直接用矩形工具将红色的Fill Area调整到和Background一样大小也行。

5、之后我们并不需要这个Canvas和《【Unity3D】UGUI自适应屏幕与锚点》(点击打开链接)一样填充到整个屏幕。如下图,将Canvas的渲染设置到World Space,也就是像普通东西一样渲染。


之后我们需要同时对Slider和Canvas的位置和大小进行调整。调整后的属性,如图所示,不然太大了。


二、脚本布置

之后我们要实现点击球,就扣血的功能,编写如下脚本SphereClicked.cs,赋予到球上。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;    //Slider属于UI,用到这个头文件

public class SphereClicked : MonoBehaviour
{

    public Slider HPStrip;    //添加血条Slider的引用
    public int HP = 10;//开始为10滴血
    void Start()
    {
        HPStrip.value = HPStrip.maxValue = HP;    //初始化血条
        GameObject.Find("Sphere").AddComponent<MeshCollider>();//球与下面的抽象射线碰撞检测必须
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))//鼠标左键点下
        {
            //住摄像机向鼠标位置发射射线  
            Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit mHit;
            //射线检验  
            if (Physics.Raycast(mRay, out mHit))
            {
                if (mHit.collider.gameObject.tag == "Sphere")
                {
                    HP--;//点到这个球,血就-1
                    HPStrip.value = HP;    //对血条执行操作
                }
            }
        }

        /*之后还可以根据HP进行一些操作*/
        if (HP <= 0)
        {
            //写下血条被清空之后的处理
        }
    }

}
给球上这个脚本之后,还没有完,如同《【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏》(点击打开链接)碰撞检测一样,我们先要给这个球,赋予一个tag,根据代码,这里的tag就是"Sphere"。再如同《【Unity3D】同场景物体传值与Vector》(点击打开链接)中,设定我们这个脚本的public Slider HPStrip;就是我们刚才弄好的血条。


2017-04-28 14:16:16 qq_26270779 阅读数 8421
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity判断手势触摸的类型 ,判断手势的滑动方向,并获取刚触摸以及触摸结束事的坐标

本章咱们一起来看下unity对有触摸手势做出的响应

单点触摸

Input.touchCount==1

移动触摸

Input.GetTouch(0).phase==TouchPhase.Moved

多点触摸

Input.touchCount > 1

判断两只手指至少有一只为移动触摸

Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved

 

/**

     * 判断是否为单点触摸

     **/

    public static bool singleTouch()

    {

        if(Input.touchCount==1)

            return true;

        return false;

    }

 

    /**

     * 判断单点触摸条件下  是否为移动触摸

     **/

    public static bool moveSingleTouch()

    {

        if (Input.GetTouch(0).phase==TouchPhase.Moved)

            return true;

        return false;

    }

 

    /**

     *判断是否为多点触摸 

     **/

    public static bool multipointTouch()

    {

        if (Input.touchCount > 1)

            return true;

        return false;

    }

 

    /**

     *判断两只手指至少有一只为移动触摸

     **/

    public static bool moveMultiTouch()

    {

        if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)

            return true;

        return false;

}

 

/**

     * 

     * 新建一个公共方法用于判断手指的移动方向 

     * 假如是往左或者往上 则模型往各个轴的正方向位置移动 函数返回1

     * 加入是往右或者往下 则模型往各个轴的负方向位置移动 函数返回-1

     * 

     * **/

    int judueFinger(){

        if (Input.GetTouch(0).phase == TouchPhase.Began && startPosFlag == true)

        {

            //Debug.Log("======开始触摸=====");

            startFingerPos = Input.GetTouch(0).position;

            startPosFlag = false;

        }

        if (Input.GetTouch(0).phase == TouchPhase.Ended)

        {

            //Debug.Log("======释放触摸=====");

            startPosFlag = true;

        }

        nowFingerPos = Input.GetTouch(0).position;

        xMoveDistance = Mathf.Abs(nowFingerPos.x - startFingerPos.x);

        yMoveDistance = Mathf.Abs(nowFingerPos.y - startFingerPos.y);

        if (xMoveDistance>yMoveDistance)

        {

            if(nowFingerPos.x-startFingerPos.x>0){

                //Debug.Log("=======沿着X轴负方向移动=====");

                backValue = -1;         //沿着X轴负方向移动

            }

            else

            {

                //Debug.Log("=======沿着X轴正方向移动=====");

                backValue = 1;          //沿着X轴正方向移动

            }

        }

        else

        {

            if (nowFingerPos.y - startFingerPos.y>0)

            {

                //Debug.Log("=======沿着Y轴正方向移动=====");

                backValue = 1;         //沿着Y轴正方向移动

            }else{

                //Debug.Log("=======沿着Y轴负方向移动=====");

                backValue = -1;         //沿着Y轴负方向移动

            }

        }

        return backValue;

    }


2017-10-28 16:07:05 qq_36930071 阅读数 0
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity判断手势触摸的类型 ,判断手势的滑动方向,并获取刚触摸以及触摸结束事的坐标

单点触摸
Input.touchCount==1
移动触摸
Input.GetTouch(0).phase==TouchPhase.Moved
多点触摸
Input.touchCount > 1
判断两只手指至少有一只为移动触摸
Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved
 
/**
     * 判断是否为单点触摸
     **/
    public static bool singleTouch()
    {
        if(Input.touchCount==1)
            return true;
        return false;
    }
 
    /**
     * 判断单点触摸条件下  是否为移动触摸
     **/
    public static bool moveSingleTouch()
    {
        if (Input.GetTouch(0).phase==TouchPhase.Moved)
            return true;
        return false;
    }
 
    /*
     *判断是否为多点触摸 
     **/
    public static bool multipointTouch()
    {
        if (Input.touchCount > 1)
            return true;
        return false;
    }
 
    /**
     *判断两只手指至少有一只为移动触摸
     **/
    public static bool moveMultiTouch()
    {
        if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
            return true;
        return false;
}
 
/**
     * 
     * 新建一个公共方法用于判断手指的移动方向 
     * 假如是往左或者往上 则模型往各个轴的正方向位置移动 函数返回1
     * 加入是往右或者往下 则模型往各个轴的负方向位置移动 函数返回-1
     * 
     * **/
    int judueFinger(){
        if (Input.GetTouch(0).phase == TouchPhase.Began && startPosFlag == true)
        {
            //Debug.Log("======开始触摸=====");
            startFingerPos = Input.GetTouch(0).position;
            startPosFlag = false;
        }
        if (Input.GetTouch(0).phase == TouchPhase.Ended)
        {
            //Debug.Log("======释放触摸=====");
            startPosFlag = true;
        }
        nowFingerPos = Input.GetTouch(0).position;
        xMoveDistance = Mathf.Abs(nowFingerPos.x - startFingerPos.x);
        yMoveDistance = Mathf.Abs(nowFingerPos.y - startFingerPos.y);
        if (xMoveDistance>yMoveDistance)
        {
            if(nowFingerPos.x-startFingerPos.x>0){
                //Debug.Log("=======沿着X轴负方向移动=====");
                backValue = -1;         //沿着X轴负方向移动
            }
            else
            {
                //Debug.Log("=======沿着X轴正方向移动=====");
                backValue = 1;          //沿着X轴正方向移动
            }
        }
        else
        {
            if (nowFingerPos.y - startFingerPos.y>0)
            {
                //Debug.Log("=======沿着Y轴正方向移动=====");
                backValue = 1;         //沿着Y轴正方向移动
            }else{
                //Debug.Log("=======沿着Y轴负方向移动=====");
                backValue = -1;         //沿着Y轴负方向移动
            }
        }
        return backValue;
    }


作者q:2366809774一起进步一起学习

Unity3D 脚本参考

阅读数 14349