unity实现一个2d的咪牌的效果

1 效果图

unity实现一个2d的咪牌的效果_第1张图片

2 主要代码

/*
 *anyuanlzh 2019-06-25
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Demo : MonoBehaviour {
    public XEventTriggerListener xListener;
    public RectTransform mask;
    public RectTransform down;
    public RectTransform up;

    Vector2 maskSize = Vector2.zero;
    Vector2 paiSize = Vector2.zero;
    float maskWidth;
    float maskObliqueLen, paiObliqueLen;//对角线的长度

    bool hasBeginDrag = false;
    bool isBackPlaying = false;

    // Use this for initialization
    void Start () {
        maskSize = mask.sizeDelta;
        paiSize = down.sizeDelta;
        maskWidth = maskSize.x;
        maskObliqueLen = Vector2.Distance(Vector2.zero, maskSize);
        paiObliqueLen = Vector2.Distance(Vector2.zero, paiSize);
        //Debug.LogErrorFormat("maskSize:{0} paiSize:{1}", maskSize, paiSize);
        xListener.onBeginDragHandler.AddListener(onBeginDrag);
        xListener.onDragHandler.AddListener(onDrag);
        xListener.onEndDragHandler.AddListener(onEndDrag);
    }

    private void onBeginDrag(PointerEventData evenData)
    {
        //Calc(evenData.pressPosition, evenData.position);
        if(isBackPlaying==false)
        {
            hasBeginDrag = true;
        }
    }

    private void onDrag(PointerEventData evenData)
    {
        if (hasBeginDrag)
        {
            Calc(evenData.pressPosition, evenData.position);
        }
    }

    private void onEndDrag(PointerEventData evenData)
    {
        if (hasBeginDrag)
        {
            Calc(evenData.pressPosition, evenData.position);
        }
        hasBeginDrag = false;
        Vector2 pressPosition = evenData.pressPosition;
        Vector2 position = evenData.position;
        position = AdjustDrag(pressPosition,position);
        StartCoroutine(BackPlaying(pressPosition, position));
    }

    IEnumerator BackPlaying(Vector2 pressPosition, Vector2 position)
    {
        Vector2 move = position - pressPosition;
        float moveDis = Vector2.Distance(Vector2.zero, move) * 0.5f;
        if (moveDis < float.Epsilon)
        {
            Calc(pressPosition, position);
            yield break;
        }
        isBackPlaying = true;
        float speed = 100f;
        float countTime = moveDis / speed;
        float curTime = 0;
        while (true)
        {
            yield return 0;
            curTime += Time.deltaTime;
            if (curTime > countTime) curTime = countTime;
            Vector2 newPos = Vector2.Lerp(pressPosition, position, 1 - curTime / countTime);
            Calc(pressPosition, newPos);
            if (curTime >= countTime)
            {
                isBackPlaying = false;
                break;
            }
        }
        isBackPlaying = false;
    }


    //public Vector2 test_dir = new Vector2(10, 10);
    //Vector2 old_test_dir = Vector2.zero;
    //void Update()
    //{
    //    if (old_test_dir != test_dir)
    //    {
    //        old_test_dir = test_dir;
    //        Calc(null);
    //    }
    //}
    void Calc(Vector2 pressPosition, Vector2 position)
    {
        position = AdjustDrag(pressPosition, position);


        Vector2 move = position - pressPosition;
        if (move == Vector2.zero) return;
        //if (move.x <= 0 && move.y <= 0) return;
        //Vector2 move = test_dir;
        Vector2 moveDir = move.normalized;
        float angle = Vector2.SignedAngle(new Vector2(1, 0), moveDir);
        //Debug.LogError(angle);
        if (angle < 0 || angle > 90)
        {
            return;
        }

        down.SetParent(transform, true);
        up.SetParent(transform, true);

        // 计算角度
        angle = 90 - angle;
        mask.localEulerAngles = new Vector3(0, 0, -angle);
        up.localEulerAngles = new Vector3(0, 0, -2*angle);
        float moveDis = Vector2.Distance(Vector2.zero, move)*0.5f;

        // 计算位置
        Vector2 dir = mask.TransformDirection(Vector2.up);
        dir.Normalize();
        float _tempAngle = Vector2.Angle(dir, paiSize);
        float _cosVal = Mathf.Cos(_tempAngle * Mathf.Deg2Rad);
        float _dis = 0.5f * paiObliqueLen * _cosVal;
        float initOffsetDis = maskWidth * 0.5f - _dis;

        Vector2 pos = dir * (initOffsetDis+moveDis);
        mask.localPosition = pos;
        //Debug.LogErrorFormat("move:{0},_tempAngle:{1}, _cosVal:{2}, _dis:{3}, moveDis:{4}",
        //    move, _tempAngle, _cosVal, _dis, moveDis);

        float up_offsetDis = 2 * (_dis-moveDis);
        Vector2 up_pos = -dir * up_offsetDis;
        up.localPosition = up_pos;


        down.SetParent(mask, true);
        up.SetParent(mask, true);
    }

    Vector2 AdjustDrag(Vector2 pressPosition, Vector2 position)
    {
        Vector2 move = position - pressPosition;
        //Vector2 moveDir = move.normalized;
        if (move.x < 0)
        {
            move.x = 0;
        }
        if (move.y < 0)
        {
            move.y = 0;
        }
        float moveDis = Vector2.Distance(Vector2.zero, move);
        float maxOffsetDis = paiObliqueLen * 1f;
        if (moveDis > maxOffsetDis)
        {
            moveDis = maxOffsetDis;
            move = move.normalized * moveDis;
        }
        return pressPosition + move;
    }
}

3、demo

下载链接

你可能感兴趣的:(Unity3D)