Unity3D程序在3 - 5秒后挂起

时间:2017-03-11 23:22:49

标签: c# unity3d

我在这里有这个代码:

for (int i=0; i<N; i++) 
{
    pid = fork();
    if (pid == -1) { // handle error }
    else if (pid == 0) {
        // son process (NO FORK INSIDE THIS ELSE IF!)
    }
    else { // parent process
        wait(NULL);
        exit(0);
    }
}

}

我的代码运行了大约3秒钟,然后它就像我不能再刷卡一样挂断(还有另一个用于滑动的脚本)。然后大约5秒后,我的应用程序崩溃了。那有什么不对?

编辑代码

using UnityEngine;
using Assets.Helpers; //DONT COPY
using System;
using System.Collections;

public class TileManager : MonoBehaviour {
[SerializeField]
private Settings _settings;

[SerializeField]
private Transform target;

[SerializeField]
private Texture2D texture;
private GameObject tile;

[SerializeField]//DONT COPY
private GameObject service;//DONT COPY

private float oldLat = 0f, oldLon = 0f;
private float lat = 0f, lon = 0f;

public PokemonManager pokeManager;

public float getLat {
    get {
        return lat;
    }
}

public float getLon {
    get { 
        return lon;
    }
}

IEnumerator Start()
{
    while (!Input.location.isEnabledByUser) {
        print ("Activate gps");
        yield return new WaitForSeconds (1f);
    }

    Debug.Log ("1");
    Input.location.Start(10f, 5f);

    int maxWait = 20;
    while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
    {
        yield return new WaitForSeconds(1);
        maxWait--;
        Debug.Log ("2");
    }

    if (maxWait < 1)
    {
        print("Timed out");
        yield break;
    }

    if (Input.location.status == LocationServiceStatus.Failed)
    {
        print("Unable to determine device location");
        yield break;
    }
    else
    {
        print("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
    }

    lat = Input.location.lastData.latitude;
    lon = Input.location.lastData.longitude;

    StartCoroutine (loadTiles (_settings.zoom));

    while (Input.location.isEnabledByUser) {

        yield return new WaitForSeconds (1f);           
    }

    yield return StartCoroutine (Start ());
    yield break;
}

public IEnumerator loadTiles(int zoom) {
    int size = _settings.size;
    string key = _settings.key;
    string style = _settings.style;

    lat = Input.location.lastData.latitude;
    lon = Input.location.lastData.longitude;

    string url = String.Format ("https://api.mapbox.com/v4/mapbox.{5}/{0},{1},{2}/{3}x{3}@2x.png?access_token={4}", lon, lat, zoom, size, key, style);

    WWW www = new WWW (url);
    yield return www;

    texture = www.texture;

    if (tile == null) {
        tile = GameObject.CreatePrimitive (PrimitiveType.Plane);
        tile.name = "Tile " + lat + "" + lon;
        tile.transform.localScale = Vector3.one * _settings.scale;
        tile.GetComponent<Renderer> ().material = _settings.material;
        tile.transform.parent = transform;
    }

    if (oldLat != 0 && oldLon != 0) {
        float x, y;
        Vector3 position = Vector3.zero;

        geodeticOffsetInv (lat * Mathf.Deg2Rad, lon * Mathf.Deg2Rad, oldLat * Mathf.Deg2Rad, oldLon * Mathf.Deg2Rad, out x, out y);

        if ((oldLat - lat) < 0 && (oldLon - lon) > 0 || (oldLat - lat) > 0 && (oldLon - lon) < 0) {
            position = new Vector3 (x, .5f, y);
        } else {
            position = new Vector3 (-x, .5f, -y);
        }

        position.x *= 0.300122f;
        position.z *= 0.123043f;

        target.position = position;
        Debug.Log ("called");
        /*float[] ll = px (lat, lon, _settings.zoom);
        float[] oll = px (oldLat, oldLon, _settings.zoom);
        x = ll [0] - oll [0];
        y = ll [0] - oll [0];

        float ps = 10 * _settings.scale / _settings.size;
        x *= ps;
        y *= ps;

        Debug.Log (x + " / " + y);*/
    }

    pokeManager.UpdatePokemonPosition ();

    tile.GetComponent<Renderer> ().material.mainTexture = texture;

    yield return new WaitForSeconds (1f);

    oldLat = lat;
    oldLon = lon;

    while (oldLat == lat && oldLon == lon) {
        lat = Input.location.lastData.latitude;
        lon = Input.location.lastData.longitude;
        yield return new WaitForSeconds (0.5f);
    }

    yield return new WaitUntil ( () => (oldLat != lat || oldLon != lon) );

    yield return StartCoroutine (loadTiles (_settings.zoom));
    yield break;
}

/*float[] px (float lat, float lon, int zoom) {
    float d = (_settings.size / 2 * Mathf.Pow (2, _settings.zoom));
    float f = Mathf.Min(Mathf.Max(Mathf.Sin(Mathf.Deg2Rad * lat), -0.9999f), 0.9999f);
    float x = Mathf.Round(d + lon * (_settings.size / 360 * Mathf.Pow (2, _settings.zoom)));
    float y = Mathf.Round(d + 0.5f * Mathf.Log((1 + f) / (1 - f)) * (-(_settings.size / (2 * Mathf.PI) * Mathf.Pow (2, _settings.zoom))));
    float[] result = new float[2];
    result [0] = x;
    result [1] = y;
    return result;
}*/

//SOURCE: http://stackoverflow.com/questions/4953150/convert-lat-longs-to-x-y-co-ordinates

float GD_semiMajorAxis = 6378137.000000f;
float GD_TranMercB     = 6356752.314245f;
float GD_geocentF      = 0.003352810664f;

void geodeticOffsetInv( float refLat, float refLon,
    float lat,    float lon,
    out float xOffset, out float yOffset )
{
    float a = GD_semiMajorAxis;
    float b = GD_TranMercB;
    float f = GD_geocentF;

    float L = lon - refLon;
    float U1    = Mathf.Atan((1-f) * Mathf.Tan(refLat));
    float U2    = Mathf.Atan((1-f) * Mathf.Tan(lat));
    float sinU1 = Mathf.Sin(U1);
    float cosU1 = Mathf.Cos(U1);
    float sinU2 = Mathf.Sin(U2);
    float cosU2 = Mathf.Cos(U2);

    float lambda = L;
    float lambdaP;
    float sinSigma;
    float sigma;
    float cosSigma;
    float cosSqAlpha;
    float cos2SigmaM;
    float sinLambda;
    float cosLambda;
    float sinAlpha;
    int iterLimit = 100;
    do {
        sinLambda = Mathf.Sin(lambda);
        cosLambda = Mathf.Cos(lambda);
        sinSigma = Mathf.Sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
            (cosU1*sinU2-sinU1*cosU2*cosLambda) *
            (cosU1*sinU2-sinU1*cosU2*cosLambda) );
        if (sinSigma==0)
        {
            xOffset = 0.0f;
            yOffset = 0.0f;
            return ;  // co-incident points
        }
        cosSigma    = sinU1*sinU2 + cosU1*cosU2*cosLambda;
        sigma       = Mathf.Atan2(sinSigma, cosSigma);
        sinAlpha    = cosU1 * cosU2 * sinLambda / sinSigma;
        cosSqAlpha  = 1 - sinAlpha*sinAlpha;
        cos2SigmaM  = cosSigma - 2*sinU1*sinU2/cosSqAlpha;
        if (cos2SigmaM != cos2SigmaM) //isNaN
        {
            cos2SigmaM = 0;  // equatorial line: cosSqAlpha=0 (ยง6)
        }
        float C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
        lambdaP = lambda;
        lambda = L + (1-C) * f * sinAlpha *
            (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
    } while (Mathf.Abs(lambda-lambdaP) > 1e-12 && --iterLimit>0);

    if (iterLimit==0)
    {
        xOffset = 0.0f;
        yOffset = 0.0f;
        return;  // formula failed to converge
    }

    float uSq  = cosSqAlpha * (a*a - b*b) / (b*b);
    float A    = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
    float B    = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
    float deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
        B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
    float s = b*A*(sigma-deltaSigma);

    float bearing = Mathf.Atan2(cosU2*sinLambda,  cosU1*sinU2-sinU1*cosU2*cosLambda);
    xOffset = Mathf.Sin(bearing)*s;
    yOffset = Mathf.Cos(bearing)*s;
}

void Update() {
    service.SetActive (!Input.location.isEnabledByUser);//DONT COPY
    target.position = Vector3.Lerp (target.position, new Vector3 (0,.5f, 0), 2.0f * Time.deltaTime);
    Debug.Log ("lerped");
}

[Serializable]
public class Settings {
    [SerializeField]
    public Vector2 centerPosition;
    [SerializeField]
    public Material material;
    [SerializeField]
    public int zoom = 18;
    [SerializeField]
    public int size = 640;
    [SerializeField]
    public float scale = 1f;
    [SerializeField]
    public int range = 1;
    [SerializeField]
    public string key = "KEY_HERE";
    [SerializeField]
    public string style = "emerald";
}

1 个答案:

答案 0 :(得分:1)

你正在进入无限循环。

问题在于:

yield return StartCoroutine (Start ());

当你执行yield return StartCoroutine (Start ())时,它会启动新的协同程序,然后等待以便旧程序完成(这将永远不会发生)然后它将启动另一个corutine而第一个正在运行

yield break;之后的yield return StartCoroutine (Start ()) 甚至会被调用。您可以在Debug.LogWarning("Finished coroutine!");之后添加yield break;来证明这一点。 <{1}}消息永远不会显示。

这里最大的问题是那些协同程序实际上都没有停止。他们Debug.Log然后开始另一个然后等待那个完成然后再开始另一个。 由于这个原因,您可以轻松地运行数千个协同程序。

要解决此问题需要做两件事

1 。删除yield以便协程可以退出

因此,请使用yield return代替StartCoroutine (Start ());

2 。在yield return StartCoroutine (Start ())之前输入yield return null;。你必须这样做,因为如果StartCoroutine (Start ());协程中的所有逻辑(例如Start())都无法运行,那么就不会产生/等待,你将再次获得无限循环。

为您的while (Input.location.isEnabledByUser)协程做同样的事情。