Unity学习笔记009.触摸控制(PC&Android)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_33643757/article/details/86218511

1. AroundCameraMobile

using Developer.CameraExtension;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class AroundCameraMobile : MonoBehaviour
{
    #region Mono-Singleton

    private static AroundCameraMobile instance;
    public static AroundCameraMobile Instance
    {
        get
        {
            if (!instance)
                instance = FindObjectOfType<AroundCameraMobile>();
            return instance;
        }
    }

    #endregion

    #region Property and Field
    
    /// <summary>
    /// Around center.
    /// </summary>
    //public Transform target;
    private Transform target;
    private Vector2 savePreAngles;
    private bool isBegin;

    /// <summary>
    /// Settings of mouse button, pointer and scrollwheel.
    /// </summary>
    public MouseSettings touchSettings = new MouseSettings(1, 10, 10);

    /// <summary>
    /// Range limit of angle.
    /// </summary>
    public Range angleRange = new Range(-90, 90);

    /// <summary>
    /// Range limit of distance.
    /// </summary>
    public Range distanceRange = new Range(1, 10);

    /// <summary>
    /// Damper for move and rotate.
    /// </summary>
    [Range(0, 10)] public float damper = 5;

    /// <summary>
    /// Camera current angls.
    /// </summary>
    public Vector2 currentAngles { protected set; get; }

    /// <summary>
    /// Current distance from camera to target.
    /// </summary>
    public float currentDistance { protected set; get; }

    /// <summary>
    /// Camera target angls.
    /// </summary>
    protected Vector2 targetAngles;

    /// <summary>
    /// Target distance from camera to target.
    /// </summary>
    protected float targetDistance;

    /// <summary>
    /// Touch Events
    /// </summary>
    private enum TouchType
    {
        None,
        Move,
        Scale,
        Rotate
    }
    private TouchType touchType = TouchType.None;

    #endregion

    #region Protected Method

    protected virtual void Start()
    {
        target = new GameObject("selftarget").transform;
        target.SetParent(transform.root);
        currentAngles = targetAngles = transform.eulerAngles;
        savePreAngles = transform.eulerAngles;               
        currentDistance = targetDistance = Vector3.Distance(transform.position, target.position);
    }

    protected virtual void LateUpdate()
    {
        if (!isBegin)
            return;
        
#if UNITY_STANDALONE
        CheckMouseInput();
#endif

#if UNITY_ANDROID
        CheckTouchInput();
#endif
    }

    public void SetTarget(Transform tar)
    {
        if (!ReferenceEquals(tar, null))
        {
            target.position = tar.position;

            isBegin = true;
        }
    }

    public void SetDefault()
    {
        target.position = Vector3.zero;

        isBegin = false;

        transform.localPosition = Vector3.zero;
        transform.localRotation = Quaternion.identity;

        currentAngles = targetAngles = savePreAngles;
        currentDistance = targetDistance = 50;
    }

    protected void CheckMouseInput()
    {
        if (Input.GetMouseButton(0))
        {
            //Mouse pointer.
            targetAngles.y += Input.GetAxis("Mouse X") * touchSettings.pointerSensitivity * 50;
            targetAngles.x -= Input.GetAxis("Mouse Y") * touchSettings.pointerSensitivity * 50;

            //Range.
            targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
        }

        //拖动
        if (Input.GetMouseButton(2))
        {
            float xAxis = Input.GetAxis("Mouse X");
            float yAxis = Input.GetAxis("Mouse Y");

            target.localPosition -= transform.right.normalized * xAxis + transform.up.normalized * yAxis;
        }

        //Mouse scrollwheel.
        targetDistance -= Input.GetAxis("Mouse ScrollWheel") * touchSettings.wheelSensitivity;
        targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);

        //Lerp.
        currentAngles = Vector2.Lerp(currentAngles, targetAngles, damper * Time.deltaTime);
        currentDistance = Mathf.Lerp(currentDistance, targetDistance, damper * Time.deltaTime);

        //Update transform position and rotation.
        transform.rotation = Quaternion.Euler(currentAngles);
        transform.position = target.position - transform.forward * currentDistance;
    }
        
    /// <summary>
    /// Check and deal with mouse input. 
    /// </summary>
    protected void CheckTouchInput()
    {
        //单点触摸, 水平上下旋转
        if (Input.touchCount == 1)
        {
            Touch touch = Input.GetTouch(0);

            if (touch.phase == TouchPhase.Began)
                touchType = TouchType.Rotate;

            if (touchType == TouchType.Rotate)
            {
                Vector2 deltaPos = touch.deltaPosition;

                //Mouse pointer.
                targetAngles.y += deltaPos.x * touchSettings.pointerSensitivity;
                targetAngles.x -= deltaPos.y * touchSettings.pointerSensitivity;

                //Range.
                targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
            }            
        }

        // 双指触摸,拖放
        if (Input.touchCount == 2)
        {
            Touch touchZero = Input.GetTouch(0);
            Touch touchOne = Input.GetTouch(1);

            if (touchZero.phase == TouchPhase.Ended || touchOne.phase == TouchPhase.Ended)
            {
                touchType = TouchType.None;
                return;
            }

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

            var dir = Vector2.Dot(touchZero.deltaPosition, touchOne.deltaPosition);

            touchType = dir > 0 ? TouchType.Move : TouchType.Scale;

            if (touchType == TouchType.Move)
            {
                //target.localPosition += new Vector3(touchZero.deltaPosition.x, touchZero.deltaPosition.y, 0) * 0.02f;

                target.position -= (transform.right.normalized * touchZero.deltaPosition.x + transform.up.normalized * touchZero.deltaPosition.y) * 0.02f;

                return;
            }

            if (touchType == TouchType.Scale)
            {
                // 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;

                float scaleF = -deltaMagnitudeDiff / 1000f;

                //Mouse scrollwheel.
                targetDistance -= scaleF * touchSettings.wheelSensitivity;
                targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);
            }
        }
                

        //Lerp.
        currentAngles = Vector2.Lerp(currentAngles, targetAngles, damper * Time.deltaTime);
        currentDistance = Mathf.Lerp(currentDistance, targetDistance, damper * Time.deltaTime);

        //Update transform position and rotation.
        transform.rotation = Quaternion.Euler(currentAngles);
        transform.position = target.position - transform.forward * currentDistance;
    }

    #endregion
}

2. AroundCameraPC

using UnityEngine;

namespace Developer.CameraExtension
{
    [RequireComponent(typeof(Camera))]
    [AddComponentMenu("Developer/CameraExtension/AroundCamera")]
    public class AroundCameraPC : MonoBehaviour
    {
        #region Property and Field

        /// <summary>
        /// Settings of mouse button, pointer and scrollwheel.
        /// </summary>
        public MouseSettings mouseSettings = new MouseSettings(1, 10, 10);

        /// <summary>
        /// Range limit of angle.
        /// </summary>
        public Range angleRange = new Range(-90, 90);

        /// <summary>
        /// Range limit of distance.
        /// </summary>
        public Range distanceRange = new Range(1, 10);

        /// <summary>
        /// Damper for move and rotate.
        /// </summary>
        [Range(0, 10)]
        public float damper = 5;

        /// <summary>
        /// Camera current angls.
        /// </summary>
        public Vector2 currentAngles { protected set; get; }

        /// <summary>
        /// Current distance from camera to target.
        /// </summary>
        public float currentDistance { protected set; get; }

        /// <summary>
        /// Camera target angls.
        /// </summary>
        protected Vector2 targetAngles;

        /// <summary>
        /// Target distance from camera to target.
        /// </summary>
        protected float targetDistance;

        #endregion

        #region Mono-Singleton

        private static AroundCameraPC instance;
        public static AroundCameraPC Instance
        {
            get
            {
                if (!instance)
                    instance = FindObjectOfType<AroundCameraPC>();
                return instance;
            }
        }

        #endregion

        private Vector2 savePreAngles;

        private Transform selfTarget;

        private bool isBegin;

        #region Protected Method

