【发布时间】: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 中启动协程。
【问题讨论】: