StopCoroutine ไม่ทำงานแม้แต่ StartCoroutine (สตริง), StopCoroutine (สตริง) ใน unity3d

ฉันไม่เข้าใจว่าทำไม

ฉันได้อ่านเอกสารเกี่ยวกับเรื่องนี้มากมายแล้วและมีความคิดเห็นมากมาย

StopCoroutine (สตริง) สามารถหยุด coroutine ที่เริ่มต้นด้วย StartCoroutine (สตริง) เท่านั้น

รหัสอยู่ด้านล่าง

ในคลาส CharTouchControl.cpp

if( Input.GetKeyDown( KeyCode.Q ) )
{
    _CharControl.StartCoroutine("useFever", 10);
}

_CharControl เป็นสมาชิกของ CharTouchControl และแน่นอนว่า _CharControl อ้างอิงอินสแตนซ์ CharControl ด้านล่าง

และ CharControl ในคลาส

public IEnumerator useFever(float _duration = 10)
{
    if( m_nUseFever < _nFeverMax )
    {
        Debug.Log("Stop!!");
        StopCoroutine("useFever");
        yield return new WaitForEndOfFrame();
    }

    m_fgCharState = CharState._FEVER;

    // fever particle
    m_psFeverPaticle.Simulate(4);

    yield return new WaitForEndOfFrame();
} // end of useFever

เมื่อ m_nUseFever ‹ _nFeverMax เป็นจริง ฉันจะเห็น "หยุด!!" บันทึก,

แต่โครูทีนไม่หยุดและจำลองปาติเคิล

มีใครช่วยเรื่องนี้บ้างไหม?


person Chickenchaser    schedule 13.11.2013    source แหล่งที่มา
comment
ด้วยความสงสัย ทำไมคุณถึงใช้ StopCoroutine จากภายในโครูทีน? ใช้ yield break ในคำสั่ง if แรกแทน   -  person Jerdak    schedule 13.11.2013
comment
คุณเรียก StopCoroutine ซึ่งจะป้องกันไม่ให้ส่วนที่เหลือของฟังก์ชัน (ซึ่งรวมถึงการจำลองอนุภาค) ดำเนินการ คุณกำลังพยายามบรรลุผลคืออะไร?   -  person Dan Puzey    schedule 13.11.2013


คำตอบ (1)


เช่นเดียวกับที่ Jerdak กล่าวไว้ คุณควรใช้ Yield Break เมื่อคุณอยู่ใน Coroutine โครูทีนจะหยุดโดยอัตโนมัติเมื่อบล็อคโค้ดเสร็จสิ้น การใช้ Yield Break ควรส่งไปที่จุดสิ้นสุดของบล็อกโค้ด

นอกจากนี้ คุณยังสามารถแก้ไขโค้ดของคุณเพื่อให้รันบล็อคโค้ดได้หากเงื่อนไขเป็นจริงเท่านั้น ฉันได้ทำสิ่งนี้ในตัวอย่างด้านล่าง หากเงื่อนไขเป็นเท็จ โครูทีนก็จะรอจนสิ้นสุดเฟรมแล้วจึงออก

public IEnumerator useFever()
{
    if( m_nUseFever > _nFeverMax )
    {
        m_fgCharState = CharState._FEVER;

        // fever particle
        m_psFeverPaticle.Simulate(4);
    }

    yield return new WaitForEndOfFrame();        
} //Coroutine automatically exits here

แก้ไข: Dan Puzey นำเสนอประเด็นที่ดี คุณแน่ใจหรือไม่ว่าไม่ควรใช้

Invoke("useFever",10) or InvokeRepeating ("useFever",10,1)

แทน? จากโค้ดของคุณ ดูเหมือนว่าคุณเพียงต้องการเรียกใช้ฟังก์ชัน useFever ภายใน 10 วินาที หากเป็นเช่นนั้น คุณควรเรียกใช้มันแทนที่จะรันเป็น coroutine และ useFever ควรเป็นฟังก์ชันปกติ

เพื่อการอ้างอิงเท่านั้น ยังมี CancelInvoke("useFever")

person MichaelTaylor3D    schedule 13.11.2013
comment
หากโค้ดนั้นทำงานตามที่ OP ตั้งใจไว้ จะไม่มีค่าใดที่รันโค้ดนั้นใน coroutine - มันจะรันจนจบในเฟรมเดียวอยู่แล้ว นอกจากนี้ ไม่ค่อยมีค่าในบรรทัดสุดท้ายของ coroutine ที่เป็น yield (เว้นแต่ว่าคุณกำลังผูกมัด coroutines) - person Dan Puzey; 13.11.2013
comment
ฉันเห็นด้วยกับคุณ แต่เขาวางไว้ตรงนั้น ดังนั้นเมื่อฉันปรับโครงสร้างโค้ดของเขาใหม่ ฉันคิดว่าเขามีเหตุผลของเขา ฉันคิดว่ามันเป็นเหตุผลด้านเวลา มันไม่ได้ขึ้นอยู่กับฉันที่จะตัดสินใจ - person MichaelTaylor3D; 13.11.2013