        protected virtual void Start()
        {
            selfTarget = new GameObject("selftarget").transform;
            selfTarget.SetParent(transform.root);
            currentAngles = targetAngles = transform.eulerAngles;
            savePreAngles = transform.eulerAngles;
            currentDistance = targetDistance = Vector3.Distance(transform.position, selfTarget.position) + 50;
        }

        protected virtual void LateUpdate()
        {
            if (!isBegin)
                return;

            CheckMouseInput();
        }

        public void SetTarget(Transform tar)
        {
            if (!ReferenceEquals(tar, null))
            {
                selfTarget.position = tar.position;

                isBegin = true;
            }
        }

        public void SetDefault()
        {
            selfTarget.position = Vector3.zero;

            isBegin = false;

            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;

            currentAngles = targetAngles = savePreAngles;
            currentDistance = targetDistance = 50;
        }

        /// <summary>
        /// Check and deal with mouse input. 
        /// </summary>
        protected void CheckMouseInput()
        {
            if (Input.GetMouseButton(mouseSettings.mouseButtonID))
            {
                //Mouse pointer.
                targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity;
                targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity;

                //Range.
                targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
            }

            //拖动
            if (Input.GetMouseButton(2))
            {
                float xAxis = Input.GetAxis("Mouse X");
                float yAxis = Input.GetAxis("Mouse Y");

                selfTarget.localPosition -= transform.right.normalized * xAxis + transform.up.normalized * yAxis;
            }

            //Mouse scrollwheel.
            targetDistance -= Input.GetAxis("Mouse ScrollWheel") * mouseSettings.wheelSensitivity;
            targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);

            //Lerp.
            currentAngles = Vector2.Lerp(currentAngles, targetAngles, damper * Time.deltaTime);
            currentDistance = Mathf.Lerp(currentDistance, targetDistance, damper * Time.deltaTime);

            //Update transform position and rotation.
            transform.rotation = Quaternion.Euler(currentAngles);
            transform.position = selfTarget.position - transform.forward * currentDistance;
        }

        
        #endregion
    }
}

3. 调用方法

using System.Collections.Generic;
using Developer.CameraExtension;
using UnityEngine;
using UnityEngine.UI;

public class CommonGameTarget : MonoBehaviour
{
    private Button TuoKaBtn, DeTuoKaBtn;
    public GameObject GameTargetPa;
    public List<GameObject> ControlGameObject;
    private GameObject ControlGoProp
    {
        get
        {
            foreach (var g in ControlGameObject)
                if (g.activeInHierarchy)
                    return g;
            return null;
        }
    }

    private ImageTargetInherit m_ImageTarget;

    private void Start()
    {
        TuoKaBtn = Utils.UtilsSearch.RecursiveFindChild(transform, "btn_Tuoka").GetComponent<Button>();
        DeTuoKaBtn = Utils.UtilsSearch.RecursiveFindChild(transform, "btn_DeTuoKa").GetComponent<Button>();

        TuoKaBtn.onClick.AddListener(StartTuoKa);
        DeTuoKaBtn.onClick.AddListener(StopTuoKa);
        m_ImageTarget = transform.FindInParents<ImageTargetInherit>();
    }

    private void StartTuoKa()
    {
        m_ImageTarget.IsTuoKa = true;

        EasyARManager.Instance.StartTrack();

        TuoKaBtn.gameObject.SetActive(false);
        DeTuoKaBtn.gameObject.SetActive(true);

        //ObjectControl.Instance.SetTarget(ControlGoProp.transform);

        //AroundCameraPC.Instance.SetTarget(ControlGoProp.transform);
        AroundCameraMobile.Instance.SetTarget(ControlGoProp.transform);
    }

    private void StopTuoKa()
    {
        m_ImageTarget.IsTuoKa = false;
        m_ImageTarget.OnStopTuoKa();
        EasyARManager.Instance.StopTrack();

        TuoKaBtn.gameObject.SetActive(true);
        DeTuoKaBtn.gameObject.SetActive(false);

        //AroundCameraPC.Instance.SetDefault();
        AroundCameraMobile.Instance.SetDefault();
        //ObjectControl.Instance.SetDefault();
    }
}

猜你喜欢

转载自blog.csdn.net/baidu_33643757/article/details/86218511