There are a lot of threads on similar topics that I have read through today, none of which have seamed to provide an answer to my issue. Hopefully it’s something minor I’ve overlooked and maybe some fresh eyes can help me out. I’m working on a project for an interactive art installation in which people will be encountering virtual characters on a large video wall. I am creating a master of ceremonies character who’s role is to address people near the space when activity is low to entice them to interact with it. He walks on from the edge of the stage and idles for a duration until he plays some voice over (“step right up!” etc) along with a gestural movement and some additive jaw flapping to accompany the audio. Everything currently works EXCEPT the jaw flapping.
The jaw flapping animation is quite simple. It’s a single looping down-up motion of the characters jaw, so that we can loop it for the entire duration of whatever audio clip is playing. It has more than one frame, so I think it’s fairly safe to rule out this reason. When it plays, I see no jaw movement at all. I have dragged the FBX with the associated jaw movement animation into the scene and tested it, and it animates fine. It’s specifically an issue with doing an additive blend.
Here is the code used to control this character’s behavior:
using UnityEngine;
using System.Collections;
public class MCController : MonoBehaviour {
/*
MCController.cs
by Aaron Siegel, 10-21-10
Controls the MC character to interact with people passing by.
Look follows the latest track to be picked up by PersonTracker.
Occasionally talks with a looping mouth-movement animation the duration of each audio clip.
Gestures to the stars when talking to people.
*/
private Transform target;
private Person targetPerson;
public float talkMinimumFrequency;
public float talkMaximumFrequency;
public AudioClip[] voiceOverClips;
public Transform exitPoof;
private int currentAudioClip;
private float talkFrequency; // delay between when he speaks
private float lastTalkStarted; // time last audio bit began
private float lastTalkEnded; // time last audio bit finished
private float talkDuration; // current audio bit length
private bool talking = false;
private bool removeWhenReady = false;
private float exitStart;
void Start () {
animation["Idle"].wrapMode = WrapMode.Loop;
animation["TalkShort"].wrapMode = WrapMode.Loop;
animation["TalkShort"].layer = 10;
animation["TalkShort"].blendMode = AnimationBlendMode.Additive;
animation["TalkShort"].weight = 1.0f;
talkFrequency = Random.Range(talkMinimumFrequency, talkMaximumFrequency);
lastTalkEnded = Time.time;
currentAudioClip = 0;
}
void Update () {
// check to see if the entrance animation is finished
if(animation["Entrance"].length - animation["Entrance"].time < 0.5f){
// crossfade into Idle
animation.CrossFade("Idle");
}
// if it's been the wait duration since the last voice over...
if(Time.time - lastTalkEnded > talkFrequency !talking){
print("spoony talking");
if(Random.value > 0.5f){
animation.CrossFade("Invite1");
} else {
animation.CrossFade("Invite2");
}
animation.CrossFade("TalkShort") ;
AudioSource.PlayClipAtPoint(voiceOverClips[currentAudioClip], transform.position);
talkDuration = voiceOverClips[currentAudioClip].length;
currentAudioClip++;
if(currentAudioClip == voiceOverClips.Length){
currentAudioClip = 0;
}
talking = true;
lastTalkStarted = Time.time;
}
// if MC is talking and it's been the whole duration of the voice over clip...
if(Time.time - lastTalkStarted > talkDuration talking){
print("spoony stopped talking");
animation.Stop("TalkShort");
talkFrequency = Random.Range(talkMinimumFrequency, talkMaximumFrequency);
talking = false;
lastTalkEnded = Time.time;
}
if(animation.IsPlaying("Invite1") animation["Invite1"].length - animation["Invite1"].time < 0.5f){
animation.CrossFade("Idle");
} else if(animation.IsPlaying("Invite2") animation["Invite2"].length - animation["Invite2"].time < 0.5f){
animation.CrossFade("Idle");
}
// remove spoony when exit animation finishes
if(removeWhenReady Time.time - exitStart > animation["Exit"].length){
destroy();
}
}
void LateUpdate() {
if(target != null){
// look out-the-screen towards the latest person (track) discovered by tyzx
((HeadLookController)gameObject.GetComponent(typeof(HeadLookController))).target = target.position;
}
}
public void setTarget(Person p){
targetPerson = p;
}
public void remove(){
// play exit animation
//print(Time.time +" starting exit animation");
animation.CrossFade("Exit", 0.1f);
exitStart = Time.time;
removeWhenReady = true;
}
public void destroy(){
if(exitPoof != null){
Vector3 particlePos = transform.position;
particlePos.z -= 0.25f;
particlePos.y += 0.8f;
Instantiate(exitPoof, particlePos, new Quaternion(0,0,0,0));
}
//print(Time.time +" removing spoony");
Component[] renderers = gameObject.GetComponentsInChildren(typeof(Renderer));
foreach(Renderer childRenderer in renderers){
Destroy(childRenderer.material); // remove child materials
}
Destroy(gameObject);
}
}