IndieDoroid

Hi guys,

I noticed that my spine animations play off screen (UI animations), even when the camera isn't focused on it.

Is there a smart way to put those animations "to sleep" besides making those gameobjects.setactive(false) ? :)

Thanks
Аватара пользователя
IndieDoroid
  • Сообщения: 154

Harald

You can disable the SkeletonRenderer component (typically SkeletonAnimation or SkeletonMecanim). Then any other game logic at the GameObject will remain active.
Аватара пользователя
Harald

Harri
  • Сообщения: 1976

Spiral Circus

Here's a MonoBehaviour script you can attach to a spine object that will turn on/off animations as soon as the renderer is visible / invisible to any cameras.

Note, this may look like it's not working in the editor since the editor scene camera also counts towards visibility so the callbacks are not always raised as you might expect from looking at the game view.
using Spine.Unity;
using UnityEngine;

[RequireComponent(typeof(Renderer), typeof(SkeletonAnimation))]
public class SpineFrustrumCullSkeletonAnimation : MonoBehaviour
{
SkeletonAnimation _anim;

void Start()
{
_anim = GetComponent<SkeletonAnimation>();
_anim.enabled = GetComponent<Renderer>().isVisible;
}

void OnBecameVisible() => _anim.enabled = true;

void OnBecameInvisible() => _anim.enabled = false;
}
Spiral Circus
  • Сообщения: 21

Harald

@Spiral_Circus Thanks very much for sharing! Much appreciated!

Please note that this will have some limitations:
As opposed to a custom bounding-box based solution, this will incorrectly cull when e.g. a single animation frame disables all attachments or moves vertices off-screen. When following frames would make parts visible again, it will not count as visible and stick to keeping it disabled instead.

---

I just thought about providing two-step culling:
1. only disabling mesh generation (vertex updates) but keeping the animations and the timing running,
2. disabling animation and mesh generation completely

I have opened an issue ticket here for you to subscribe to get notifications on any progress:
[unity] Provide two step frustum culling at `SkeletonRenderer` · #1595
Аватара пользователя
Harald

Harri
  • Сообщения: 1976

Spiral Circus

Perfect, yeah I never thought about those edge cases, i guess i've never seen it come up where I've been using it but it's good to know to watch out for. Rolling this into the SkeletonAnimation component directly would be really useful.
Spiral Circus
  • Сообщения: 21

IndieDoroid

Spiral Circus писал(а):Here's a MonoBehaviour script you can attach to a spine object that will turn on/off animations as soon as the renderer is visible / invisible to any cameras.

Note, this may look like it's not working in the editor since the editor scene camera also counts towards visibility so the callbacks are not always raised as you might expect from looking at the game view.
using Spine.Unity;
using UnityEngine;

[RequireComponent(typeof(Renderer), typeof(SkeletonAnimation))]
public class SpineFrustrumCullSkeletonAnimation : MonoBehaviour
{
SkeletonAnimation _anim;

void Start()
{
_anim = GetComponent<SkeletonAnimation>();
_anim.enabled = GetComponent<Renderer>().isVisible;
}

void OnBecameVisible() => _anim.enabled = true;

void OnBecameInvisible() => _anim.enabled = false;
}
I was thinking about something like this too, but wasn't sure if it would cause issue with rendering sequences.

Thanks for the code suggestion

---

Harald писал(а):@Spiral_Circus Thanks very much for sharing! Much appreciated!

Please note that this will have some limitations:
As opposed to a custom bounding-box based solution, this will incorrectly cull when e.g. a single animation frame disables all attachments or moves vertices off-screen. When following frames would make parts visible again, it will not count as visible and stick to keeping it disabled instead.

---

I just thought about providing two-step culling:
1. only disabling mesh generation (vertex updates) but keeping the animations and the timing running,
2. disabling animation and mesh generation completely

I have opened an issue ticket here for you to subscribe to get notifications on any progress:
[unity] Provide two step frustum culling at `SkeletonRenderer` · #1595
Thanks @Harald
I've got like 15 characters all animating off camera, but get called for certain situations. So your 1st option of "disabling mesh only, but keeping animations running" would be useful.

Much appreciated!
Аватара пользователя
IndieDoroid
  • Сообщения: 154

Spiral Circus

Just thinking about rolling my own custom bounding box culler. Is there a way to access the "largest possible bounding box" through SkeletonAnimation.cs ?

I'm asking to prevent myself from leaving open the same edge case where animations the animation itself could take the mesh off screen, but shouldn't be culled because it's about to come back on screen in a few frames.
Spiral Circus
  • Сообщения: 21

Jamez0r

Spiral Circus писал(а):Just thinking about rolling my own custom bounding box culler. Is there a way to access the "largest possible bounding box" through SkeletonAnimation.cs ?

I'm asking to prevent myself from leaving open the same edge case where animations the animation itself could take the mesh off screen, but shouldn't be culled because it's about to come back on screen in a few frames.
I don't know of any way of telling what the largest possible bounding box is.

