Hier das Script mit State-Auswertung in "PlayerAction" (unter Verwendung SpineBeginnerView), mein Hauptscript des Players (Leben-Counter und Collisions habe ich hier weggelassen), SpineBeginnerInput und SpineBeginnerModel liegen auch auf dem Player.
void Start()
{
bulletPrefab = GetComponent<Rigidbody2D>();
if (skeletonAnimation == null) return;
model.ShootEvent += PlayShoot;
model.StartAimEvent += StartPlayingAim;
model.StopAimEvent += StopPlayingAim;
skeletonAnimation.AnimationState.Event += HandleEvent;
isJumping = false;
inputESC = false;
bone = skeletonAnimation.Skeleton.FindBone(boneName);
}
void HandleEvent(Spine.TrackEntry trackEntry, Spine.Event e)
{
if (e.Data == footstepEvent.EventData)
PlayFootstepSound();
}
public void FixedUpdate()
{
rb.MovePosition(rb.position + move * speed * Time.fixedDeltaTime);
}
public void Update()
{
if (skeletonAnimation == null) return;
if (model == null) return;
move.x = joystick.Horizontal;
move.y = joystick.Vertical * jumpspeed;
if (Input.GetKeyDown(KeyCode.Escape))
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
if ((skeletonAnimation.skeleton.ScaleX < 0) != model.facingLeft)
{ // Detect changes in model.facingLeft
Turn(model.facingLeft);
}
var currentModelState = model.state;
if (previousViewState != currentModelState)
{
PlayNewStableAnimation();
}
previousViewState = currentModelState;
isJumping = false;
} // Update Ende
void PlayNewStableAnimation()
{
var newModelState = model.state;
//Animation nextAnimation;
// Add conditionals to not interrupt transient animations.
if (previousViewState == SpineBeginnerBodyState.Jumping && newModelState != SpineBeginnerBodyState.Jumping)
{
PlayFootstepSound();
}
if (newModelState == SpineBeginnerBodyState.Jumping)
{
jumpSource.Play();
skeletonAnimation.AnimationState.SetAnimation(0, jump, true);
}
else
{
if (newModelState == SpineBeginnerBodyState.Running)
{
//nextAnimation = run;
skeletonAnimation.AnimationState.SetAnimation(0, run, true);
}
else
{
//nextAnimation = idle;
skeletonAnimation.AnimationState.SetAnimation(0, idle, true);
}
}
}
void PlayFootstepSound()
{
footstepSource.Play();
footstepSource.pitch = GetRandomPitch(footstepPitchOffset);
}
[ContextMenu("Check Tracks")]
void CheckTracks()
{
var state = skeletonAnimation.AnimationState;
//Debug.Log(state.GetCurrent(0));
//Debug.Log(state.GetCurrent(1));
}
#region Transient Actions
public void PlayShoot()
{
// Play the shoot animation on track 1.
var shootTrack = skeletonAnimation.AnimationState.SetAnimation(1, shoot, false);
shootTrack.AttachmentThreshold = 1f;
shootTrack.MixDuration = 0f;
var empty1 = skeletonAnimation.state.AddEmptyAnimation(1, 0.5f, 0.1f);
empty1.AttachmentThreshold = 1f;
// Update skeleton to apply animations
skeletonAnimation.Update(0);
boneFollower = GetComponent<BoneFollower>();
// Play the aim animation on track 2 to aim at the mouse target.
var aimTrack = skeletonAnimation.AnimationState.SetAnimation(2, aim, false);
aimTrack.AttachmentThreshold = 1f;
aimTrack.MixDuration = 0f;
var empty2 = skeletonAnimation.state.AddEmptyAnimation(2, 0.5f, 0.1f);
empty2.AttachmentThreshold = 1f;
gunSource.pitch = GetRandomPitch(gunsoundPitchOffset);
gunSource.Play();
//gunParticles.randomSeed = (uint)Random.Range(0, 100);
gunParticles.Play();
// Attack();
}
public class QuitOnClick : MonoBehaviour
{ public void Quit()
{
//Spiel beenden
//Debug.Log("Spiel beendet");
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
public void StartPlayingAim()
{
// Play the aim animation on track 2 to aim at the mouse target.
var aimTrack = skeletonAnimation.AnimationState.SetAnimation(2, aim, true);
aimTrack.AttachmentThreshold = 1f;
aimTrack.MixDuration = 0f;
}
public void StopPlayingAim()
{
var empty2 = skeletonAnimation.state.AddEmptyAnimation(2, 0.5f, 0.1f);
empty2.AttachmentThreshold = 1f;
}
public void Turn(bool facingLeft)
{
skeletonAnimation.Skeleton.ScaleX = facingLeft ? -1f : 1f;
// Maybe play a transient turning animation too, then call ChangeStableAnimation.
}
#endregion
#region Utility
public float GetRandomPitch(float maxPitchOffset)
{
return 1f + Random.Range(-maxPitchOffset, maxPitchOffset);
}
#endregion
}
"SpineboyBeginerInput"
public void OnValidate()
{
if (skeletonAnimation == null) skeletonAnimation = GetComponent<SkeletonAnimation>();
if (model == null) model = GetComponent<SpineboyBeginnerModel>();
}
#endregion
private void Start()
{
rb = GetComponent<Rigidbody2D>();
bone = skeletonAnimation.Skeleton.FindBone(boneName);
}
public void FixedUpdate()
{
//rb.MovePosition(rb.position + move * speed * Time.fixedDeltaTime);
}
public void Update()
{
if (model == null) return;
currentHorizontal = joystick.Horizontal;
model.TryMove(currentHorizontal);
mousePosition = Input.mousePosition;
//Touch touch = Input.GetTouch(0);
if (Input.touchCount > 0)
{
//Debug.Log("Input: Touch - " + touch.position);
touch = Input.GetTouch(0);
dz++;
PlayerPrefs.SetInt("Touches", dz);
}
else { return; }
if (Input.touchCount < 0 || touch.phase != TouchPhase.Began)
{ return; }
if (IsPointerOverGameObject())
{
// keine shooting
}
else
{
mousePosition = Input.mousePosition;
worldMousePosition = camera.ScreenToWorldPoint(mousePosition);
var skeletonSpacePoint = skeletonAnimation.transform.InverseTransformPoint(worldMousePosition);
skeletonSpacePoint.x *= skeletonAnimation.Skeleton.ScaleX;
skeletonSpacePoint.y *= skeletonAnimation.Skeleton.ScaleY;
bone.SetLocalPosition(skeletonSpacePoint);
model.TryShoot();
}
}
// regelt den Touch über dem Joystick
public bool IsPointerOverGameObject()
{
if (EventSystem.current.IsPointerOverGameObject())
{
return true;
}
// Check touches
for (int i = 0; i < Input.touchCount; i++)
{
var touch = Input.GetTouch(i);
if (touch.phase == TouchPhase.Began)
{
if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
{
return true;
}
}
}
return false;
}
}