Unity - 尝试在 Mapbox 的特定位置添加项目
Unity - trying to add items at specific locations in Mapbox
我遵循了 YouTube 上的一个教程,其中开发人员在 MapBox 中的图块上添加了以特定间隔在玩家周围生成的项目,并具有最大距离。我想要实现的是在特定的经度和纬度添加它们。
我所做的更改是循环遍历我要添加的项目的最大数量,递增 i 变量。然后,我没有像 newLat = getPlayerPosition() + random;
那样在玩家周围生成物品,而是像这样硬编码了纬度和经度:case 0: newLat = 48.30791f; newLon = 18.08611f; millenium_item.tag = "MI0"; break;
并且每个项目都添加到项目列表中。
我期望的行为是将每个项目添加到列表中,然后在地图上生成它们,但只添加了一个项目,即与玩家具有完全相同纬度和经度的项目:
case 3: newLat = 48.32232f; newLon = 18.09462f; millenium_item.tag = "MI3"; break;
案例 3 已添加,因为它与我的播放器具有相同的纬度和经度(phone 实际所在的位置)。
case 4: newLat = 48.32232f; newLon = 18.09538f; millenium_item.tag = "MI4"; break;
案例 4 没有添加,但正如您所见,它与案例 3 的位置非常接近。
我不知道我做错了什么。完整代码:
void SpawnItems() {
itemindex = 100;
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false)
{
MilleniumItemType type = (MilleniumItemType)(int)UnityEngine.Random.Range(0, Enum.GetValues(typeof(MilleniumItemType)).Length);
float newLat = 0;
float newLon = 0;
MilleniumPuzzle prefab = Resources.Load("MilleniumItems/puzzle", typeof(MilleniumPuzzle)) as MilleniumPuzzle;
MilleniumPuzzle millenium_item = Instantiate(prefab, Vector3.zero, Quaternion.Euler(-100, 0, 0)) as MilleniumPuzzle;
millenium_item.tileManager = tileManager;
switch (i)
{
...
case 3: newLat = 48.32232f; newLon = 18.09462f; millenium_item.tag = "MI3"; break;
case 4: newLat = 48.32232f; newLon = 18.09538f; millenium_item.tag = "MI4"; break;
case 5: newLat = 48.32310f; newLon = 18.09536f; millenium_item.tag = "MI5"; break;
...
}
/// OUR LAT: 48.32232 OUR LON: 18.09462
millenium_item.Init(newLat, newLon);
items.Add(millenium_item);
}
}
然后 Init 看起来像这样:
public void Init(float _lat, float _lon) {
lat = _lat;
lon = _lon;
UpdatePosition ();
}
和:
public void UpdatePosition() {
float x, y;
Vector3 position = Vector3.zero;
geodeticOffsetInv (tileManager.getLat * Mathf.Deg2Rad, tileManager.getLon * Mathf.Deg2Rad, lat * Mathf.Deg2Rad, lon * Mathf.Deg2Rad, out x, out y);
if ((lat - tileManager.getLat) < 0 && (lon - tileManager.getLon) > 0 || (lat - tileManager.getLat) > 0 && (lon - tileManager.getLon) < 0) {
position = new Vector3(x, .5f, y);
}
else {
position = new Vector3 (-x, .5f, -y);
}
position.x *= 0.300122f;
position.z *= 0.123043f;
Debug.Log("Position of inited millenium puzzle: " + position.x + " z: " + position.z);
transform.position = position;
}
很难说到底是什么原因造成的,但是这段代码很有可能会导致索引超出范围异常。
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false)
{
相反,您应该这样做:
for(int i = 0; i < googleSignIn.locationdata.length; i++)
{
if (googleSignIn.locationdata[i] == false)
{
但是,还有一个问题。
这个 class 和 googleSignIn
class 都在 Start()
中初始化它们自己,并且不能保证 googleSignIn
会先执行。要解决此问题,您应该将 SpawnItems();
调用移至 Awake()
而不是 Start()
我自己解决了这个问题。在精确坐标处添加项目从来没有奏效,因此我将项目坐标保存在数组中。然后在 update()
中,我将玩家的位置与物品所在的坐标进行比较。如果位置之间的差异在我定义的常数之间,那么物品将出现在玩家周围,虽然不完全在建筑物上,但在我的情况下我不介意。
示例:
`public void SpawnItems() {
itemindex = 100;
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false && spawnedItem[i] == false)
{
if(tileManager.getLat - itemLats[i] < 0.003f && tileManager.getLat - itemLats[i] > -0.003f && tileManager.getLon - itemLons[i] < 0.00103f && tileManager.getLon - itemLons[i] > -0.00103f)
{
MilleniumItemType type = (MilleniumItemType)(int)UnityEngine.Random.Range(0, Enum.GetValues(typeof(MilleniumItemType)).Length);
MilleniumPuzzle prefab = Resources.Load("MilleniumItems/puzzle", typeof(MilleniumPuzzle)) as MilleniumPuzzle;
MilleniumPuzzle millenium_item = Instantiate(prefab, Vector3.zero, Quaternion.Euler(-100, 0, 0)) as MilleniumPuzzle;
millenium_item.tileManager = tileManager;
float newLat = tileManager.getLat + UnityEngine.Random.Range(-0.0001f, 0.0001f);
float newLon = tileManager.getLon + UnityEngine.Random.Range(-0.0001f, 0.0001f);
if(newLat == previousLat || newLon == previousLon)
{
newLat = tileManager.getLat + UnityEngine.Random.Range(-0.0001f, 0.0001f);
newLon = tileManager.getLon + UnityEngine.Random.Range(-0.0001f, 0.0001f);
}
previousLon = newLon;
previousLat = newLat;
spawnedItem[i] = true;
millenium_item.tag = "MI" + i;
millenium_item.Init(newLat, newLon);
items.Add(millenium_item);
}
}
}
}`
如果您使用的是 MapBox,Location-based 游戏示例有一张地图,您现在可以在其中添加图层。选择数据源 'Mapbox Streets',然后使用指定 long/latitude 选项添加兴趣点。这使您可以在这些坐标处生成预制件。
我遵循了 YouTube 上的一个教程,其中开发人员在 MapBox 中的图块上添加了以特定间隔在玩家周围生成的项目,并具有最大距离。我想要实现的是在特定的经度和纬度添加它们。
我所做的更改是循环遍历我要添加的项目的最大数量,递增 i 变量。然后,我没有像 newLat = getPlayerPosition() + random;
那样在玩家周围生成物品,而是像这样硬编码了纬度和经度:case 0: newLat = 48.30791f; newLon = 18.08611f; millenium_item.tag = "MI0"; break;
并且每个项目都添加到项目列表中。 我期望的行为是将每个项目添加到列表中,然后在地图上生成它们,但只添加了一个项目,即与玩家具有完全相同纬度和经度的项目:
case 3: newLat = 48.32232f; newLon = 18.09462f; millenium_item.tag = "MI3"; break;
案例 3 已添加,因为它与我的播放器具有相同的纬度和经度(phone 实际所在的位置)。
case 4: newLat = 48.32232f; newLon = 18.09538f; millenium_item.tag = "MI4"; break;
案例 4 没有添加,但正如您所见,它与案例 3 的位置非常接近。
我不知道我做错了什么。完整代码:
void SpawnItems() {
itemindex = 100;
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false)
{
MilleniumItemType type = (MilleniumItemType)(int)UnityEngine.Random.Range(0, Enum.GetValues(typeof(MilleniumItemType)).Length);
float newLat = 0;
float newLon = 0;
MilleniumPuzzle prefab = Resources.Load("MilleniumItems/puzzle", typeof(MilleniumPuzzle)) as MilleniumPuzzle;
MilleniumPuzzle millenium_item = Instantiate(prefab, Vector3.zero, Quaternion.Euler(-100, 0, 0)) as MilleniumPuzzle;
millenium_item.tileManager = tileManager;
switch (i)
{
...
case 3: newLat = 48.32232f; newLon = 18.09462f; millenium_item.tag = "MI3"; break;
case 4: newLat = 48.32232f; newLon = 18.09538f; millenium_item.tag = "MI4"; break;
case 5: newLat = 48.32310f; newLon = 18.09536f; millenium_item.tag = "MI5"; break;
...
}
/// OUR LAT: 48.32232 OUR LON: 18.09462
millenium_item.Init(newLat, newLon);
items.Add(millenium_item);
}
}
然后 Init 看起来像这样:
public void Init(float _lat, float _lon) {
lat = _lat;
lon = _lon;
UpdatePosition ();
}
和:
public void UpdatePosition() {
float x, y;
Vector3 position = Vector3.zero;
geodeticOffsetInv (tileManager.getLat * Mathf.Deg2Rad, tileManager.getLon * Mathf.Deg2Rad, lat * Mathf.Deg2Rad, lon * Mathf.Deg2Rad, out x, out y);
if ((lat - tileManager.getLat) < 0 && (lon - tileManager.getLon) > 0 || (lat - tileManager.getLat) > 0 && (lon - tileManager.getLon) < 0) {
position = new Vector3(x, .5f, y);
}
else {
position = new Vector3 (-x, .5f, -y);
}
position.x *= 0.300122f;
position.z *= 0.123043f;
Debug.Log("Position of inited millenium puzzle: " + position.x + " z: " + position.z);
transform.position = position;
}
很难说到底是什么原因造成的,但是这段代码很有可能会导致索引超出范围异常。
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false)
{
相反,您应该这样做:
for(int i = 0; i < googleSignIn.locationdata.length; i++)
{
if (googleSignIn.locationdata[i] == false)
{
但是,还有一个问题。
这个 class 和 googleSignIn
class 都在 Start()
中初始化它们自己,并且不能保证 googleSignIn
会先执行。要解决此问题,您应该将 SpawnItems();
调用移至 Awake()
而不是 Start()
我自己解决了这个问题。在精确坐标处添加项目从来没有奏效,因此我将项目坐标保存在数组中。然后在 update()
中,我将玩家的位置与物品所在的坐标进行比较。如果位置之间的差异在我定义的常数之间,那么物品将出现在玩家周围,虽然不完全在建筑物上,但在我的情况下我不介意。
示例:
`public void SpawnItems() {
itemindex = 100;
for(int i = 0; i < count; i++)
{
if (googleSignIn.locationdata[i] == false && spawnedItem[i] == false)
{
if(tileManager.getLat - itemLats[i] < 0.003f && tileManager.getLat - itemLats[i] > -0.003f && tileManager.getLon - itemLons[i] < 0.00103f && tileManager.getLon - itemLons[i] > -0.00103f)
{
MilleniumItemType type = (MilleniumItemType)(int)UnityEngine.Random.Range(0, Enum.GetValues(typeof(MilleniumItemType)).Length);
MilleniumPuzzle prefab = Resources.Load("MilleniumItems/puzzle", typeof(MilleniumPuzzle)) as MilleniumPuzzle;
MilleniumPuzzle millenium_item = Instantiate(prefab, Vector3.zero, Quaternion.Euler(-100, 0, 0)) as MilleniumPuzzle;
millenium_item.tileManager = tileManager;
float newLat = tileManager.getLat + UnityEngine.Random.Range(-0.0001f, 0.0001f);
float newLon = tileManager.getLon + UnityEngine.Random.Range(-0.0001f, 0.0001f);
if(newLat == previousLat || newLon == previousLon)
{
newLat = tileManager.getLat + UnityEngine.Random.Range(-0.0001f, 0.0001f);
newLon = tileManager.getLon + UnityEngine.Random.Range(-0.0001f, 0.0001f);
}
previousLon = newLon;
previousLat = newLat;
spawnedItem[i] = true;
millenium_item.tag = "MI" + i;
millenium_item.Init(newLat, newLon);
items.Add(millenium_item);
}
}
}
}`
如果您使用的是 MapBox,Location-based 游戏示例有一张地图,您现在可以在其中添加图层。选择数据源 'Mapbox Streets',然后使用指定 long/latitude 选项添加兴趣点。这使您可以在这些坐标处生成预制件。