【问题标题】:Touch to Zoom And Rotate script for Unity player触摸以缩放和旋转 Unity 播放器的脚本
【发布时间】:2020-02-03 02:54:04
【问题描述】:

我在 android studio 活动中嵌入了这个统一播放器。
这是一个带有动画的 3d 模型,我希望查看器能够缩放并以不同的角度查看。

脚本来自这个link

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

public class MobilemaxCamera : MonoBehaviour {

public Transform target;
public Vector3 targetOffset;
public float distance = 5.0f;
public float maxDistance = 20;
public float minDistance = .6f;
public float xSpeed = 5.0f;
public float ySpeed = 5.0f;
public int yMinLimit = -80;
public int yMaxLimit = 80;
public float zoomRate = 10.0f;
public float panSpeed = 0.3f;
public float zoomDampening = 5.0f;

private float xDeg = 0.0f;
private float yDeg = 0.0f;
private float currentDistance;
private float desiredDistance;
private Quaternion currentRotation;
private Quaternion desiredRotation;
private Quaternion rotation;
private Vector3 position;

private Vector3 FirstPosition;
private Vector3 SecondPosition;
private Vector3 delta;
private Vector3 lastOffset;
private Vector3 lastOffsettemp;
//private Vector3 CameraPosition;
//private Vector3 Targetposition;
//private Vector3 MoveDistance;


void Start() { Init(); }
void OnEnable() { Init(); }

public void Init()
{
    //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
    if (!target)
    {
        GameObject go = new GameObject("Cam Target");
        go.transform.position = transform.position + (transform.forward * distance);
        target = go.transform;
    }

    distance = Vector3.Distance(transform.position, target.position);
    currentDistance = distance;
    desiredDistance = distance;

    //be sure to grab the current rotations as starting points.
    position = transform.position;
    rotation = transform.rotation;
    currentRotation = transform.rotation;
    desiredRotation = transform.rotation;

    xDeg = Vector3.Angle(Vector3.right, transform.right);
    yDeg = Vector3.Angle(Vector3.up, transform.up);
}

/*
  * Camera logic on LateUpdate to only update after all character movement logic has been handled.
  */
void LateUpdate()
{
    // If Control and Alt and Middle button? ZOOM!
    if (Input.touchCount==2)
    {
        Touch touchZero = Input.GetTouch (0);

        Touch touchOne = Input.GetTouch (1);



        Vector2 touchZeroPreviousPosition = touchZero.position - touchZero.deltaPosition;

        Vector2 touchOnePreviousPosition = touchOne.position - touchOne.deltaPosition;



        float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;

        float TouchDeltaMag = (touchZero.position - touchOne.position).magnitude;



        float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;

        desiredDistance += deltaMagDiff * Time.deltaTime * zoomRate * 0.0025f * Mathf.Abs(desiredDistance);
    }
    // If middle mouse and left alt are selected? ORBIT
    if (Input.touchCount==1 && Input.GetTouch(0).phase == TouchPhase.Moved)
    {
        Vector2 touchposition = Input.GetTouch(0).deltaPosition;
        xDeg += touchposition.x * xSpeed * 0.002f;
        yDeg -= touchposition.y * ySpeed * 0.002f;
        yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);

    }
    desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
    currentRotation = transform.rotation;
    rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
    transform.rotation = rotation;


    if (Input.GetMouseButtonDown (1))
    {
        FirstPosition = Input.mousePosition;
        lastOffset = targetOffset;
    }

    if (Input.GetMouseButton (1))
    {
        SecondPosition = Input.mousePosition;
        delta = SecondPosition - FirstPosition;
        targetOffset = lastOffset + transform.right * delta.x*0.003f + transform.up * delta.y*0.003f;

    }

    ////////Orbit Position

    // affect the desired Zoom distance if we roll the scrollwheel
    desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);

    position = target.position - (rotation * Vector3.forward * currentDistance );

    position = position - targetOffset;

    transform.position = position;




}
private static float ClampAngle(float angle, float min, float max)
{
    if (angle < -360)
        angle += 360;
    if (angle > 360)
        angle -= 360;
    return Mathf.Clamp(angle, min, max);
}
}

