gpt4 book ai didi

c# - 如何在统一编辑器中使用 Input.Location 和模拟位置

转载 作者:太空狗 更新时间:2023-10-29 23:13:07 29 4
gpt4 key购买 nike

我正在构建一个基于位置的游戏,有点像 pokemon go。我在我的 android 手机上读取位置没有任何问题,但是当我在 unity 编辑器中开发时我无法获取任何位置数据,因为 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
}

但是该位置的所有属性都是只读的,所以我遇到了编译错误。有没有办法在编辑器中启用位置服务,或者对位置进行硬编码?

最佳答案

Is there a way to enable location service in the editor, or hardcode a location?

这就是为什么 Unity Remote 的原因之一。被制成。设置 Unity Remote,然后将您的移动设备连接到编辑器。您现在可以从编辑器中获取真实位置。

But all of the properties of the location are read only

如果你真的想开发一种模拟位置的方法,你必须放弃 Unity 的 LocationInfo 结构。制作您自己的自定义 LocationInfo 并将其命名为 LocationInfoExt。 Ext = 扩展。

也为 LocationService 做同样的事情,然后将官方 LocationService 包装到您的自定义 LocationServiceExt 类中。您可以使用 LocationServiceExt 来决定是否应该使用 LocationInfoExt 模拟位置,或者不通过在内部使用 LocationInfo 来提供结果来模拟位置。

在下面的示例中,官方的 LocationServiceLocationInfoLocationServiceStatus 类/结构/枚举被替换为 LocationServiceExtLocationInfoExtLocationServiceStatusExt。它们还实现了相同的功能和属性。唯一的区别是您可以将 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,
}

用法:

创建模拟位置

LocationServiceExt locationServiceExt = new LocationServiceExt(true);

创建真实位置

LocationServiceExt locationServiceExt = new LocationServiceExt(false);

稍后修改位置

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

来自 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();
}

关于c# - 如何在统一编辑器中使用 Input.Location 和模拟位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38828748/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com