Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Unity 5用户界面进行收缩缩放_C#_User Interface_Unity3d_Unity5_Pinchzoom - Fatal编程技术网

C# 使用Unity 5用户界面进行收缩缩放

C# 使用Unity 5用户界面进行收缩缩放,c#,user-interface,unity3d,unity5,pinchzoom,C#,User Interface,Unity3d,Unity5,Pinchzoom,我正在尝试在一个基于Unity UI的应用程序中重新实现一个从收缩到缩放的系统。大约六个月前,我通过将UI画布制作成常规游戏对象的子对象,并操纵该对象的变换,将其组合在一起,但自从更新到Unity 5.5+后,我发现这不起作用。我能得到的最近距离允许收缩手势更改画布的缩放因子,这a)会使图像、面板等根据其对齐方式不正确地调整大小,b)缩放后不允许平移 到目前为止,我得到的是: public class PinchToZoomScaler : MonoBehaviour { public

我正在尝试在一个基于Unity UI的应用程序中重新实现一个从收缩到缩放的系统。大约六个月前,我通过将UI画布制作成常规游戏对象的子对象,并操纵该对象的变换,将其组合在一起,但自从更新到Unity 5.5+后,我发现这不起作用。我能得到的最近距离允许收缩手势更改画布的缩放因子,这a)会使图像、面板等根据其对齐方式不正确地调整大小,b)缩放后不允许平移

到目前为止,我得到的是:

public class PinchToZoomScaler : MonoBehaviour {

    public Canvas canvas; // The canvas
    public float zoomSpeed = 0.5f;        // The rate of change of the canvas scale factor

    public float _resetDuration = 3.0f;
    float _durationTimer = 0.0f;

    float _startScale = 0.0f;

    void Start() {
        _startScale = canvas.scaleFactor;
    }

    void Update()
    {
            // If there are two touches on the device...
            if (Input.touchCount == 2) {
                // Store both touches.
                Touch touchZero = Input.GetTouch (0);
                Touch touchOne = Input.GetTouch (1);

                // Find the position in the previous frame of each touch.
                Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
                Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

                // Find the magnitude of the vector (the distance) between the touches in each frame.
                float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
                float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

                // Find the difference in the distances between each frame.
                float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

                // ... change the canvas size based on the change in distance between the touches.
                canvas.scaleFactor -= deltaMagnitudeDiff * zoomSpeed;

                // Make sure the canvas size never drops below 0.1
                canvas.scaleFactor = Mathf.Max (canvas.scaleFactor, _startScale);
                canvas.scaleFactor = Mathf.Min (canvas.scaleFactor, _startScale * 3.0f);

                _durationTimer = 0.0f;
            } else {
                _durationTimer += Time.deltaTime;

                if (_durationTimer >= _resetDuration) {
                    canvas.scaleFactor = _startScale;
                }
            }
    }
}
正如我所说,这在一定程度上是可行的,但它并没有给我一个很好的统一缩放,也不允许我平移画布。提前感谢您的帮助。

您可以使用此函数(只需将负deltaMagnitudeDiff传递给它即可) 同样,以类似(0.05)的比率对deltaMagnitudeDiff进行多次叠加也是很好的

float currentScale=1f;
空心缩放(浮动增量)
{
电流标度+=增量;
如果(currentScale>=maxScale)
{
currentScale=maxScale;
}
else if(当前刻度最大值+偏移量)
温度x=最大值x+偏移量x;
如果(温度y<-最大值+偏移量)
温度y=-MaxY+offsetY;
否则如果(温度y>MaxY+offsetY)
温度y=最大值+偏移量;
transform.localPosition=temp;
}

只需从事件触发器组件调用函数(BeginDrag&Drag)

>我用捏法缩放物体的方法是,当物体在屏幕中央时,它在任何触摸屏上工作:

if(Input.touchCount==2)
{
//检查两次触摸之间的距离,然后使用该距离缩放
//通过将两个手指进一步移动或彼此靠近来移动对象。
Touch touch0=Input.GetTouch(0);
Touch Touch 1=输入。GetTouch(1);
if(isScaling)//仅当scaling为true时才会执行此操作
{
float currentTouchDistance=getTouchDistance();
浮点deltaTouchDistance=当前触摸距离-触摸距离原点;
浮点数百分比=(deltaTouchDistance/1200f)+1f;
Vector3 scaleTemp=transform.localScale;
scaleTemp.x=比例百分比*原始比例.x;
scaleTemp.y=比例百分比*原始比例.y;
scaleTemp.z=比例百分比*原始比例.z;
//要使对象捕捉到100%,正在进行检查,以查看对象比例是否接近100%,
//如果是,则比例将恢复为100%,以便捕捉到正常比例。
//这是一种生活质量特征,因此很容易获得对象的原始大小。
如果(scaleTemp.x*100<102&&scaleTemp.x*100>98)
{
scaleTemp.x=1;
scaleTemp.y=1;
scaleTemp.z=1;
}
//在这里,我们应用上面所做的计算来实际使对象变大/变小。
transform.localScale=scaleTemp;
}
其他的
{
//如果两个手指触摸屏幕,但isScaling不正确,我们将查看
//屏幕中央正在查看对象,如果将isScalinf设置为true;
射线;
雷卡斯特·希特鲁克;
光线=cam.ViewportPointToRay(新矢量3(0.5f,0.5f,0));
if(物理.光线投射(光线,外触,100f))
{
if(hitTouch.transform==transform)
{
isScaling=true;
//确保初始接触时手指之间的距离用作原始距离
touchDistanceOrigin=getTouchDistance();
originalScale=transform.localScale;
}
}
}
}