放大和缩小效果完美。
但问题是,旋转/平移完全不起作用。
任何人都可以在这方面提供一些帮助吗?

【问题讨论】:

  • 你目前的结果是什么,请告诉我们,以便我们找出问题所在。

标签: c# android unity3d


【解决方案1】:

对于多点触控,你必须使用我在下面给出的这个脚本。

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

public class MultiTouch: MonoBehaviour
{
    float initialFingersDistance;
    Vector3 initialScale;
    float rotationRate = 0.2f;
    int direction = 1;
    void LateUpdate()
    {
        if (Input.touches.Length == 1)
        {
            if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
            {
                Touch touch = Input.touches[0];

                Quaternion desiredRotation = transform.rotation;

                TouchLogic.Calculate();

                if (Mathf.Abs(TouchLogic.turnAngleDelta) > 0)
                { // rotate
                   Vector3 rotationDeg = transform.eulerAngles;

                   rotationDeg.z = -TouchLogic.turnAngleDelta;
                   desiredRotation *= Quaternion.Euler(rotationDeg);
                }

               // not so sure those will work:
                  transform.rotation = desiredRotation;


               // transform.Rotate(touch.deltaPosition.y * rotationRate, -touch.deltaPosition.x * rotationRate, 0, Space.World);
                   Vector3 rot = new Vector3(touch.deltaPosition.y * rotationRate, -touch.deltaPosition.x * rotationRate, transform.eulerAngles.z* rotationRate);
                //  transform.rotation = Quaternion.EulerAngles(rot);

            }
        }

        else if (Input.touches.Length == 2)
        {
            Touch t1 = Input.touches[0];
            Touch t2 = Input.touches[1];

            if (t1.phase == TouchPhase.Began || t2.phase == TouchPhase.Began)
            {
                initialFingersDistance = Vector2.Distance(t1.position, t2.position);
                initialScale = gameObject.transform.localScale;
            }

            else if (t1.phase == TouchPhase.Moved || t2.phase == TouchPhase.Moved)
            {
                var currentFingersDistance = Vector2.Distance(t1.position, t2.position);
                //   Debug.Log(currentFingersDistance);
                ////if (currentFingersDistance != initialFingersDistance) 
                //{
                var scaleFactor = currentFingersDistance / initialFingersDistance;
                gameObject.transform.localScale = initialScale * scaleFactor;
                //} 

                float Dx = t1.position.x - transform.position.x;
                float Dy = t1.position.y - transform.position.y;

   
                //var cameraTransform = Camera.main.transform.InverseTransformPoint(0, 0, 0);
                //transform.position = Camera.main.ScreenToWorldPoint(new Vector3(t2.position.x, t2.position.y, cameraTransform.z -0.5f));

   
                Vector3 pos = t2.position;

                //Vector3 pos = t1.position - t2.position;
                Vector3 touchedPos = Camera.main.ScreenToWorldPoint(new Vector3(pos.x, pos.y, 10));
                   transform.position = Vector3.Lerp(transform.position, touchedPos, Time.deltaTime * 4);
             //   transform.position += touchedPos;

                float pinchAmount = 0;
                Quaternion desiredRotation = transform.rotation;

                TouchLogic.Calculate();

                if (Mathf.Abs(TouchLogic.pinchDistanceDelta) > 0)
                { // zoom
                    pinchAmount = TouchLogic.pinchDistanceDelta;
                }

                if (Mathf.Abs(TouchLogic.turnAngleDelta) > 0)
                { // rotate
                    Vector3 rotationDeg = Vector3.zero;
                    rotationDeg.z = -TouchLogic.turnAngleDelta;
                    desiredRotation *= Quaternion.Euler(rotationDeg);
                }

                // not so sure those will work:
                transform.rotation = desiredRotation;
                transform.position += Vector3.forward * pinchAmount;
            }
        }
    }
}

