效果
1.配置adb环境
adb压缩包:提取码:1234
解压后添加到环境变量中
解压后添加到环境变量中.png
在Path中新建:%adb%
在Path中新建.png
验证是否配置成功:adb version
验证是否配置成功.png
将手机连到电脑上后,输入:adb shell getevent
在手机上触摸一下,得到eventId的值。
获取输入信息.png
-
在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);
}
}
网友评论