c# - 在Unity 3D中模拟 "Swipe to Unlock"

标签 c# unity-game-engine

我必须在 Unity 3D 中创建一个“滑动解锁”功能(就像 iPhone 锁屏中的功能一样)。我尝试了以下方法:

第 1 部分 - 检测滑动

我可以使用以下代码检测滑动:

private bool couldBeSwipe = false;
private float minSwipeDistance = 14;
private float maxSwipeTime = 10;
private float comfortZone = 100;
private float startTime;
private Vector2 startPos;
const int SWIPE_NONE = 0;
const int SWIPE_UP = 1;
const int SWIPE_RIGHT = 2;
const int SWIPE_DOWN = 3;
const int SWIPE_LEFT = 4;
private int swipeDirection = SelectStageScene.SWIPE_NONE;

void Update() :

    // Input
    swipeDirection = SelectStageScene.SWIPE_NONE;
    if (Input.touchCount > 0) {
        Touch touch = Input.touches [0];
        switch (touch.phase) {
        case TouchPhase.Began:
            couldBeSwipe = true;
            startPos = touch.position;
            startTime = Time.time;
            break;
        case TouchPhase.Moved:
            if ((Mathf.Abs (touch.position.y - startPos.y) > comfortZone) && (Mathf.Abs (touch.position.x - startPos.x) > comfortZone)) {
                couldBeSwipe = false;
            }
            break;
        case TouchPhase.Ended:
            float swipeTime = Time.time - startTime;
            float swipeDistance = (touch.position - startPos).magnitude;
            float deltaX = touch.position.x - startPos.x;
            float deltaY = touch.position.y - startPos.y;

            if (couldBeSwipe && (swipeTime < maxSwipeTime) && (swipeDistance > minSwipeDistance)) { 
                if (Mathf.Abs (deltaX) > comfortZone) {
                    float swipeDirectionY = Mathf.Sign(deltaX);
                    if (swipeDirectionY == 1) {
                        swipeDirection = SelectStageScene.SWIPE_RIGHT;
                    } else {
                        swipeDirection = SelectStageScene.SWIPE_LEFT;
                    }
                }
                if (Mathf.Abs (deltaY) > comfortZone) {
                      float swipeDirectionY = Mathf.Sign(deltaY);
                      if (swipeDirectionY == 1) {
                            swipeDirection = SelectStageScene.SWIPE_UP;
                  } else {
                            swipeDirection = SelectStageScene.SWIPE_DOWN;
                  }
                }
            } else if (swipeTime > maxSwipeTime) {
                Debug.Log ("Too slow");
                swipeDirection = SelectStageScene.SWIPE_NONE;
            } else if (swipeDistance < minSwipeDistance) {
                Debug.Log ("Too short");
                swipeDirection = SelectStageScene.SWIPE_NONE;
            } else if (!couldBeSwipe) {
                Debug.Log ("Not a swipe");
                swipeDirection = SelectStageScene.SWIPE_NONE;
            } else {
                swipeDirection = SelectStageScene.SWIPE_NONE;
            }
            break;
        }
    }

第 2 部分 - 移动纹理(带有轴约束)

移动纹理的方法有多种,包括 GUI.DragWindow() , GUI.Box()等等。但没有一个直接移动 Texture 。这是沿轴移动纹理的最简单方法。例如,限制其运动仅在X轴上?

最佳答案

关于使用 Unity GUI,每次在 OnGUI() {} 内调用 GUI 元素时,您不会不断重绘或发送重绘消息,例如GUI.按钮

如果您想使用 OnGUI,我将按如下方式构造运动;

我已经塑造了你的函数并编写了这个类;

using UnityEngine;
using System.Collections;

public class SelectStageScene : MonoBehaviour {

    // You'll want to set this;
    public Texture2D        screenTexture;

    private float           minSwipeDistance        = 14;
    private float           maxSwipeTime            = 10;
    private float           startTime;

    private Vector2         startPos;
    private Vector2         currentPos;

    const int               SWIPE_NONE              = 0;
    const int               SWIPE_UP                = 1;
    const int               SWIPE_RIGHT             = 2;
    const int               SWIPE_DOWN              = 3;
    const int               SWIPE_LEFT              = 4;
    private int             swipeDirection          = SelectStageScene.SWIPE_NONE;

