AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Tools Unity Cinemachine

skill-tjboudreaux-cc-plugin-unity-gamedev-tools-unity-cinemachine · by tjboudreaux

Unity Cinemachine camera system patterns including virtual cameras, blending, and state-driven cameras.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-tjboudreaux-cc-plugin-unity-gamedev-tools-unity-cinemachine

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-tjboudreaux-cc-plugin-unity-gamedev-tools-unity-cinemachine)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
6mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Tools Unity Cinemachine? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Unity Cinemachine

Overview

Cinemachine is Unity's camera system for dynamic, procedural camera behavior. This skill covers common patterns for gameplay cameras, cutscenes, and camera effects.

When to Use

  • Third-person cameras
  • Combat camera behavior
  • Cutscene cameras
  • Camera shake effects
  • Multi-target framing
  • State-driven camera transitions

Basic Setup

Virtual Camera Configuration

using Cinemachine;

public class CameraController : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _mainCamera;
    [SerializeField] private Transform _followTarget;
    [SerializeField] private Transform _lookAtTarget;
    
    private void Start()
    {
        _mainCamera.Follow = _followTarget;
        _mainCamera.LookAt = _lookAtTarget;
    }
    
    public void SetFollowTarget(Transform target)
    {
        _mainCamera.Follow = target;
    }
    
    public void SetLookAtTarget(Transform target)
    {
        _mainCamera.LookAt = target;
    }
}

Third Person Camera

public class ThirdPersonCameraSetup : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _virtualCamera;
    
    private Cinemachine3rdPersonFollow _bodyComponent;
    private CinemachineComposer _aimComponent;
    
    private void Awake()
    {
        _bodyComponent = _virtualCamera.GetCinemachineComponent();
        _aimComponent = _virtualCamera.GetCinemachineComponent();
    }
    
    public void SetCameraDistance(float distance)
    {
        if (_bodyComponent != null)
        {
            _bodyComponent.CameraDistance = distance;
        }
    }
    
    public void SetShoulderOffset(Vector3 offset)
    {
        if (_bodyComponent != null)
        {
            _bodyComponent.ShoulderOffset = offset;
        }
    }
    
    public void SetDamping(float damping)
    {
        if (_bodyComponent != null)
        {
            _bodyComponent.Damping.x = damping;
            _bodyComponent.Damping.y = damping;
            _bodyComponent.Damping.z = damping;
        }
    }
}

Camera Blending

Priority-Based Switching

public class CameraPriorityManager : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _explorationCamera;
    [SerializeField] private CinemachineVirtualCamera _combatCamera;
    [SerializeField] private CinemachineVirtualCamera _dialogueCamera;
    
    private const int InactivePriority = 0;
    private const int ActivePriority = 10;
    
    private void Start()
    {
        SetExplorationCamera();
    }
    
    public void SetExplorationCamera()
    {
        _explorationCamera.Priority = ActivePriority;
        _combatCamera.Priority = InactivePriority;
        _dialogueCamera.Priority = InactivePriority;
    }
    
    public void SetCombatCamera()
    {
        _explorationCamera.Priority = InactivePriority;
        _combatCamera.Priority = ActivePriority;
        _dialogueCamera.Priority = InactivePriority;
    }
    
    public void SetDialogueCamera()
    {
        _explorationCamera.Priority = InactivePriority;
        _combatCamera.Priority = InactivePriority;
        _dialogueCamera.Priority = ActivePriority;
    }
}

Custom Blend Settings

public class CameraBlendController : MonoBehaviour
{
    [SerializeField] private CinemachineBrain _brain;
    
    public void SetBlendTime(float duration)
    {
        _brain.m_DefaultBlend.m_Time = duration;
    }
    
    public void SetBlendStyle(CinemachineBlendDefinition.Style style)
    {
        _brain.m_DefaultBlend.m_Style = style;
    }
    
    public void SetInstantBlend()
    {
        _brain.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.Cut;
    }
    
    public void SetSmoothBlend(float duration = 1f)
    {
        _brain.m_DefaultBlend.m_Style = CinemachineBlendDefinition.Style.EaseInOut;
        _brain.m_DefaultBlend.m_Time = duration;
    }
}