对于您的触摸控制逻辑,您必须使用我在下面给出的第二个脚本。

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

public class TouchLogic: MonoBehaviour
{
    const float pinchTurnRatio = Mathf.PI / 2;
    const float minTurnAngle = 0;

    const float pinchRatio = 1;
    const float minPinchDistance = 0;

    const float panRatio = 1;
    const float minPanDistance = 0;

    /// <summary>
    ///   The delta of the angle between two touch points
    /// </summary>
    static public float turnAngleDelta;
    /// <summary>
    ///   The angle between two touch points
    /// </summary>
    static public float turnAngle;

    /// <summary>
    ///   The delta of the distance between two touch points that were distancing from each other
    /// </summary>
    static public float pinchDistanceDelta;
    /// <summary>
    ///   The distance between two touch points that were distancing from each other
    /// </summary>
    static public float pinchDistance;

    /// <summary>
    ///   Calculates Pinch and Turn - This should be used inside LateUpdate
    /// </summary>
    /// 
    static public Touch LastTouch;
    static public void Calculate()
    {
        pinchDistance = pinchDistanceDelta = 0;
        turnAngle = turnAngleDelta = 0;

        // if two fingers are touching the screen at the same time ...

       
        if (Input.touchCount == 1)
        {
           
            Touch touch1 = Input.touches[0];
        
            turnAngle = Angle(touch1.position, LastTouch.position);
            float prevTurn = Angle(touch1.position + touch1.deltaPosition,
                                   LastTouch.deltaPosition + LastTouch.position);
            turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle);

            // ... if it's greater than a minimum threshold, it's a turn!
            if (Mathf.Abs(turnAngleDelta) > minTurnAngle)
            {
                turnAngleDelta *= pinchTurnRatio;
            }
            else
            {
                turnAngle = turnAngleDelta = 0;
            }
            LastTouch =Input.touches[0];
        }

        else if (Input.touchCount == 2)
        {
            Touch touch1 = Input.touches[0];
            Touch touch2 = Input.touches[1];

            // ... if at least one of them moved ...
            if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved)
            {
                // ... check the delta distance between them ...
                pinchDistance = Vector2.Distance(touch1.position, touch2.position);
                float prevDistance = Vector2.Distance(touch1.position - touch1.deltaPosition,
                                                     touch2.position - touch2.deltaPosition);
                pinchDistanceDelta = pinchDistance - prevDistance;

                // ... if it's greater than a minimum threshold, it's a pinch!
                if (Mathf.Abs(pinchDistanceDelta) > minPinchDistance)
                {
                   pinchDistanceDelta *= pinchRatio;
                }
                else
                {
                   pinchDistance = pinchDistanceDelta = 0;
                }

                // ... or check the delta angle between them ...
                turnAngle = Angle(touch1.position, touch2.position);
                float prevTurn = Angle(touch1.position + touch1.deltaPosition,
                                       touch2.position + touch2.deltaPosition);
                turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle);

                // ... if it's greater than a minimum threshold, it's a turn!
                if (Mathf.Abs(turnAngleDelta) > minTurnAngle)
                {
                    turnAngleDelta *= pinchTurnRatio;
                }
                else
                {
                    turnAngle = turnAngleDelta = 0;
                }
            }
        }
    }


    static private float Angle(Vector2 pos1, Vector2 pos2)
    {
        Vector2 from = pos2 - pos1;
        Vector2 to = new Vector2(1, 0);

        float result = Vector2.Angle(from, to);
        Vector3 cross = Vector3.Cross(from, to);

        if (cross.z > 0)
        {
            result = 360f - result;
        }

        return result;
    }
}

两个脚本都在一个项目中使用。使用这些脚本,您可以轻松地旋转 3d 对象。

注意:请将这两个脚本附加到一个 3d 对象中,以便您可以轻松使用此脚本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    相关资源
    最近更新 更多