In case anyone has the same requirements, paste my demo code here:
/// owl will follow the target.
using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
using Spine.Unity;
using Spine;
public class OwlController : MonoBehaviour {
public string skeletonName = "owl-pro";
public SkeletonGraphic skeletonGraphic;
public GameObject target;
public TextAsset skeletonJson;
public TextAsset atlasText;
public Texture2D[] textures;
public Material materialPropertySource;
SpineAtlasAsset runtimeAtlasAsset;
SkeletonDataAsset runtimeSkeletonDataAsset;
SkeletonData skeletonData;
Spine.TrackEntry left;
Spine.TrackEntry right;
Spine.TrackEntry up;
Spine.TrackEntry down;
Spine.AnimationState state;
Skeleton skeleton;
Vector2 parentSize;
float halfX, halfY;
float leftX, rightX, upY, downY;
void OnValidate () {
if (skeletonGraphic == null) skeletonGraphic = GetComponent<SkeletonGraphic>();
}
void Start () {
LoadSkeletonData();
Vector2 parentSize = transform.parent.GetComponent<RectTransform>().rect.size;
halfX = parentSize.x / 2;
halfY = parentSize.y / 2;
}
void Update () {
if (target == null) {
if (left.Alpha != 0 || right.Alpha != 0 || up.Alpha != 0 || down.Alpha != 0) {
left.Alpha = 0;
right.Alpha = 0;
up.Alpha = 0;
down.Alpha = 0;
skeletonGraphic.Skeleton = new Skeleton(skeletonData);
skeletonGraphic.Update(Time.deltaTime);
}
return;
}
var parent = transform.parent;
Vector3 targetPos = target.transform.position;
Vector3 localPos = transform.parent.InverseTransformPoint(targetPos);
float x = localPos.x;
float y = localPos.y;
left.Alpha = (x > 0) ? math.clamp(x / halfX, 0f, 1f): 0;
right.Alpha = (x < 0) ? math.clamp(1 - (halfX + x) / halfX, 0f, 1f): 0;
up.Alpha = (y > 0) ? math.clamp(y / halfY, 0f, 1f): 0;
down.Alpha = (y < 0) ? math.clamp(1 - (halfY + y) / halfY, 0f, 1f): 0;
skeletonGraphic.Skeleton = new Skeleton(skeletonData);
skeletonGraphic.Update(Time.deltaTime);
}
void LoadSkeletonData()
{
if (skeletonJson == null || atlasText == null)
{
Debug.LogError("can not load Spine resource file");
return;
}
runtimeAtlasAsset = SpineAtlasAsset.CreateRuntimeInstance(atlasText, textures, materialPropertySource, true, null);
runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true, 0.025f);
if (runtimeSkeletonDataAsset == null)
{
Debug.LogError("can not parse SkeletonData");
return;
}
skeletonData = runtimeSkeletonDataAsset.GetSkeletonData(false);
skeleton = new Skeleton(skeletonData);
skeletonGraphic.skeletonDataAsset = runtimeSkeletonDataAsset;
skeletonGraphic.Initialize(true);
state = skeletonGraphic.AnimationState;
state.SetAnimation(0, "idle", true);
state.SetAnimation(1, "blink", true);
left = state.SetAnimation(2, "left", true);
right = state.SetAnimation(3, "right", true);
up = state.SetAnimation(4, "up", true);
down = state.SetAnimation(5, "down", true);
left.MixBlend = MixBlend.Add;
right.MixBlend = MixBlend.Add;
up.MixBlend = MixBlend.Add;
down.MixBlend = MixBlend.Add;
left.Alpha = 0;
right.Alpha = 0;
up.Alpha = 0;
down.Alpha = 0;
}
}
`