State-Driven Camera

Animator State Camera

public class StateDrivenCameraController : MonoBehaviour
{
    [SerializeField] private CinemachineStateDrivenCamera _stateDrivenCamera;
    [SerializeField] private Animator _animator;
    
    private void Start()
    {
        // Animator is automatically linked via CinemachineStateDrivenCamera inspector
        // States are mapped to virtual cameras in the component
    }
    
    public void TriggerCameraState(string animatorStateName)
    {
        // Triggering animator state will automatically switch camera
        _animator.CrossFade(animatorStateName, 0.2f);
    }
}

Manual State Switching

public class GameStateCameraManager : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera[] _cameras;
    
    private Dictionary _cameraMap;
    
    private void Awake()
    {
        _cameraMap = new Dictionary
        {
            { GameState.Exploration, _cameras[0] },
            { GameState.Combat, _cameras[1] },
            { GameState.Dialogue, _cameras[2] },
            { GameState.Cinematic, _cameras[3] }
        };
    }
    
    public void OnGameStateChanged(GameState newState)
    {
        foreach (var cam in _cameras)
        {
            cam.Priority = 0;
        }
        
        if (_cameraMap.TryGetValue(newState, out var activeCamera))
        {
            activeCamera.Priority = 10;
        }
    }
}

Camera Shake

Impulse System

public class CameraShakeController : MonoBehaviour
{
    [SerializeField] private CinemachineImpulseSource _impulseSource;
    [SerializeField] private CinemachineImpulseDefinition _lightImpulse;
    [SerializeField] private CinemachineImpulseDefinition _heavyImpulse;
    
    public void LightShake()
    {
        _impulseSource.m_ImpulseDefinition = _lightImpulse;
        _impulseSource.GenerateImpulse();
    }
    
    public void HeavyShake()
    {
        _impulseSource.m_ImpulseDefinition = _heavyImpulse;
        _impulseSource.GenerateImpulse();
    }
    
    public void ShakeWithVelocity(Vector3 velocity)
    {
        _impulseSource.GenerateImpulse(velocity);
    }
    
    public void DirectionalShake(Vector3 direction, float force)
    {
        _impulseSource.GenerateImpulse(direction.normalized * force);
    }
}

Noise-Based Shake

public class ContinuousShakeController : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _virtualCamera;
    
    private CinemachineBasicMultiChannelPerlin _noise;
    
    private void Awake()
    {
        _noise = _virtualCamera.GetCinemachineComponent();
    }
    
    public void SetShakeIntensity(float amplitude, float frequency)
    {
        if (_noise != null)
        {
            _noise.m_AmplitudeGain = amplitude;
            _noise.m_FrequencyGain = frequency;
        }
    }
    
    public void StartCombatShake()
    {
        SetShakeIntensity(0.5f, 1f);
    }
    
    public void StopShake()
    {
        SetShakeIntensity(0f, 0f);
    }
    
    public async UniTask ShakeForDuration(float amplitude, float frequency, float duration)
    {
        SetShakeIntensity(amplitude, frequency);
        await UniTask.Delay(TimeSpan.FromSeconds(duration));
        StopShake();
    }
}

Target Group

Multi-Target Framing

public class TargetGroupController : MonoBehaviour
{
    [SerializeField] private CinemachineTargetGroup _targetGroup;
    [SerializeField] private CinemachineVirtualCamera _groupCamera;
    
    public void AddTarget(Transform target, float weight = 1f, float radius = 1f)
    {
        _targetGroup.AddMember(target, weight, radius);
    }
    
    public void RemoveTarget(Transform target)
    {
        _targetGroup.RemoveMember(target);
    }
    
    public void SetTargetWeight(Transform target, float weight)
    {
        for (int i = 0; i  0)
        {
            _targetGroup.RemoveMember(_targetGroup.m_Targets[0].target);
        }
    }
}

Combat Target Group

