Created
August 6, 2017 08:24
-
-
Save onionmk2/fa94769f8ad838d7086d40c8d82646ce to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEngine; | |
public class Blink : MonoBehaviour | |
{ | |
///<summary>まばたき間隔が、この値より大きいことを保証する。間隔保証不要なら0</summary> | |
private readonly float blinkMinInterval = 0; | |
private Animator animator; | |
private float eyeClosedTime; | |
private bool isRunning; | |
private float lastBlinkTime; | |
public List<AnimationClip> noBlinkAnimationClips; | |
private bool mustStopCoroutine; | |
private void Awake() | |
{ | |
animator = GetComponent<Animator>(); | |
animator.SetLayerWeight(AnimatorSettingConst.Alicia.LayerIndices.Face, 1); | |
} | |
private IEnumerator RandomCheck() | |
{ | |
var blinkPerSec = 10f / 60f; | |
var framePerSec = 1 / Time.deltaTime; | |
var framePerBlink = Mathf.FloorToInt(framePerSec / blinkPerSec); | |
// 第2引数はexclusiveのため、最大framePerBlinkの乱数を得るにはframePerBlink + 1を割り当てる。 | |
var rand = Random.Range(1, framePerBlink + 1); | |
while (rand != framePerBlink) | |
{ | |
rand = Random.Range(1, framePerBlink + 1); | |
yield return null; | |
} | |
} | |
private void Update() | |
{ | |
// set mustStopCoroutine true if current state of next state is one of noBlinkAnimationClips. | |
{ | |
var currentStates = animator.GetCurrentAnimatorClipInfo(AnimatorSettingConst.Alicia.LayerIndices.Face); | |
var nextStates = animator.GetNextAnimatorClipInfo(AnimatorSettingConst.Alicia.LayerIndices.Face); | |
var conflictCurrent = currentStates.Any(info => noBlinkAnimationClips.Contains(info.clip)); | |
var conflictNext = nextStates.Any(info => noBlinkAnimationClips.Contains(info.clip)); | |
if (conflictCurrent || conflictNext) mustStopCoroutine = true; | |
} | |
if (!isRunning) StartCoroutine(DoBlink()); | |
} | |
private IEnumerator DoBlink() | |
{ | |
isRunning = true; | |
yield return StartCoroutine(RandomCheck()); | |
yield return StartCoroutine(WaitMinInterval()); | |
lastBlinkTime = Time.time; | |
yield return StartCoroutine(CloseEye(Time.time, 0.05f)); | |
yield return StartCoroutine(OpenEye(eyeClosedTime, 0.05f)); | |
isRunning = false; | |
} | |
private IEnumerator WaitMinInterval() | |
{ | |
while (Time.time - lastBlinkTime < blinkMinInterval) | |
{ | |
yield return null; | |
} | |
} | |
private IEnumerator CloseEye(float startTime, float duration) | |
{ | |
var blinkRatio = animator.GetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink); | |
var isBlink1 = Mathf.Approximately(blinkRatio, 1); | |
while (!isBlink1) | |
{ | |
if (mustStopCoroutine) | |
{ | |
animator.SetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink, 0); | |
yield break; | |
} | |
var progressRatio = (Time.time - startTime) / duration; | |
var progressRation01 = Mathf.Clamp01(progressRatio); | |
animator.SetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink, progressRation01); | |
blinkRatio = animator.GetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink); | |
isBlink1 = Mathf.Approximately(blinkRatio, 1); | |
yield return null; | |
} | |
eyeClosedTime = Time.time; | |
} | |
private IEnumerator OpenEye(float startTime, float duration) | |
{ | |
var blinkRatio = animator.GetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink); | |
var isBlink0 = Mathf.Approximately(blinkRatio, 0); | |
while (!isBlink0) | |
{ | |
if (mustStopCoroutine) | |
{ | |
animator.SetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink, 0); | |
yield break; | |
} | |
var progressRatio = (Time.time - startTime) / duration; | |
var progressRation01 = 1f - Mathf.Clamp01(progressRatio); | |
animator.SetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink, progressRation01); | |
blinkRatio = animator.GetFloat(AnimatorSettingConst.Alicia.ParameterNames.blink); | |
isBlink0 = Mathf.Approximately(blinkRatio, 0); | |
yield return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
animator.GetFloat
SetFloat
をつかわない版は https://gist.github.com/onionmk2/82cf6de7303aaf276ee2dde4916d43f8 へ。