c# - How to use the Input.Location and mock location in the unity editor -
i building location based game, bit pokemon go. reading location on android phone without problem, can't location data when i'm developing in unity editor since input.location.isenabledbyuser false in editor
it ok mock/hard code location, can try without deploying phone.
i tried hard code this:
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 }
but of properties of location read only, i'm getting compilation errors. there way enable location service in editor, or hardcode location?
is there way enable location service in editor, or hardcode location?
this 1 of reasons why unity remote 4 made. setup unity remote connect mobile device editor. can real location editor.
but of properties of location read only
if want develop way mock location, have abandon unity's locationinfo
structure. make own custom locationinfo
, name locationinfoext
. ext = extended.
do the-same thing locationservice
too, wrap official locationservice
custom locationserviceext
class. can use locationserviceext
decide if should mock location using locationinfoext
or not mock location using locationinfo
internally provide result.
in example below, official locationservice
, locationinfo
, locationservicestatus
class/struct/enum replaced locationserviceext
, locationinfoext
, locationservicestatusext
. have the-same functions , properties implemented. difference can pass true/false constructor of locationserviceext
in order use in editor.
locationserviceext
wrapper class:
create class called locationserviceext
copy code below it: has every function , property original locationservice
class.
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 failing on android. input.location.isenabledbyuser fix { return usemocklocation ? misenabledbyuser : input.location.isenabledbyuser; } set { misenabledbyuser = value; } } public locationinfoext lastdata { { return usemocklocation ? mockedlastdata : getreallocation(); } set { mockedlastdata = value; } } public locationservicestatusext status { { 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. override overriding lastdata 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, }
usage:
create mock location
locationserviceext locationserviceext = new locationserviceext(true);
create real location
locationserviceext locationserviceext = new locationserviceext(false);
modify location later on
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 location change
full ported working example unity doc.
public text text; ienumerator startgps() { text.text = "starting"; //pass true use mocked location. pass false or don't pass 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 determine device location"); text.text = "unable determine device location"; yield break; } else { // access granted , location value 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 no need query location updates continuously locationserviceext.stop(); }
Comments
Post a Comment