public class CombatCameraController : MonoBehaviour
{
    [SerializeField] private CinemachineTargetGroup _combatGroup;
    [SerializeField] private Transform _player;
    
    private readonly List _enemies = new();
    
    public void StartCombat()
    {
        _combatGroup.AddMember(_player, 2f, 2f); // Higher weight for player
    }
    
    public void AddEnemy(Transform enemy)
    {
        _enemies.Add(enemy);
        _combatGroup.AddMember(enemy, 1f, 1f);
    }
    
    public void RemoveEnemy(Transform enemy)
    {
        _enemies.Remove(enemy);
        _combatGroup.RemoveMember(enemy);
    }
    
    public void EndCombat()
    {
        foreach (var enemy in _enemies)
        {
            _combatGroup.RemoveMember(enemy);
        }
        _enemies.Clear();
        _combatGroup.RemoveMember(_player);
    }
}

Field of View

Dynamic FOV

public class DynamicFOVController : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _virtualCamera;
    
    [SerializeField] private float _defaultFOV = 60f;
    [SerializeField] private float _sprintFOV = 70f;
    [SerializeField] private float _aimFOV = 45f;
    [SerializeField] private float _fovTransitionSpeed = 5f;
    
    private float _targetFOV;
    
    private void Start()
    {
        _targetFOV = _defaultFOV;
    }
    
    private void Update()
    {
        _virtualCamera.m_Lens.FieldOfView = Mathf.Lerp(
            _virtualCamera.m_Lens.FieldOfView,
            _targetFOV,
            Time.deltaTime * _fovTransitionSpeed
        );
    }
    
    public void SetSprintFOV()
    {
        _targetFOV = _sprintFOV;
    }
    
    public void SetAimFOV()
    {
        _targetFOV = _aimFOV;
    }
    
    public void ResetFOV()
    {
        _targetFOV = _defaultFOV;
    }
}

Dolly Track

Dolly Camera Movement

public class DollyCameraController : MonoBehaviour
{
    [SerializeField] private CinemachineVirtualCamera _dollyCamera;
    [SerializeField] private CinemachineDollyCart _dollyCart;
    [SerializeField] private CinemachineSmoothPath _dollyPath;
    
    public void StartDollyShot(float duration)
    {
        StartCoroutine(PlayDollyShot(duration));
    }
    
    private IEnumerator PlayDollyShot(float duration)
    {
        _dollyCart.m_Position = 0f;
        _dollyCamera.Priority = 20;
        
        float elapsed = 0f;
        float pathLength = _dollyPath.PathLength;
        
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = elapsed / duration;
            _dollyCart.m_Position = t * pathLength;
            yield return null;
        }
        
        _dollyCamera.Priority = 0;
    }
    
    public void SetDollyPosition(float normalizedPosition)
    {
        _dollyCart.m_Position = normalizedPosition * _dollyPath.PathLength;
    }
}

Confiner

Camera Bounds

public class CameraConfinerController : MonoBehaviour
{
    [SerializeField] private CinemachineConfiner2D _confiner;
    
    public void SetBounds(Collider2D boundsCollider)
    {
        _confiner.m_BoundingShape2D = boundsCollider;
        _confiner.InvalidateCache();
    }
    
    public void ClearBounds()
    {
        _confiner.m_BoundingShape2D = null;
    }
    
    public void SetDamping(float damping)
    {
        _confiner.m_Damping = damping;
    }
}

Best Practices

  1. Use virtual cameras - Don't move main camera directly
  2. Set priorities for camera switching
  3. Use impulse for one-shot shakes
  4. Use noise for continuous shake
  5. Tune damping for smooth following
  6. Use target groups for multi-subject framing
  7. Cache component references on Awake
  8. Test blend times for feel
  9. Use confiners for bounded areas
  10. Profile camera updates - Can be expensive

Troubleshooting

| Issue | Solution | |-------|----------| | Camera not switching | Check priorities | | Jerky movement | Adjust damping values | | Shake too intense | Lower amplitude gain | | Wrong blend | Check custom blends in brain | | Target lost | Verify Follow/LookAt assigned | | Confiner issues | Call InvalidateCache() |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.