Hi Harald, thanks, that worked, but now I'm getting this:
Assets/_BITFAIN/Scripts/CharacterAnimationController.cs(57,53): error CS1061: 'SkeletonGraphic' does not contain a definition for 'AnimationState' and no accessible extension method 'AnimationState' accepting a first argument of type 'SkeletonGraphic' could be found (are you missing a using directive or an assembly reference?)
My code:
`using Spine.Unity;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BitFain
{
public class CharacterAnimationController : MonoBehaviour
{
#region Inspector
// [SpineAnimation] attribute allows an Inspector dropdown of Spine animation names coming form SkeletonAnimation.
[SpineAnimation]
public string idleAnimation;
[SpineAnimation]
public string happyAnimation;
[SpineAnimation]
public string sadAnimation;
[SpineAnimation]
public string talkAnimation;
[SpineAnimation]
public string phonePointingAnimation;
[SpineAnimation]
public string okeyAnimation;
public float randomAnimDuration = 2.5f;
public SkeletonGraphic skeletonAnimation;
[Header("Sunete disponibile")]
public List<AudioClip> soundClips;
public AudioClip loveSound;
public AudioClip auAuAuSound;
public AudioClip itiDau100Sound;
public AudioClip powerUpSound;
public AudioClip topulDePeLumeSound;
private AudioSource audioSource;
#endregion
// Spine.AnimationState and Spine.Skeleton are not Unity-serialized objects. You will not see them as fields in the inspector.
public Spine.AnimationState spineAnimationState;
public Spine.Skeleton skeleton;
void Start()
{
//skeletonAnimation = GetComponent<SkeletonAnimation>();
spineAnimationState = skeletonAnimation.AnimationState;
skeleton = skeletonAnimation.Skeleton;
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
}
StartCoroutine(DoDemoRoutine());
}
public void VorbesteCaracter()
{
StartCoroutine(VorbesteCaracterAcum());
}
private IEnumerator VorbesteCaracterAcum()
{
AudioClip selectedClip = soundClips[2];
PlayClip(selectedClip);
if (selectedClip != null)
{
spineAnimationState.SetAnimation(0, okeyAnimation, false);
//Debug.Log("Current animation name: " + talkAnimation);
yield return new WaitForSeconds(selectedClip.length);
}
else
{
// fallback în caz că nu e sunet
yield return new WaitForSeconds(0.6f);
}
spineAnimationState.SetAnimation(0, idleAnimation, true);
yield return new WaitForSeconds(0.1f);
Debug.Log("CARACTERUL A VORBIT!");
StopCoroutine(VorbesteCaracterAcum());
}
IEnumerator DoDemoRoutine()
{
while (true)
{
// SetAnimation is the basic way to set an animation.
// SetAnimation sets the animation and starts playing it from the beginning.
// Common Mistake: If you keep calling it in Update, it will keep showing the first pose of the animation, do don't do that.
spineAnimationState.SetAnimation(0, idleAnimation, true);
//Debug.Log("Current animation name: " + idleAnimation);
yield return new WaitForSeconds(randomAnimDuration);
spineAnimationState.SetAnimation(0, happyAnimation, true);
//Debug.Log("Current animation name: " + happyAnimation);
yield return new WaitForSeconds(randomAnimDuration);
//spineAnimationState.SetAnimation(0, idleAnimation, true);
//Debug.Log("Current animation name: " + idleAnimation);
//yield return new WaitForSeconds(randomAnimDuration);
// Alege și redă un sunet aleatoriu, returnând durata lui
AudioClip selectedClip = PlayRandomSoundAndReturnClip();
if (selectedClip != null)
{
spineAnimationState.SetAnimation(0, talkAnimation, false);
//Debug.Log("Current animation name: " + talkAnimation);
yield return new WaitForSeconds(selectedClip.length + 0.2f);
}
else
{
// fallback în caz că nu e sunet
yield return new WaitForSeconds(0.6f);
}
spineAnimationState.SetAnimation(0, idleAnimation, true);
//Debug.Log("Current animation name: " + idleAnimation);
yield return new WaitForSeconds(randomAnimDuration);
// AddAnimation queues up an animation to play after the previous one ends.
//spineAnimationState.SetAnimation(0, happyAnimation, false);
//spineAnimationState.AddAnimation(0, idleAnimation, true, 0);
yield return new WaitForSeconds(1f);
AudioClip selectedClip2 = soundClips[7];
if (selectedClip2 != null)
{
PlayClip(selectedClip2);
spineAnimationState.SetAnimation(0, phonePointingAnimation, true);
//Debug.Log("Current animation name: " + talkAnimation);
yield return new WaitForSeconds(selectedClip2.length + 1.5f);
}
else
{
// fallback în caz că nu e sunet
yield return new WaitForSeconds(0.6f);
}
//spineAnimationState.SetAnimation(0, okeyAnimation, true);
//yield return new WaitForSeconds(randomAnimDuration);
spineAnimationState.SetAnimation(0, idleAnimation, true);
yield return new WaitForSeconds(1.0f);
//skeleton.ScaleX = -1; // skeleton allows you to flip the skeleton.
//Debug.Log("Ne-am intors invers");
//yield return new WaitForSeconds(5.5f);
//skeleton.ScaleX = 1;
//Debug.Log("Ne-am intors normal");
}
}
public void PlayRandomSound()
{
if (soundClips == null || soundClips.Count == 0)
{
Debug.LogWarning("Lista de sunete este goală!");
return;
}
int randomIndex = Random.Range(0, soundClips.Count);
AudioClip selectedClip = soundClips[randomIndex];
audioSource.PlayOneShot(selectedClip);
Debug.Log("Redat sunetul: " + selectedClip.name + " (index " + randomIndex + ")");
}
public AudioClip PlayRandomSoundAndReturnClip()
{
if (soundClips == null || soundClips.Count == 0)
{
Debug.LogWarning("Lista de sunete este goală!");
return null;
}
int randomIndex = Random.Range(0, soundClips.Count - 1); //am pus minu unu ca sa nu avem sunetul cu topul de pe lume
AudioClip selectedClip = soundClips[randomIndex];
audioSource.PlayOneShot(selectedClip);
//Debug.Log("Redat sunetul: " + selectedClip.name + " (index " + randomIndex + ")");
return selectedClip;
}
private void PlayClip(AudioClip clip)
{
if (clip != null)
{
audioSource.PlayOneShot(clip);
}
else
{
Debug.LogWarning("Clipul nu este setat!");
}
}
}
}`