将此脚本附加到画布对象中,以便通过挤压放大和缩小该对象

using UnityEngine;
using UnityEngine.EventSystems;

public class ObjectScalling : MonoBehaviour, IPointerDownHandler, IPointerUpHandler 
{
    private bool _isDragging;
    private float _currentScale;
    public float minScale, maxScale;
    private float _temp = 0;
    private float _scalingRate = 2;

    private void Start() 
    {
        _currentScale = transform.localScale.x;
    }

    public void OnPointerDown(PointerEventData eventData) 
    {
        if (Input.touchCount == 1) 
        {
            _isDragging = true;
        }
    }


    public void OnPointerUp(PointerEventData eventData) 
    {
        _isDragging = false;
    }


    private void Update() 
    {
        if (_isDragging)
            if (Input.touchCount == 2) 
            {
                transform.localScale = new Vector2(_currentScale, _currentScale);
                float distance = Vector3.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
                if (_temp > distance) 
                {
                    if (_currentScale < minScale)
                        return;
                    _currentScale -= (Time.deltaTime) * _scalingRate;
                }

                else if (_temp < distance) 
                {
                    if (_currentScale > maxScale)
                        return;
                    _currentScale += (Time.deltaTime) * _scalingRate;
                }

                _temp = distance;
            }
    }
}
使用UnityEngine;
使用UnityEngine.EventSystems;
公共类ObjectScaling:MonoBehavior、IPInterDownHandler、IPInterUpHandler
{
私人厕所;
私人浮标;
公共浮点数,最大刻度;
专用浮点数_temp=0;
私有浮动_scalingRate=2;
私有void Start()
{
_currentScale=transform.localScale.x;
}
POINTERDOWN上的公共无效(PointerEventData事件数据)
{
如果(Input.touchCount==1)
{
_IsDraging=true;
}
}
POINTERUP上的公共无效(PointerEventData事件数据)
{
_IsDraging=错误;
}
私有void更新()
{
如果(_istragging)
如果(Input.touchCount==2)
{
transform.localScale=新向量2(\u currentScale,\u currentScale);
float distance=Vector3.距离(Input.GetTouch(0).位置,Input.GetTouch(1).位置);
如果(温度>距离)
{
如果(_currentScalemaxScale)
返回;
_currentScale+=(Time.deltaTime)*\u scalingRate;
}
_温度=距离;
}
}
}
提醒:此脚本仅适用于画布对象

public class Pan : MonoBehaviour
{
    public float Speed;

    Vector3 startDragPosition;

    public void BeginDrag ()
    {
        startDragPosition = Input.mousePosition;
    }

    public void Drag ()
    {
        transform.localPosition += (Input.mousePosition - startDragPosition) * Speed;
        startDragPosition = Input.mousePosition;

        ValidatePosition ();
    }

    public void ValidatePosition ()
    {
        var temp = transform.localPosition;

        var width = ((RectTransform)transform).sizeDelta.x;
        var height = ((RectTransform)transform).sizeDelta.y;

        var MaxX = 0.5f * width * Mathf.Max (0, transform.localScale.x - 1);
        var MaxY = 0.5f * height * Mathf.Max (0, transform.localScale.y - 1);

        var offsetX = transform.localScale.x * width * (((RectTransform)transform).pivot.x - 0.5f);
        var offsetY = transform.localScale.y * width * (((RectTransform)transform).pivot.y - 0.5f);

        if (temp.x < -MaxX + offsetX)
            temp.x = -MaxX + offsetX;
        else if (temp.x > MaxX + offsetX)
            temp.x = MaxX + offsetX;

        if (temp.y < -MaxY + offsetY)
            temp.y = -MaxY + offsetY;
        else if (temp.y > MaxY + offsetY)
            temp.y = MaxY + offsetY;

        transform.localPosition = temp;
}
using UnityEngine;
using UnityEngine.EventSystems;

public class ObjectScalling : MonoBehaviour, IPointerDownHandler, IPointerUpHandler 
{
    private bool _isDragging;
    private float _currentScale;
    public float minScale, maxScale;
    private float _temp = 0;
    private float _scalingRate = 2;

    private void Start() 
    {
        _currentScale = transform.localScale.x;
    }

    public void OnPointerDown(PointerEventData eventData) 
    {
        if (Input.touchCount == 1) 
        {
            _isDragging = true;
        }
    }


    public void OnPointerUp(PointerEventData eventData) 
    {
        _isDragging = false;
    }


    private void Update() 
    {
        if (_isDragging)
            if (Input.touchCount == 2) 
            {
                transform.localScale = new Vector2(_currentScale, _currentScale);
                float distance = Vector3.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
                if (_temp > distance) 
                {
                    if (_currentScale < minScale)
                        return;
                    _currentScale -= (Time.deltaTime) * _scalingRate;
                }

                else if (_temp < distance) 
                {
                    if (_currentScale > maxScale)
                        return;
                    _currentScale += (Time.deltaTime) * _scalingRate;
                }

                _temp = distance;
            }
    }
}