0

Working on a a Unity project and I'm caching an GameObject reference via its implemented interface at the start of my coroutine. For some reason, this variable is "out of scope" when I debug it. This causes any variable that references it (like the boolean below it) to be out of scope as well. I've tried a number of fixes, from updating VS2019, to ensuring all projects are set to start up when attaching to Unity to debug. I've tried every fix that applied to my issue suggested here:

Visual Studio 2015 Debugging: Can't expand local variables?

Nothing I do allows me to scrutinize this variable or anything associated with it. It doesn't show up in the Locals window. I'm not sure what I'm missing here, but it's been a real pain to debug this code. Any help would be appreciated!

EDIT: Provided code sample:

private IEnumerator TranslateTouchableNew(Touchable translator, OffsetTransform destination)
{
    bool hasArrived = false;

    ITouchTranslationProfile profile = translator.TranslationProfile;
    bool hasProfile = (profile != null);

    //Translator position vars
    Vector3 positionBeforeYArcOffset = translator.transform.position;
    Vector3 newPosition;
    Vector3 normalizedHeading = Vector3.zero;

    //Destination & Distance
    Vector3 destinationWithOffsets = CalculateDestinationWithOffsets();
    float startingDistance = (destinationWithOffsets - positionBeforeYArcOffset).magnitude; //Length between the translator transform and the final destinatin vector after considering receptacle offset and translator mesh offset
    float currentDistance = startingDistance;
    float distanceCoveredPercent;

    //Applying profile values, if they exist; otherwise use default values for speed and arc
    AnimationCurve yArc = hasProfile && profile.YArcOverride != null ? profile.YArcOverride : standardYArcOffset;
    float yArcProximityFactor = yArcByProximityFactor.Evaluate(startingDistance);
    float speed = hasProfile ? metersPerSecond * profile.SpeedScalePercent : metersPerSecond;

    while (!hasArrived)
    {
        //Skip standard translator logic for custom implementation on the translator
        if (hasProfile && profile.UseCustomTranslation) hasArrived = profile.CustomTranslateUntilArrived(destination);
        else
        {
            //Calculate the final destination. Because the destination is transform based (it can move), this needs to be done every frame.
            destinationWithOffsets = CalculateDestinationWithOffsets();

            //This is needed to get an accurate calculation on distance covered BEFORE applying the Y Arc offset, which interferes with the actual length calculated by GetCurrentDistance()
            //translator.transform.position = positionBeforeOffset;

            currentDistance = (destinationWithOffsets - positionBeforeYArcOffset).magnitude;

            //Closer the translator is to the destination, the higher the percent
            distanceCoveredPercent = 1 - (currentDistance / startingDistance);

            ///Application of max speed (after application of <see cref="ITouchTranslationProfile.SpeedScalePercent"/>), by total distance proximity
            float speedFactor = speedByProximityFactor.Evaluate(distanceCoveredPercent);

            newPosition = Vector3.MoveTowards(translator.transform.position, destinationWithOffsets, (speed * speedFactor) * Time.deltaTime);
            LogVector3Explicit(newPosition, "position before YArc:");
            positionBeforeYArcOffset = newPosition;//Set this for next frame so that CurrentDistance can be accurately calculated
            SetArcOffsetOnNewPosition();//Apply YArc to the previously calculated NewPosition
            LogVector3Explicit(newPosition, "position after YArc:");
            translator.transform.position = newPosition;



            if (distanceCoveredPercent < 0.99f) normalizedHeading = (destinationWithOffsets - translator.transform.position).normalized;//Set the heading if we're almost done with translation
            if (hasProfile) profile.TranslationPercentComplete = distanceCoveredPercent; //translator may use this data for its own calculations
            if (distanceCoveredPercent >= 1.0f) hasArrived = true;
        }

        yield return null;
    }

    if (hasProfile) profile.OnArrival(normalizedHeading, speed);
    CoroutineByTranslator.Remove(translator);

    void SetArcOffsetOnNewPosition()
    {
        float yOffset = yArc.Evaluate(currentDistance);
        yOffset *= yArcProximityFactor;
        newPosition.y += yOffset;
    }

    Vector3 CalculateDestinationWithOffsets()
    {
        Vector3 finalPosition = destination.Transform.position + destination.Offset;
        if (hasProfile) finalPosition.y += profile.TransformToMeshEndLength;
        return finalPosition;
    }

    void LogVector3Explicit(Vector3 logMe, string name)
    {
        Debug.Log(name + " : " + logMe.x + ", " + logMe.y + ", " + logMe.z);

    }
}

Assigning "Profile" from the provided Touchable translator (translator implements Monobehavior and has a reference to the component that implements ITouchTranslatorProfile) is the variable in question.

Here's the breakpointed code sample to help illustrate the issue I'm having while debugging (see Watch window):

CodeExample

  • Can you put the code in the question please? And not using images. – Zer0 Mar 14 '20 at 23:29
  • @Zer0 For sure. – VroomVroom Mar 14 '20 at 23:36
  • Hi. `//snip - rest is irrelevant` can actually be relevant. Does this part of your code refers to variables `profile` or `hasProfile`? Did you also try to click the refresh icon on the rightmost side of the watched variables? – Oguz Ozgul Mar 14 '20 at 23:41
  • 2
    Does this answer your question? [The identifier is not in the scope \[Unity, VS2019\]](https://stackoverflow.com/questions/56282608/the-identifier-is-not-in-the-scope-unity-vs2019) – Zer0 Mar 14 '20 at 23:41
  • @OguzOzgul It does. I tried refreshing, yes. Happy to provide the rest of the method body, but I don't see how code after assignment would make a difference here. It's a somewhat long chunk of code... – VroomVroom Mar 14 '20 at 23:50
  • "but I don't see how code after assignment would make a difference here": Compiler optimization. – Oguz Ozgul Mar 14 '20 at 23:56
  • See the linked question. Looks like this was a known bug. It is marked as fixed, so have you tried the workaround they suggest or updating VS2019 to version 16.2? I also presume you are not debugging a release build. – Zer0 Mar 14 '20 at 23:56
  • @OguzOzgul Gotcha. Thanks for clarifying. Updating... – VroomVroom Mar 14 '20 at 23:57
  • @Zer0 I don't have explicit namespaces declared - should I declare them for the interface and reference them explicitly to recreate the workaround? – VroomVroom Mar 15 '20 at 00:00
  • Ok the variables cannot be optimized out. "I've tried a number of fixes, from updating VS2019 to ...". The bug report link provided by @Zer0 seems to be specific to VS2019. You said upgrading to VS 2019 is one of the things you tried to fix the problem. Do you have the same problem on VS 2015? In the bug report, the op returned to VS2017 to fix it. – Oguz Ozgul Mar 15 '20 at 00:01
  • this https://issuetracker.unity3d.com/issues/local-variables-inside-coroutines-are-out-of-scope-in-the-watch-window-when-entities-package-is-installed and this https://issuetracker.unity3d.com/issues/dot-net-4-dot-6-cannot-see-local-variables-in-vs-watch-window-when-debugging-async-methods talk about the same problem. Are we sure that it is fixed? – Oguz Ozgul Mar 15 '20 at 00:11
  • Downloaded 2017 to check. Still seeing that same issue. Can't rollback to 2015 - getting errors from using local methods within the coroutine method (assuming cuz I'm using a newer version of C# that 2015 doesn't have support for?). Good point about that ticket. I'll file a bug with Unity. Thanks for you help! – VroomVroom Mar 15 '20 at 00:14

0 Answers0