美文网首页
将安卓手机输入映射到Unity工程中的虚拟屏幕中

将安卓手机输入映射到Unity工程中的虚拟屏幕中

作者: 全新的饭 | 来源:发表于2022-07-25 16:13 被阅读0次

    效果

    将手机输入位置映射到Unity中.gif
    1.配置adb环境
    adb压缩包:提取码:1234
    解压后添加到环境变量中
    解压后添加到环境变量中.png

    在Path中新建:%adb%


    在Path中新建.png

    验证是否配置成功:adb version


    验证是否配置成功.png

    将手机连到电脑上后,输入:adb shell getevent
    在手机上触摸一下,得到eventId的值。


    获取输入信息.png
    1. 在Unity中制作一个虚拟屏幕
      将前面得到的eventId填入后,运行游戏。


      配置虚拟屏幕.png

    代码

    MyAndroidAdb.cs

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Diagnostics;
    using System.IO;
    using System.Threading;
    
    public class MyAndroidAdb : MonoBehaviour
    {
        SynchronizationContext _syncContext;
        private System.Diagnostics.Process PP;
        private Vector2 _pos;
        private int _curFingerCnt;
    
        private Vector2 _size;
        private bool _canBroadcastPosInfo;
    
        public event Action<Vector2> StartSetPosEvent;
        public event Action StopSetPosEvent;
        public event Action<Vector2> SetPosEvent;
        [SerializeField]
        private int _eventId = 2;
        
    
        void Start()
        {
            _curFingerCnt = 0;
            _pos = Vector2.zero;
            _canBroadcastPosInfo = false;
            InitSize();
    
            _syncContext = SynchronizationContext.Current;
            System.Diagnostics.Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c adb shell getevent";
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            //p.EnableRaisingEvents = true;
            PP = p;
            p.Start();
            //
            p.OutputDataReceived += (s, a) =>
            {
                OnOutputDataReceived(a.Data);
            };
            //
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            //p.WaitForExit();
        }
        private void InitSize()
        {
            System.Diagnostics.Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c adb shell wm size";
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            //p.EnableRaisingEvents = true;
            p.Start();
            //
            p.OutputDataReceived += (s, a) =>
            {
                OnOutputDataReceived(a.Data);
            };
            //
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
    
            void OnOutputDataReceived(string readLine)
            {
                var str = readLine.Replace("Physical size: ", string.Empty);
                string[] ss = str.Split('x');
                int w = int.Parse(ss[0]);
                int h = int.Parse(ss[1]);
                _size = new Vector2(w, h);
                UnityEngine.Debug.Log(_size);
                p.Close();
            }
        }
    
        void OnOutputDataReceived(string readLine)
        {
            _syncContext.Post(_ =>
            {
                //UnityEngine.Debug.Log($"adb getevent--->{readLine}");
                //
                // UnityEngine.Debug.Log(readLine);
    
                if (readLine != null)
                {
                    if (readLine.StartsWith("/dev/input/event"+_eventId.ToString()))
                    {
                        string[] ss = readLine.Split(' ');
                        if (_curFingerCnt == 1)
                        {
                            if (readLine.Contains("0035"))
                            {
                                string x = ss[3];
                                _pos.x = int.Parse(x, System.Globalization.NumberStyles.HexNumber);
                                // UnityEngine.Debug.Log($"x坐标{_pos.x}");
                            }
                            if (readLine.Contains("0036"))
                            {
                                string x = ss[3];
                                _pos.y = int.Parse(x, System.Globalization.NumberStyles.HexNumber);
                                // UnityEngine.Debug.Log($"y坐标{_pos.y}");
                            }
                        }
    
                        if (ss[2] == "0039")
                        {
                            if (ss[3] == "ffffffff")
                            {
                                _curFingerCnt--;
                            }
                            else
                            {
                                _curFingerCnt++;
                            }
                        }
                        
                        if (ss[1] == "0001" && ss[2] == "014a")
                        {
                            // UnityEngine.Debug.Log(readLine);
                            if (ss[3] == "00000001")
                            {
                                FirstPointerDown();
                            }
                            else if (ss[3] == "00000000")
                            {
                                LastPointerUp();
                            }
                        }
                    }
                }
            }, null);
    
        }
    
        [ContextMenu("强制停止")]
        void ForceStop()
        {
            PP.Close();
        }
    
        // 第一根手指触到屏幕
        private void FirstPointerDown()
        {
            MonoSys.Instance.DelayCall(0.03f, () =>
             {
                 _canBroadcastPosInfo = true;
                 StartSetPosEvent?.Invoke(PosInfo);
                 UnityEngine.Debug.Log("StartSetPosEvent: " + PosInfo);
             });
        }
        // 最后一根手指离开屏幕
        private void LastPointerUp()
        {
            _canBroadcastPosInfo = false;
            StopSetPosEvent?.Invoke();
        }
    
        private void Update() 
        {
            if (_canBroadcastPosInfo)
            {
                BroadcastPosInfo();
            }
        }
    
        private void BroadcastPosInfo()
        {
            SetPosEvent?.Invoke(PosInfo);
        }
    
        private Vector2 PosInfo
        {
            get
            {
                float x = _pos.x;
                float y = _size.y - _pos.y;
                return new Vector2(x / _size.x, y / _size.y);
            }
        }
    }
    

    DisplayFingerPos.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class DisplayFingerPos : MonoBehaviour
    {
        [SerializeField]
        private Transform _minTrans;
        [SerializeField]
        private Transform _maxTrans;
        [SerializeField]
        private Transform _fingerSignTrans;
    
        private MyAndroidAdb _adb;
        private float _width;
        private float _height;
        [SerializeField]
        private float _moveSpeed = 10;
        private Vector3 _targetPos;
    
        private void Start()
        {
            Init(FindObjectOfType<MyAndroidAdb>());
        }
    
        private void Update() 
        {
            _fingerSignTrans.localPosition = Vector3.Lerp(_fingerSignTrans.localPosition, _targetPos, _moveSpeed * Time.deltaTime);
        }
    
        private void OnDestroy()
        {
            Destroy();
        }
    
        private void Init(MyAndroidAdb adb)
        {
            _targetPos = _fingerSignTrans.localPosition;
            _width = _maxTrans.localPosition.x - _minTrans.localPosition.x;
            _height = _maxTrans.localPosition.y - _minTrans.localPosition.y;
            HideSign();
    
            _adb = adb;
            _adb.StartSetPosEvent += OnStartSetPos;
            _adb.SetPosEvent += OnSetPos;
            _adb.StopSetPosEvent += OnStopSetPos;
        }
        private void Destroy()
        {
            if (_adb != null)
            {
                _adb.StartSetPosEvent -= OnStartSetPos;
                _adb.SetPosEvent -= OnSetPos;
                _adb.StopSetPosEvent -= OnStopSetPos;
                _adb = null;
            }
    
        }
    
        private void OnStartSetPos(Vector2 posInfo)
        {
            SetPos(posInfo);
            _fingerSignTrans.localPosition = _targetPos;
            ShowSign();
        }
        private void OnSetPos(Vector2 posInfo)
        {
            SetPos(posInfo);
        }
        private void OnStopSetPos()
        {
            HideSign();
        }
    
        private void ShowSign()
        {
            _fingerSignTrans.gameObject.SetActive(true);
        }
        private void HideSign()
        {
            _fingerSignTrans.gameObject.SetActive(false);
        }
        private void SetPos(Vector2 posInfo)
        {
            var localX = _minTrans.localPosition.x + _width * posInfo.x;
            var localY = _minTrans.localPosition.y + _height * posInfo.y;
            _targetPos = new Vector3(localX, localY, _minTrans.localPosition.z);
        }
    }
    

    相关文章

      网友评论

          本文标题:将安卓手机输入映射到Unity工程中的虚拟屏幕中

          本文链接:https://www.haomeiwen.com/subject/pgggirtx.html