    private Vector2         screenTextureOffset     = Vector2.zero;
    private float           fadeAlpha               = 0f;
    private float           fadeSpeed               = 1f; // How fast the texture fades after swipe.

    public void Update() {
        // If no swipe direction is set.
        if ( swipeDirection == SelectStageScene.SWIPE_NONE ) {
            // To fade back in after swipe (just to complete the loop)
            if ( fadeAlpha > 0 ) {
                fadeAlpha -= Time.deltaTime * fadeSpeed;
            }
            // Getting input
            if ( Input.touchCount > 0 ) {
                Touch touch = Input.touches [0];
                switch ( touch.phase ) {
                case TouchPhase.Began:
                    startPos = touch.position;
                    startTime = Time.time;
                    break;
                case TouchPhase.Moved:
                    currentPos = touch.position;
                    break;
                case TouchPhase.Ended:
                    screenTextureOffset = currentPos - startPos;

                    // By using swipe distance as a magnitude here, regardless of x or y axis, we'll be choosing a swipe direction.
                    // If we were only interested in X axis we would use screenTextureOffset.x instead of swipeDistance
                    if ( Time.time - startTime < maxSwipeTime && ( currentPos - startPos ).magnitude > minSwipeDistance ) {
                        // Find if we've moved more on the x-axis or y-axis.
                        if ( Mathf.Abs( screenTextureOffset.x ) > Mathf.Abs( screenTextureOffset.y ) ) {
                            // x-axis
                            if ( screenTextureOffset.x > 0 ) {
                                swipeDirection = SelectStageScene.SWIPE_RIGHT;
                            } else {
                                swipeDirection = SelectStageScene.SWIPE_LEFT;
                            }
                        } else {
                            // y-axis
                            if ( screenTextureOffset.y > 0 ) {
                                swipeDirection = SelectStageScene.SWIPE_UP;
                            } else {
                                swipeDirection = SelectStageScene.SWIPE_DOWN;
                            }
                        }
                    } else {
                        swipeDirection = SelectStageScene.SWIPE_NONE;
                    }
                    break;
                }
            } else {
                screenTextureOffset *= 1 - Time.deltaTime * fadeSpeed;
            }
        } else {
            // This fades the texture and moves it further in direction of swipe.
            screenTextureOffset *= 1 + Time.deltaTime * fadeSpeed;
            fadeAlpha += Time.deltaTime * fadeSpeed;
            if ( fadeAlpha > 1 ) {
                swipeDirection = SelectStageScene.SWIPE_NONE;
                Debug.Log( "Finished swipe movement : " + swipeDirection );
            }
        }
    }

    public void OnGUI() {
        GUI.color = Color.white - Color.black * fadeAlpha;
        GUI.DrawTexture( new Rect( screenTextureOffset.x, screenTextureOffset.y, Screen.width, Screen.height ), screenTexture );
        /*// Specific axis. Constraining visually leaves easy potential access later on.
        if ( Mathf.Abs( screenTextureOffset.x ) > Mathf.Abs( screenTextureOffset.y ) ) {
            // x-axis
            GUI.DrawTexture( new Rect( screenTextureOffset.x, 0, Screen.width, Screen.height ), screenTexture );
        } else {
            // y-axis
            GUI.DrawTexture( new Rect( 0, screenTextureOffset.y, Screen.width, Screen.height ), screenTexture );
        }
        */
    }

}

关于c# - 在Unity 3D中模拟 "Swipe to Unlock",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26458590/

相关文章:

unity-game-engine - 将 Unity RenderTexture 流式传输到 Gstreamer

c# - 统一四元数,保持 x 和 z 旋转不变

c# - 如何从 IEnumerable 获取模型元数据?

c# - 有人可以解释一下 C# 中的 "passing by value"和 "Passing by reference"是什么意思吗?

c# - Unity 2D 中翻转 Sprite 的问题

unity-game-engine - Unity中的大场景场景,远大于一个Terrain?

c# - eShopOnWeb 项目中的聚合是什么意思?

c# - 将 GeoJson 特征映射到属性

c# - 如何根据名称获取属性值

android - Unity 2018 或 2019 减小 APK 或 .ipa 文件的大小