Emi*_*mil 5 c# unity-game-engine
我正在开发一款基于位置的游戏,有点像口袋妖怪游戏。我正在阅读Android手机上的位置,没有任何问题,但是在统一编辑器中进行开发时,我无法获取任何位置数据,因为Input.location.isEnabledByUser在编辑器中为false
可以模拟/硬编码位置,这样我就可以在不部署到手机的情况下进行尝试了。
我试图这样硬编码:
LocationInfo ReadLocation(){
#if UNITY_EDITOR
var location = new LocationInfo();
location.latitude = 59.000f;
location.longitude = 18.000f;
location.altitude= 0.0f;
location.horizontalAccuracy = 5.0f;
location.verticalAccuracy = 5.0f;
return location;
#elif
return Input.location.lastData;
#endif
}
Run Code Online (Sandbox Code Playgroud)
但是该位置的所有属性都是只读的,因此出现编译错误。是否可以在编辑器中启用位置服务或对位置进行硬编码?
有没有办法在编辑器中启用位置服务,或对位置进行硬编码?
这就是Unity Remote诞生的原因之一。设置 Unity Remote,然后将您的移动设备连接到编辑器。您现在可以从编辑器获取真实位置。
但该位置的所有属性都是只读的
如果你真的想开发一种模拟位置的方法,你就必须放弃Unity的LocationInfo结构。进行您自己的定制LocationInfo并命名LocationInfoExt。Ext = 扩展。
也做同样的事情LocationService,然后将官方包装LocationService到您的自定义LocationServiceExt类中。您可以用来LocationServiceExt决定是否应该通过使用模拟位置来模拟位置LocationInfoExt,或者不通过内部使用来模拟位置LocationInfo来提供结果。
在下面的示例中,官方的LocationService, LocationInfo和LocationServiceStatusclass/struct/enum 被替换为LocationServiceExt,LocationInfoExt和LocationServiceStatusExt。它们还实现了相同的功能和属性。唯一的区别是您可以将 true/false 传递给 的构造函数 LocationServiceExt以便在编辑器中使用它。
LocationServiceExt包装类:
创建一个名为的类LocationServiceExt,然后将以下代码复制到其中: 它具有原始LocationService类中的每个函数和属性。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LocationServiceExt
{
private LocationService realLocation;
private bool useMockLocation = false;
private LocationInfoExt mockedLastData;
private LocationServiceStatusExt mockedStatus;
private bool mIsEnabledByUser = false;
public LocationServiceExt(bool mockLocation = false)
{
this.useMockLocation = mockLocation;
if (mockLocation)
{
mIsEnabledByUser = true;
mockedLastData = getMockLocation();
}
else
{
realLocation = new LocationService();
}
}
public bool isEnabledByUser
{
//realLocation.isEnabledByUser seems to be failing on Android. Input.location.isEnabledByUser is the fix
get { return useMockLocation ? mIsEnabledByUser : Input.location.isEnabledByUser; }
set { mIsEnabledByUser = value; }
}
public LocationInfoExt lastData
{
get { return useMockLocation ? mockedLastData : getRealLocation(); }
set { mockedLastData = value; }
}
public LocationServiceStatusExt status
{
get { return useMockLocation ? mockedStatus : getRealStatus(); }
set { mockedStatus = value; }
}
public void Start()
{
if (useMockLocation)
{
mockedStatus = LocationServiceStatusExt.Running;
}
else
{
realLocation.Start();
}
}
public void Start(float desiredAccuracyInMeters)
{
if (useMockLocation)
{
mockedStatus = LocationServiceStatusExt.Running;
}
else
{
realLocation.Start(desiredAccuracyInMeters);
}
}
public void Start(float desiredAccuracyInMeters, float updateDistanceInMeters)
{
if (useMockLocation)
{
mockedStatus = LocationServiceStatusExt.Running;
}
else
{
realLocation.Start(desiredAccuracyInMeters, updateDistanceInMeters);
}
}
public void Stop()
{
if (useMockLocation)
{
mockedStatus = LocationServiceStatusExt.Stopped;
}
else
{
realLocation.Stop();
}
}
//Predefined Location. You always override this by overriding lastData from another class
private LocationInfoExt getMockLocation()
{
LocationInfoExt location = new LocationInfoExt();
location.latitude = 59.000f;
location.longitude = 18.000f;
location.altitude = 0.0f;
location.horizontalAccuracy = 5.0f;
location.verticalAccuracy = 5.0f;
location.timestamp = 0f;
return location;
}
private LocationInfoExt getRealLocation()
{
if (realLocation == null)
return new LocationInfoExt();
LocationInfo realLoc = realLocation.lastData;
LocationInfoExt location = new LocationInfoExt();
location.latitude = realLoc.latitude;
location.longitude = realLoc.longitude;
location.altitude = realLoc.altitude;
location.horizontalAccuracy = realLoc.horizontalAccuracy;
location.verticalAccuracy = realLoc.verticalAccuracy;
location.timestamp = realLoc.timestamp;
return location;
}
private LocationServiceStatusExt getRealStatus()
{
LocationServiceStatus realStatus = realLocation.status;
LocationServiceStatusExt stats = LocationServiceStatusExt.Stopped;
if (realStatus == LocationServiceStatus.Stopped)
stats = LocationServiceStatusExt.Stopped;
if (realStatus == LocationServiceStatus.Initializing)
stats = LocationServiceStatusExt.Initializing;
if (realStatus == LocationServiceStatus.Running)
stats = LocationServiceStatusExt.Running;
if (realStatus == LocationServiceStatus.Failed)
stats = LocationServiceStatusExt.Failed;
return stats;
}
}
public struct LocationInfoExt
{
public float altitude { get; set; }
public float horizontalAccuracy { get; set; }
public float latitude { get; set; }
public float longitude { get; set; }
public double timestamp { get; set; }
public float verticalAccuracy { get; set; }
}
public enum LocationServiceStatusExt
{
Stopped = 0,
Initializing = 1,
Running = 2,
Failed = 3,
}
Run Code Online (Sandbox Code Playgroud)
用法:
创建模拟位置
LocationServiceExt locationServiceExt = new LocationServiceExt(true);
Run Code Online (Sandbox Code Playgroud)
创建真实位置
LocationServiceExt locationServiceExt = new LocationServiceExt(false);
Run Code Online (Sandbox Code Playgroud)
稍后修改位置
LocationInfoExt locInfo = new LocationInfoExt();
locInfo.latitude = 59.000f;
locInfo.longitude = 18.000f;
locInfo.altitude = -3.0f; //0.0f;
locInfo.horizontalAccuracy = 5.0f;
locInfo.verticalAccuracy = 5.0f;
locationServiceExt.lastData = locInfo; //Apply the location change
Run Code Online (Sandbox Code Playgroud)
来自Unity Doc的完整移植工作示例。
public Text text;
IEnumerator StartGPS()
{
text.text = "Starting";
//Pass true to use mocked Location. Pass false or don't pass anything to use real location
LocationServiceExt locationServiceExt = new LocationServiceExt(true);
LocationInfoExt locInfo = new LocationInfoExt();
locInfo.latitude = 59.000f;
locInfo.longitude = 18.000f;
locInfo.altitude = -3.0f; //0.0f;
locInfo.horizontalAccuracy = 5.0f;
locInfo.verticalAccuracy = 5.0f;
locationServiceExt.lastData = locInfo;
// First, check if user has location service enabled
if (!locationServiceExt.isEnabledByUser)
{
text.text = "Not Enabled";
yield break;
}
else
{
text.text = "Enabled!";
}
// Start service before querying location
locationServiceExt.Start();
// Wait until service initializes
int maxWait = 20;
while (locationServiceExt.status == LocationServiceStatusExt.Initializing && maxWait > 0)
{
text.text = "Timer: " + maxWait;
yield return new WaitForSeconds(1);
maxWait--;
}
// Service didn't initialize in 20 seconds
if (maxWait < 1)
{
print("Timed out");
text.text = "Timed out";
yield break;
}
// Connection has failed
if (locationServiceExt.status == LocationServiceStatusExt.Failed)
{
print("Unable to determine device location");
text.text = "Unable to determine device location";
yield break;
}
else
{
// Access granted and location value could be retrieved
string location = "Location: " + locationServiceExt.lastData.latitude + " "
+ locationServiceExt.lastData.longitude + " " + locationServiceExt.lastData.altitude
+ " " + locationServiceExt.lastData.horizontalAccuracy + " " + locationServiceExt.lastData.timestamp;
Debug.Log(location);
text.text = location;
}
// Stop service if there is no need to query location updates continuously
locationServiceExt.Stop();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4847 次 |
| 最近记录: |