【问题标题】:How can I start the coroutine with time?如何随时间启动协程?
【发布时间】:2021-09-09 05:59:17
【问题描述】:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class PlayerMouthSpeechController : MonoBehaviour
{
    public TMP_Text[] texts;
    public bool startTalking = false;
    public float talkTime;
    public float duration;
    [Range(0, 100)]
    public float valueRange;
    private SkinnedMeshRenderer bodySkinnedMeshRenderer;
    //private bool isTalking = true;

    // Start is called before the first frame update
    void Start()
    {
        bodySkinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        /*if (startTalking && isTalking)
        {
            StartCoroutine(AnimateMouth());
            StartCoroutine(TalkTime());

            isTalking = false;
        }

        if(startTalking == false && isTalking == false)
        {
            isTalking = true;
        }*/
    }

    //Lerp between startValue and endValue over 'duration' seconds
    private IEnumerator LerpShape(float startValue, float endValue, float duration)
    {
        float elapsed = 0;
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float value = Mathf.Lerp(startValue, endValue, elapsed / duration);
            bodySkinnedMeshRenderer.SetBlendShapeWeight(0, value);
            yield return null;
        }
    }

    //animate open and closed, then repeat
    public IEnumerator AnimateMouth()
    {
        while (startTalking == true)
        {
            yield return StartCoroutine(LerpShape(0, valueRange, duration));
            yield return StartCoroutine(LerpShape(valueRange, 0, duration));
        }
    }

    public IEnumerator TalkTime()
    {
        yield return new WaitForSeconds(talkTime);

        startTalking = false;
    }
}

我之前用太多标志搞砸了,在 Update() 中也搞砸了。

我想做一些简单的事情。为了能够从任何其他脚本调用 AnimateMouth 方法并且 AnimateMouth 方法也将获得一个浮点数,这将是嘴部动画的时间。类似:

StartCoroutine(AnimateMouth(4f));

但我把这一切都搞砸了。可能是让 AnimateMout 公共静态,或者在从另一个脚本调用时首先引用 PlayerMouthSpeechController,然后将其称为:

playerMouthSpeechController.AnimateMouth(); 

然后一些东西会启动 AnimatedMouth 协程。但我又搞砸了。

更新:

这几乎可以完美地按照我的意愿运行,但每次我希望播放器开始说话时,我都需要使用 StartCoroutine,但它可以正常工作。

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class PlayerMouthSpeechController : MonoBehaviour
{
    public TMP_Text[] texts;
    public float duration;
    [Range(0, 100)]
    public float valueRange;

    private bool startTalking = false;
    private SkinnedMeshRenderer bodySkinnedMeshRenderer;

    // Start is called before the first frame update
    void Start()
    {
        bodySkinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    //Lerp between startValue and endValue over 'duration' seconds
    private IEnumerator LerpShape(float startValue, float endValue, float duration)
    {
        float elapsed = 0;
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float value = Mathf.Lerp(startValue, endValue, elapsed / duration);
            bodySkinnedMeshRenderer.SetBlendShapeWeight(0, value);
            yield return null;
        }
    }

    //animate open and closed, then repeat
    public IEnumerator AnimateMouth(float TimeToTalk)
    {
        startTalking = true;

        StartCoroutine(TalkTime(TimeToTalk));

        while (startTalking == true)
        {
            yield return StartCoroutine(LerpShape(0, valueRange, duration));
            yield return StartCoroutine(LerpShape(valueRange, 0, duration));
        }
    }

    private IEnumerator TalkTime(float TalkTime)
    {
        yield return new WaitForSeconds(TalkTime);

        startTalking = false;
    }
}

例如在另一个脚本中使用它:

在顶部:

public PlayerMouthSpeechController blendShapeController;

StartCoroutine(blendShapeController.AnimateMouth(10f));

我希望我能以某种方式做到我不会每次都启动协程,它会自动启动协程,我只会这样做:

blendShapeController.AnimateMouth(10f);

它会在 PlayerMouthSpeechController 中启动协程。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    我想要的工作解决方案:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using TMPro;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class PlayerMouthSpeechController : MonoBehaviour
    {
        public TMP_Text[] texts;
        public float duration;
        [Range(0, 100)]
        public float valueRange;
    
        private bool startTalking = false;
        private SkinnedMeshRenderer bodySkinnedMeshRenderer;
    
        // Start is called before the first frame update
        void Start()
        {
            bodySkinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
        }
    
        // Update is called once per frame
        void Update()
        {
            
        }
    
        //Lerp between startValue and endValue over 'duration' seconds
        private IEnumerator LerpShape(float startValue, float endValue, float duration)
        {
            float elapsed = 0;
            while (elapsed < duration)
            {
                elapsed += Time.deltaTime;
                float value = Mathf.Lerp(startValue, endValue, elapsed / duration);
                bodySkinnedMeshRenderer.SetBlendShapeWeight(0, value);
                yield return null;
            }
        }
    
        //animate open and closed, then repeat
        public void AnimateMouth(float TimeToTalk)
        {
            StartCoroutine(StartAnimating(TimeToTalk));
        }
    
        private IEnumerator StartAnimating(float TimeToTalk)
        {
            startTalking = true;
    
            StartCoroutine(TalkingTime(TimeToTalk));
    
            while (startTalking == true)
            {
                yield return StartCoroutine(LerpShape(0, valueRange, duration));
                yield return StartCoroutine(LerpShape(valueRange, 0, duration));
            }
        }
    
        private IEnumerator TalkingTime(float TalkTime)
        {
            yield return new WaitForSeconds(TalkTime);
    
            startTalking = false;
        }
    }
    

    在其他脚本中做参考:

    public PlayerMouthSpeechController blendShapeController;
    

    开始

    blendShapeController.AnimateMouth(10f);
    

    【讨论】:

      猜你喜欢
      • 2013-07-07
      • 2020-04-12
      • 2017-12-11
      • 1970-01-01
      • 2021-10-24
      • 2021-12-30
      • 2016-03-18
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多