Unity3d手机端俄罗斯方块滑动条操作


文章目录

  • Unity3d手机端俄罗斯方块滑动条操作
  • 前言
  • 一、玩法介绍
  • 二、下落物体
  • 1.下落预制体
  • 2.脚本代码
  • 三、滑动条
  • 1.滑动条属性
  • 2.脚本代码
  • 总结



前言

为了实现单手就可以进行操作移动、加速、旋转,舍弃了第一次的区域划分后使用滑动和点击进行操作的第一版操作方式;改进成使用滑动条控制加速和旋转,左右移动仍是点击屏幕两侧。


一、玩法介绍

1.左右的移动仍然还是通过点击屏幕两侧实现,与第一次相比较的区别在于,从屏幕的三分之一的点击操作范围扩大为了屏幕的二分之一。

2.滑动条的使用方式如图所示:向上滑动进行旋转;向下滑动则会加速,滑动的位置越靠下,加速值越高。

u3d 手游 android u3d手机版_游戏开发


u3d 手游 android u3d手机版_u3d 手游 android_02

二、下落物体

1.下落预制体

一共有七个预制体。

u3d 手游 android u3d手机版_ios_03


这些预制体上都挂载着shape脚本,用于控制自身的移动。

u3d 手游 android u3d手机版_android_04


1.每一个block代表一个方块。

2.Pivot是整个图形的旋转中心点。

2.脚本代码

代码如下(示例):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Shape : MonoBehaviour
{
    public static Shape Instence;

    /// <summary>
    /// 计时器
    /// </summary>
    private float timer = 0;
    /// <summary>
    /// 下落一格需要的时间
    /// </summary>
    private float stepTime = 0.8f;
    /// <summary>
    /// 图形的中心点
    /// </summary>
    private Transform pivot;
    /// <summary>
    /// 下落倍数
    /// </summary>
    private int multiple = 30;

    private void Awake()
    {
        Instence = this;
        pivot = transform.Find("Pivot");
    }

    private void Update()
    {
        //控制掉落
        timer += Time.deltaTime;
        if(timer > stepTime)
        {
            timer = 0;
            Fall();
        }
        //控制移动
        AndroidMoveControl_2();
    }

    public void Init(Color color)
    {
        //遍历所有子物体
        foreach(Transform t in transform)
        {
            if(t.tag == "Block")
            {
                t.GetComponent<SpriteRenderer>().color = color;
            }
        }
    }

    /// <summary>
    /// 下落
    /// </summary>
    private void Fall()
    {
        Vector3 pos = transform.position;
        pos.y -= 1;
        transform.position = pos;
    }

    /// <summary>
    /// 手机版移动控制_2
    /// </summary>
    public void AndroidMoveControl_2()
    {
        float h = 0;

        if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)) //判断有没有碰到UI
        {
            if (Application.platform == RuntimePlatform.Android) //如果当前平台是安卓
            {
                if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
                {
                    return;
                }
            }
            else //其他平台
            {
                if (EventSystem.current.IsPointerOverGameObject())
                {
                    return;
                }
            }
            Vector3 clickPos = Input.mousePosition;
            slideInitialPos = clickPos; //将初始位置置为点击的位置
            if (clickPos.x <= Screen.width / 2 && clickPos.y <= Screen.height - 410)  //点击左侧屏幕
            {
                h = -1;
            }
            if (clickPos.x >= Screen.width / 2 && clickPos.y <= Screen.height - 410)  //点击右侧屏幕
            {
                h = 1;
            }
            if (h != 0)
            {
                Vector3 pos = transform.position;
                pos.x += h;
                transform.position = pos;
                return; //控制图形左右移动时,不能进行其他操作
            }
        }
        
    }

    /// <summary>
    /// 下落加速
    /// </summary>
    public void SpeedUp(float FallingMultiple)
    {
        if(FallingMultiple >= 0.6f)
        {
            FallingMultiple = 0.6f;
        }
        stepTime = 0.8f / ((FallingMultiple - 0.3f) * 100);
    }

    /// <summary>
    /// 重置速度
    /// </summary>
    public void SpeedReset()
    {
        stepTime = 0.8f;
    }

    /// <summary>
    /// 旋转
    /// </summary>
    public void ShapeRotate()
    {
        if (isRotate)
        {
            //进行旋转
            transform.RotateAround(pivot.position, Vector3.forward, -90);
            isRotate = false;
        }
    }

    /// <summary>
    /// 重置旋转状态
    /// </summary>
    public void RotateReset()
    {
        isRotate = true;
    }
}

一些小的细节提醒:

Init函数中的代码主要目的是为了获取已经设置好的几种颜色,在生成的时候颜色随机。

