vFrame.UnityComponents provides a set of MonoBehaviour components that can be attached directly to GameObjects, extending Unity's built-in animation, audio, culling, timed invocation, and state snapshot capabilities.
- Provides named playback over Unity's legacy
Animationcomponent throughAnimationPlayer. - Provides
AnimatorExandTrailRendererExwith time-scale and pause/resume control. - Provides
AudioPlayerto unifyAudioSourceplayback, pause, mute, and completion callbacks. - Provides
MethodInvokerfor delayed invocation and looping invocation through coroutines. - Provides
CullingBehaviourandParticleCullingfor frustum visibility control based onCullingGroup. - Provides
GameObjectSnapshotBehaviourandGameObjectSnapshotRecursiveBehaviourto save and restore object state. - Includes built-in snapshot types:
TransformSnapshot,RendererEnableStateSnapshot,BehaviourEnableStateSnapshot, andParticleSystemEnableStateSnapshot. - Includes Editor inspectors and
ShowOnlyAttributeto make component inspection and setup easier in the Inspector.
- Unity
2018.4or newer, as declared inpackage.json - Verified and maintained in the current workspace with Unity
2022.3.62f3 - Runtime assembly
vFrame.UnityComponentsdepends onvFrame.CoreandvFrame.Core.Unity - Namespace:
vFrame.UnityComponents
Add the dependency to your project's Packages/manifest.json:
{
"dependencies": {
"com.vyronlee.vframe.unity-components": "https://github.com/VyronLee/vFrame.UnityComponents.git#1.0.1"
}
}You can also add the repository URL in Unity through Window > Package Manager > Add package from git URL....
If you use this library inside the vFrame workspace, make sure the following are available together:
Assets/vFrame.UnityComponents/vFrame.CorevFrame.Core.Unity
| Component | Description |
|---|---|
AnimationPlayer |
Maps custom string names to AnimationClip assets and supports playback, cross-fades, and waiting for completion |
AnimatorEx |
Controls Animator.speed by combining TimeScale and Speed |
AudioPlayer |
Wraps common AudioSource playback control and playback-finished callbacks |
TrailRendererEx |
Adds pause, resume, clear, and time-scale control to TrailRenderer |
MethodInvoker |
Provides coroutine scheduling APIs: Invoke, DelayInvoke, and LoopInvoke |
CullingBehaviour |
Inheritable culling base class using CullingGroup to detect visibility changes |
ParticleCulling |
Automatically starts and stops particle systems and renderers based on visibility |
GameObjectSnapshot |
Base class for snapshot implementations, defining Take() and Restore() |
GameObjectSnapshotBehaviour |
Captures and restores snapshots for a single GameObject according to configuration |
GameObjectSnapshotRecursiveBehaviour |
Recursively processes snapshots for the current object and all its children |
GameObjectSnapshotSettings |
ScriptableObject configuration base class that declares SnapshotTypes |
TransformSnapshot |
Stores active state, layer, tag, and local position/scale/rotation |
RendererEnableStateSnapshot |
Stores Renderer.enabled |
BehaviourEnableStateSnapshot |
Stores Behaviour.enabled state for all child behaviours |
ParticleSystemEnableStateSnapshot |
Stores ParticleSystem.emission.enabled |
ShowOnlyAttribute |
Inspector helper attribute for read-only field display |
The example below shows how to play an audio clip and execute a callback two seconds later:
using UnityEngine;
using vFrame.UnityComponents;
public class AudioPlayerExample : MonoBehaviour
{
[SerializeField] private AudioClip _clip;
private void Start()
{
var player = gameObject.AddComponent<AudioPlayer>();
var invoker = gameObject.AddComponent<MethodInvoker>();
player.SetClip(_clip);
player.Play(false, 1f, () => Debug.Log("Audio finished"));
invoker.DelayInvoke(2f, () => Debug.Log("2 seconds passed"));
}
}AnimationPlayer depends on Unity's legacy Animation component and uses an AnimationSet list to map names to clips.
using System.Collections;
using UnityEngine;
using vFrame.UnityComponents;
public class AnimationPlayerExample : MonoBehaviour
{
[SerializeField] private AnimationPlayer _player;
private IEnumerator Start()
{
if (_player.Play("Idle"))
{
yield return _player.CrossFadeUntilFinished("Attack");
_player.ForwardToEnd("Attack");
}
}
}Common members:
| Member | Description |
|---|---|
GetAnimation(string animationName) |
Gets the mapped AnimationClip |
Play(string animationName) |
Plays the specified animation and returns false if the name is not found |
PlayUntilFinished(string animationName) |
Plays and waits until completion |
CrossFade(string animationName) |
Cross-fades to the specified animation |
CrossFadeUntilFinished(string animationName) |
Cross-fades and waits until completion |
ForwardToEnd(string animationName) |
Samples directly to the end of the animation |
using UnityEngine;
using vFrame.UnityComponents;
public class TimeScaleExample : MonoBehaviour
{
[SerializeField] private AnimatorEx _animatorEx;
[SerializeField] private TrailRendererEx _trailRendererEx;
[SerializeField] private AudioPlayer _audioPlayer;
public void PauseEffects()
{
_animatorEx.TimeScale = 0f;
_trailRendererEx.Pause();
_audioPlayer.Pause();
}
public void ResumeEffects()
{
_animatorEx.TimeScale = 1f;
_trailRendererEx.UnPause();
_audioPlayer.UnPause();
}
}Additional notes:
AnimatorEx.SpeedandAnimatorEx.TimeScaleare multiplied together before being written toAnimator.speedTrailRendererEx.Clear()clears the current trail and restores timing parameters on the next frame- Both
AudioPlayer.Play()andAudioPlayer.Play(bool loop, float volume, Action onPlayFinished = null)requireAudioSource.clipto be assigned first
using UnityEngine;
using vFrame.UnityComponents;
public class MethodInvokerExample : MonoBehaviour
{
[SerializeField] private MethodInvoker _invoker;
private int _count;
private void Start()
{
_invoker.TimeScale = 1f;
_invoker.DelayInvoke(1f, () => Debug.Log("Delayed once"));
_invoker.LoopInvoke(0.5f, Tick, true);
}
private bool Tick()
{
_count++;
Debug.Log($"Tick {_count}");
return _count >= 5;
}
}When the callback passed to LoopInvoke returns true, the loop stops. The component also calls Stop() automatically in OnDisable() and OnDestroy().
using UnityEngine;
using vFrame.UnityComponents;
public class ParticleCullingExample : MonoBehaviour
{
[SerializeField] private ParticleCulling _particleCulling;
private void Awake()
{
_particleCulling.TargetCamera = Camera.main;
_particleCulling.AutoUpdate = true;
_particleCulling.onCullingStateChanged += isInvisible =>
Debug.Log($"Particle invisible: {isInvisible}");
}
}ParticleCulling derives from CullingBehaviour. When the object enters the view, it calls ParticleSystem.Play() and enables related Renderers; when it leaves the view, it calls ParticleSystem.Stop() and disables those renderers.
First, create a configuration asset derived from GameObjectSnapshotSettings and return the snapshot types to capture:
using System;
using System.Collections.Generic;
using UnityEngine;
using vFrame.UnityComponents;
[CreateAssetMenu(menuName = "vFrame/Snapshot Settings")]
public class ExampleSnapshotSettings : GameObjectSnapshotSettings
{
public override List<Type> SnapshotTypes => new List<Type>
{
typeof(TransformSnapshot),
typeof(RendererEnableStateSnapshot),
typeof(ParticleSystemEnableStateSnapshot)
};
}Then call it from a component:
using UnityEngine;
using vFrame.UnityComponents;
public class SnapshotExample : MonoBehaviour
{
[SerializeField] private GameObjectSnapshotBehaviour _snapshot;
public void SaveState()
{
_snapshot.Take();
}
public void RestoreState()
{
_snapshot.Restore();
}
}If you need to process the entire child hierarchy as well, use Take(), Restore(), and Clear() on GameObjectSnapshotRecursiveBehaviour.
AnimationPlayeruses Unity's legacyAnimation, notAnimatorAudioPlayerplayback with completion callbacks relies onUpdate()polling for the playback-finished stateCullingBehaviouris marked with[ExecuteInEditMode], but its runtime culling logic mainly targetsApplication.isPlayingGameObjectSnapshotBehaviourandGameObjectSnapshotRecursiveBehaviourdynamically add snapshot components at runtime and set theirhideFlagstoHideInInspector- The configuration entry point for the snapshot system is
GameObjectSnapshotSettings.SnapshotTypes - The package also includes an Editor assembly for Inspector and drawer support; runtime code lives under
Assets/vFrame.UnityComponents/Runtime/
This project is licensed under the Apache License 2.0.