What I do is add a buffer-distance to the bounding box when deciding whether or not the animations should be culled, and then based on my knowledge of the character's extents I set that buffer. So if a character doesn't move much, the buffer distance can be small, but if the character has a spear that he stabs out really far, I'd make the buffer larger in that direction

Here is the code, if you want to implement it I suggest understanding what it does and then re-writing it to fit your needs.

"renderer" is set to the mesh renderer
"SHOULD_BE_UPDATED" is just a bool that gets set to false initially and then tests to see if the thing is close enough to the camera's view to update it or not. So I use the value of SHOULD_BE_UPDATED to enable/disable the animation.
public void UpdateOffscreenTest() {

SHOULD_BE_UPDATED = false;

//Check if its within regular view based on the renderer
if (renderer.isVisible == true) { SHOULD_BE_UPDATED = true; return;}

//Check if its outside the camera's view + buffer distance
if(CameraController.Instance != null) {
if (renderer.bounds.max.x + cullBufferDistance < CameraController.Instance.cameraRect.xMin) { return; }
if (renderer.bounds.min.x - cullBufferDistance > CameraController.Instance.cameraRect.xMax) { return; }
if (renderer.bounds.max.y + cullBufferDistance < CameraController.Instance.cameraRect.yMin) { return; }
if (renderer.bounds.min.y - cullBufferDistance > CameraController.Instance.cameraRect.yMax) { return; }
}

//We now know that its within the camera's view + buffer distance
SHOULD_BE_UPDATED = true;
}
Note: instead of using a singular "cullBufferDistance", you could further customize it into: maxX, minX, maxY, minY for each of the direction checks

Note 2: Should have mentioned it earlier, but the purpose of this is to have a buffer area thats outside of the camera's view where the Spine Animation will start animating again before the Spine Animation comes within the cameras view

Note 3: This is how my cameraRect is set. It is called every frame on my camera object:
public void UpdateMainCameraRect() {

float height = Camera.main.orthographicSize * 2.0f;
float width = height * Screen.width / Screen.height;

cameraRect.Set(Camera.main.transform.position.x - width / 2f,
Camera.main.transform.position.y - height / 2f,
width,
height);
}
Note 4: All of this is assuming your Unity project is 2D ;)
Аватара пользователя
Jamez0r
  • Сообщения: 162

Spiral Circus

@Jamez0r thanks. I have a system like this for LODing and culling AI calculations so I can probably hook into that for renderering too.
Spiral Circus
  • Сообщения: 21

Harald

Thanks again very much @Jamez0r for answering and sharing the code!

As @Jamez0r already pointed out, swapping out attachments can swap a small dagger with a long spear, rendering any pre-computed boxes obsolete.
Аватара пользователя
Harald

Harri
  • Сообщения: 1976

IndieDoroid

Hi @Harald,

I just noticed you updated the Git task a while back, regarding animation optimization. This is super awesome!
[unity] Provide two step frustum culling at `SkeletonRenderer` · #1595

Is there any documentation that teaches us how to access the 3 options? :)
    No culling
    Continue animation but disable mesh generation
    Don't animate

Thanks for the help!
Аватара пользователя
IndieDoroid
  • Сообщения: 154

Harald

I'm sorry to say that we did not yet get to implement this task. So currently you cannot access these 3 options.
Аватара пользователя
Harald

Harri
  • Сообщения: 1976

IndieDoroid

Oh. Darn that's too bad.

Ok well hope we can get some news on it at some point. :)
Аватара пользователя
IndieDoroid
  • Сообщения: 154

Harald

We can gladly announce that this feature has just been implemented. 8)

From the changelog:
Added frustum culling update mode parameters Update When Invisible (Inspector parameter) and UpdateMode (available via code) to all Skeleton components. This provides a simple way to disable certain updates when the Renderer is no longer visible (outside all cameras, culled in frustum culling). The new UpdateMode property allows disabling updates at a finer granularity level than disabling the whole component. Available modes are: Nothing, OnlyAnimationStatus, EverythingExceptMesh and FullUpdate.
A new 3.8 unitypackage is available for download here as usual:
Spine Unity Download

Hope you like it!
Аватара пользователя
Harald

Harri
  • Сообщения: 1976

IndieDoroid

Harald писал(а):We can gladly announce that this feature has just been implemented. 8)

From the changelog:
Added frustum culling update mode parameters Update When Invisible (Inspector parameter) and UpdateMode (available via code) to all Skeleton components. This provides a simple way to disable certain updates when the Renderer is no longer visible (outside all cameras, culled in frustum culling). The new UpdateMode property allows disabling updates at a finer granularity level than disabling the whole component. Available modes are: Nothing, OnlyAnimationStatus, EverythingExceptMesh and FullUpdate.
A new 3.8 unitypackage is available for download here as usual:
Spine Unity Download

Hope you like it!
Thanks so much Harald! Can't wait to try it out!

Everyone is going to want to take advantage of this performance boost!
Аватара пользователя
IndieDoroid
  • Сообщения: 154

Harald

Thanks for your kind feedback!
IndieDoroid писал(а):Everyone is going to want to take advantage of this performance boost!
We hope so! :)
Аватара пользователя
Harald

Harri
  • Сообщения: 1976


Вернуться в Unity