三、滑动条

1.滑动条属性

1.在滑动控制UI上挂载脚本SlideControlManager,用来管理以及控制左右两个滑动条。

u3d 手游 android u3d手机版_ios_05


2.以右滑动条为例进行介绍:

(1)Direction属性为从上到下,Value初始值设置为0.3.

(2)有一个OnValueChanged(在脚本中添加)。

(3)使用EventTrigger添加一个PointerUp事件,用于处理玩家松开滚动条按钮之后,按钮归位的事情。

u3d 手游 android u3d手机版_游戏开发_06

2.脚本代码

代码如下(示例):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SlideControlManager : MonoBehaviour
{
    /// <summary>
    /// 左滚动条
    /// </summary>
    private Scrollbar leftScrollbar;
    /// <summary>
    /// 右滚动条
    /// </summary>
    private Scrollbar rightScrollbar;
    
    /// <summary>
    /// 左侧滚动条是否处于加速区间
    /// </summary>
    private bool isLeftScrollbarSpeedUp;
    /// <summary>
    /// 右侧滚动条是否处于加速区间
    /// </summary>
    private bool isRightScrollbarSpeedUp;

    private void Awake()
    {
        leftScrollbar = transform.Find("LeftScrollbar").GetComponent<Scrollbar>();
        leftScrollbar.onValueChanged.AddListener(OnLeftScrollbarValueChange); //为左滚动条添加事件
        rightScrollbar = transform.Find("RightScrollbar").GetComponent<Scrollbar>();
        rightScrollbar.onValueChanged.AddListener(OnRightScrollbarValueChange); //为右滚动条添加事件
    }

    /// <summary>
    /// 左滚动条的值发生改变
    /// </summary>
    /// <param name="a"></param>
    private void OnLeftScrollbarValueChange(float a)
    {
        if (leftScrollbar.value == 0.3f)
        {
            isLeftScrollbarSpeedUp = false;
            Shape.Instence.SpeedReset(); //重置速度
            Shape.Instence.RotateReset(); //重置旋转状态
            return;
        }
        else if (leftScrollbar.value < 0.3f)
        {
            //旋转图形
            Shape.Instence.ShapeRotate();
            //Debug.Log("旋转");
        }
        else if (leftScrollbar.value > 0.3f)
        {
            isLeftScrollbarSpeedUp = true;
            //根据value进行加速
            SpeedUp();
            //Debug.Log("加速");
        }
    }

    /// <summary>
    /// 右滚动条的值发生改变
    /// </summary>
    /// <param name="a"></param>
    private void OnRightScrollbarValueChange(float a)
    {
        if(rightScrollbar.value == 0.3f)
        {
            isRightScrollbarSpeedUp = false;
            Shape.Instence.SpeedReset();
            Shape.Instence.RotateReset();
            return;
        }
        else if(rightScrollbar.value < 0.3f)
        {
            //旋转图形
            Shape.Instence.ShapeRotate();
            //Debug.Log("旋转");
        }
        else if(rightScrollbar.value > 0.3f)
        {
            isRightScrollbarSpeedUp = true;
            //根据value进行加速
            SpeedUp();
            //Debug.Log("加速");
        }
    }

    /// <summary>
    /// 加速
    /// </summary>
    private void SpeedUp()
    {
        if(isLeftScrollbarSpeedUp && isRightScrollbarSpeedUp == false) //只有左侧发生滑动
        {
            rightScrollbar.value = 0.3f;
            Shape.Instence.SpeedUp(leftScrollbar.value);
        }
        else if(isLeftScrollbarSpeedUp == false && isRightScrollbarSpeedUp) //只有右侧发生滑动
        {
            leftScrollbar.value = 0.3f;
            Shape.Instence.SpeedUp(rightScrollbar.value);
        }
    }

    /// <summary>
    /// 左侧滚动条退出
    /// </summary>
    public void OnExitLeftScrollbarEvent()
    {
        StartCoroutine(ResetValue(leftScrollbar));
    }

    /// <summary>
    /// 右侧滚动条退出
    /// </summary>
    public void OnExitRightScrollbarEvent()
    {
        StartCoroutine(ResetValue(rightScrollbar));
    }

    private IEnumerator ResetValue(Scrollbar scrollbar)
    {
        yield return new WaitForSeconds(0.05f);
        scrollbar.value = 0.3f;
    }
}

总结

这种通过滑动条控制操作的方式,本人认为还是比较方便的,但仍存在不方便的地方,滑动条的按钮因为可以点哪到哪,所以容易出现误操作的状况,如拖动按钮时,按到了按钮的上方区域而导致物体旋转。
所以手机版俄罗斯方块的操作方式仍需要探索和修改。