C# Unity 3D:Coroutine武器动画获胜';不要执行多次

C# Unity 3D:Coroutine武器动画获胜';不要执行多次,c#,unity3d,coroutine,C#,Unity3d,Coroutine,我有一个用于我正在制作的游戏的伸缩式钉子武器,它曾经工作得非常好,但之后不会再开火: public void ExpandSequence() { if (!mExpanding) { StartCoroutine(mExpand); } } private IEnumerator _ExpandSequence() { mExpanding = true; mBaseGoal = transform.localPosi

我有一个用于我正在制作的游戏的伸缩式钉子武器,它曾经工作得非常好,但之后不会再开火:

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;
}
public void ExpandSequence()
{
如果(!mExpanding)
{
启动程序(mExpand);
}
}
私有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>mconend)
{//仅使用条件中的第一个圆柱体截面,因为它们移动的距离相同
transform.localPosition=Vector3.moveToward(transform.localPosition,mBaseGoal,mSpeed);
mSpikeSections[1]。localPosition=mSpikeSections[2]。localPosition=mSpikeSections[3]。localPosition=
mSpikeSections[4]。localPosition=Vector3.moveToward(mSpikeSections[1]。localPosition,Vector3.up*mCylinderDistance,mSpeed);
mSpikeSections[5]。localPosition=Vector3.moveToward(mSpikeSections[5]。localPosition,mConeGoal,mSpeed);
if(数学近似值(transform.localPosition.y,mBaseSpikeEnd)&&
近似数学(mSpikeSections[1].localPosition.y,MCYLINDEND)&&
近似数学(mSpikeSections[5].localPosition.y,mconend))
{
mExpanding=false;//可能不必要
transform.localPosition=mBaseGoal;
mSpikeSections[5].localPosition=mConeGoal;
屈服中断;//把这个放在这里可以阻止它循环,但它仍然不会再次开火
}
收益返回空;
}
mExpanding=false;
}
公共空间塌陷序列()
{
如果(!mcollapping)
{
开始例行程序(mCollapse);
}
}
私有IEnumerator_CollapseSequence()
{
mcollapping=true;
mBaseGoal=transform.localPosition-mBaseDistance*Vector3.up;
mConeGoal=mSpikeSections[5].localPosition-mConeDistance*Vector3.up;
while(transform.localPosition.y

我在最后添加的if声明是为了“损害控制”,但似乎并没有改变总体结果。expand helper函数“expand()”似乎每次都执行,但实际函数和collapse helper函数只运行一次。如果有人能帮我解决这个问题,我将不胜感激。

我看不出您在哪里分配
mExpand
mCollapse

但我猜你只做了一次,例如在
开始
中。然后它只发生一次,因为分配的例程在第一次运行后已经完成

它可能应该是

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

相应地,为了运行一个新的IEnumerator,而不是已经运行到最后的那一个,折叠例程也是如此。

事实上,我在Start函数中分配了它们。这是我通常做的,这是我唯一一次遇到这样的问题。我也试过你的代码,但它告诉我你不能将一个协同程序转换成IEnumeratorOk,然后跳过
mExpand=
。。我以为你把它存储为
Coroutine
而不是
IEnumerator
这很有效!非常感谢你!作为将来的参考,您知道为什么通过变量名调用它们会给我带来问题,但调用函数本身却可以很好地工作吗?