简体   繁体   中英

Unity 3D: Coroutine weapon animation won't execute more than once

I have a telescoping spike weapon for a game I'm working on that works perfectly fine once, but won't fire again afterwards:

public void ExpandSequence()
{
    if (!mExpanding)
    {
        StartCoroutine(mExpand);
    }
        
}

private IEnumerator _ExpandSequence()
{
    mExpanding = true;
    mBaseGoal = transform.localPosition + mBaseDistance * Vector3.up;
    mConeGoal = mSpikeSections[5].localPosition + mConeDistance * Vector3.up;

    while (transform.localPosition.y > mBaseSpikeEnd || mSpikeSections[1].localPosition.y > mCylinderEnd
        || mSpikeSections[5].localPosition.y > mConeEnd)
    { //only using the first cylinder section in the condition since they all move the same distance
        
        transform.localPosition = Vector3.MoveTowards(transform.localPosition, mBaseGoal, mSpeed);

        mSpikeSections[1].localPosition = mSpikeSections[2].localPosition = mSpikeSections[3].localPosition = 
            mSpikeSections[4].localPosition = Vector3.MoveTowards(mSpikeSections[1].localPosition, Vector3.up * mCylinderDistance, mSpeed);

        mSpikeSections[5].localPosition = Vector3.MoveTowards(mSpikeSections[5].localPosition, mConeGoal, mSpeed);

        if (Mathf.Approximately(transform.localPosition.y, mBaseSpikeEnd) &&
            Mathf.Approximately(mSpikeSections[1].localPosition.y, mCylinderEnd) &&
            Mathf.Approximately(mSpikeSections[5].localPosition.y, mConeEnd))
        {
            mExpanding = false; //probably unnecessary
            transform.localPosition = mBaseGoal;
            mSpikeSections[5].localPosition = mConeGoal;

            yield break; //putting this here stops it from looping, but it still won't fire a second time
        }

        yield return null;
    }
    mExpanding = false;
}

public void CollapseSequence()
{
    if (!mCollapsing)
    {
        StartCoroutine(mCollapse);
    }
}

private IEnumerator _CollapseSequence()
{
    mCollapsing = true;
    mBaseGoal = transform.localPosition - mBaseDistance * Vector3.up;
    mConeGoal = mSpikeSections[5].localPosition - mConeDistance * Vector3.up;

    while (transform.localPosition.y < mBaseSpikeStart || mSpikeSections[1].localPosition.y < mCylinderStart
        || mSpikeSections[5].localPosition.y < mConeStart)
    { //only using the first cylinder section in the condition since they all move the same distance

        transform.localPosition = Vector3.MoveTowards(transform.localPosition, mBaseGoal, mSpeed);

        mSpikeSections[1].localPosition = mSpikeSections[2].localPosition = mSpikeSections[3].localPosition =
            mSpikeSections[4].localPosition = Vector3.MoveTowards(mSpikeSections[1].localPosition, Vector3.zero, mSpeed);

        mSpikeSections[5].localPosition = Vector3.MoveTowards(mSpikeSections[5].localPosition, mConeGoal, mSpeed);

        if (Mathf.Approximately(transform.localPosition.y, mBaseSpikeStart) && 
            Mathf.Approximately(mSpikeSections[1].localPosition.y, mCylinderStart) && 
            Mathf.Approximately(mSpikeSections[5].localPosition.y, mConeStart))
        {
            transform.localPosition = mBaseGoal;
            mSpikeSections[5].localPosition = mConeGoal;
            mCollapsing = false; //probably unnecessary
            yield break; //putting this here stops it from looping, but it still won't fire a second time
        }

        yield return null;
    }
    mCollapsing = false;
}

The if-statements I added at the end were for "damage control" but don't seem to change the general outcome. The expand helper function "Expand()" seems to execute every time, but the actual functions as well as the collapse helper function only run once. If anyone can help me figure this out it would be greatly appreciated.

I don't see where you assign mExpand and mCollapse .

But I guess you did it only once eg in Start . It then happens only once because the assigned routine is already finished after the first run.

It should probably rather be eg

public void ExpandSequence()
{
    if (!mExpanding)
    {
        mExpand = StartCoroutine(_ExpandSequence());
    }
}

and accordingly also for the collapse routine in order to be running a new IEnumerator / Coroutine instead of the one that already ran to the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM