Use unique_ptr
diff --git a/include/rive/animation/animation_state.hpp b/include/rive/animation/animation_state.hpp
index 178d287..fa9b696 100644
--- a/include/rive/animation/animation_state.hpp
+++ b/include/rive/animation/animation_state.hpp
@@ -15,8 +15,8 @@
 
     public:
         const LinearAnimation* animation() const { return m_Animation; }
-        StateInstance* makeInstance() const override;
+        std::unique_ptr<StateInstance> makeInstance() const override;
     };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/rive/animation/blend_state_1d.hpp b/include/rive/animation/blend_state_1d.hpp
index 78ed6b4..9d00a34 100644
--- a/include/rive/animation/blend_state_1d.hpp
+++ b/include/rive/animation/blend_state_1d.hpp
@@ -7,8 +7,8 @@
     public:
         StatusCode import(ImportStack& importStack) override;
 
-        StateInstance* makeInstance() const override;
+        std::unique_ptr<StateInstance> makeInstance() const override;
     };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/rive/animation/blend_state_direct.hpp b/include/rive/animation/blend_state_direct.hpp
index 4dcb101..4e724c5 100644
--- a/include/rive/animation/blend_state_direct.hpp
+++ b/include/rive/animation/blend_state_direct.hpp
@@ -5,8 +5,8 @@
 namespace rive {
     class BlendStateDirect : public BlendStateDirectBase {
     public:
-        StateInstance* makeInstance() const override;
+        std::unique_ptr<StateInstance> makeInstance() const override;
     };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/rive/animation/layer_state.hpp b/include/rive/animation/layer_state.hpp
index 3802da8..06b2c07 100644
--- a/include/rive/animation/layer_state.hpp
+++ b/include/rive/animation/layer_state.hpp
@@ -35,8 +35,8 @@
 
         /// Make an instance of this state that can be advanced and applied by
         /// the state machine when it is active or being transitioned from.
-        virtual StateInstance* makeInstance() const;
+        virtual std::unique_ptr<StateInstance> makeInstance() const;
     };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/animation/animation_state.cpp b/src/animation/animation_state.cpp
index b6e85a8..b78b1ac 100644
--- a/src/animation/animation_state.cpp
+++ b/src/animation/animation_state.cpp
@@ -7,10 +7,10 @@
 
 using namespace rive;
 
-StateInstance* AnimationState::makeInstance() const {
+std::unique_ptr<StateInstance> AnimationState::makeInstance() const {
     if (animation() == nullptr) {
         // Failed to load at runtime/some new type we don't understand.
-        return new SystemStateInstance(this);
+        return std::make_unique<SystemStateInstance>(this);
     }
-    return new AnimationStateInstance(this);
-}
\ No newline at end of file
+    return std::make_unique<AnimationStateInstance>(this);
+}
diff --git a/src/animation/blend_state_1d.cpp b/src/animation/blend_state_1d.cpp
index 497790c..6feab65 100644
--- a/src/animation/blend_state_1d.cpp
+++ b/src/animation/blend_state_1d.cpp
@@ -6,8 +6,8 @@
 
 using namespace rive;
 
-StateInstance* BlendState1D::makeInstance() const {
-    return new BlendState1DInstance(this);
+std::unique_ptr<StateInstance> BlendState1D::makeInstance() const {
+    return std::make_unique<BlendState1DInstance>(this);
 }
 
 StatusCode BlendState1D::import(ImportStack& importStack) {
diff --git a/src/animation/blend_state_direct.cpp b/src/animation/blend_state_direct.cpp
index 3dd5deb..ab07669 100644
--- a/src/animation/blend_state_direct.cpp
+++ b/src/animation/blend_state_direct.cpp
@@ -6,6 +6,6 @@
 
 using namespace rive;
 
-StateInstance* BlendStateDirect::makeInstance() const {
-    return new BlendStateDirectInstance(this);
-}
\ No newline at end of file
+std::unique_ptr<StateInstance> BlendStateDirect::makeInstance() const {
+    return std::make_unique<BlendStateDirectInstance>(this);
+}
diff --git a/src/animation/layer_state.cpp b/src/animation/layer_state.cpp
index 20c3679..c9bd1d5 100644
--- a/src/animation/layer_state.cpp
+++ b/src/animation/layer_state.cpp
@@ -48,6 +48,6 @@
     m_Transitions.push_back(transition);
 }
 
-StateInstance* LayerState::makeInstance() const {
-    return new SystemStateInstance(this);
-}
\ No newline at end of file
+std::unique_ptr<StateInstance> LayerState::makeInstance() const {
+    return std::make_unique<SystemStateInstance>(this);
+}
diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp
index 06bed78..990d6a3 100644
--- a/src/animation/state_machine_instance.cpp
+++ b/src/animation/state_machine_instance.cpp
@@ -21,12 +21,10 @@
         static const int maxIterations = 100;
         const StateMachineLayer* m_Layer = nullptr;
 
-        StateInstance* m_AnyStateInstance = nullptr;
-        StateInstance* m_CurrentState = nullptr;
-        StateInstance* m_StateFrom = nullptr;
+        std::unique_ptr<StateInstance> m_AnyStateInstance;
+        std::unique_ptr<StateInstance> m_CurrentState;
+        std::unique_ptr<StateInstance> m_StateFrom;
 
-        // const LayerState* m_CurrentState = nullptr;
-        // const LayerState* m_StateFrom = nullptr;
         const StateTransition* m_Transition = nullptr;
 
         bool m_HoldAnimationFrom = false;
@@ -42,12 +40,6 @@
         float m_HoldTime = 0.0f;
 
     public:
-        ~StateMachineLayerInstance() {
-            delete m_AnyStateInstance;
-            delete m_CurrentState;
-            delete m_StateFrom;
-        }
-
         void init(const StateMachineLayer* layer) {
             assert(m_Layer == nullptr);
             m_AnyStateInstance = layer->anyState()->makeInstance();
@@ -117,11 +109,11 @@
 
             m_WaitingForExit = false;
 
-            if (tryChangeState(m_AnyStateInstance, inputs, ignoreTriggers)) {
+            if (tryChangeState(m_AnyStateInstance.get(), inputs, ignoreTriggers)) {
                 return true;
             }
 
-            return tryChangeState(m_CurrentState, inputs, ignoreTriggers);
+            return tryChangeState(m_CurrentState.get(), inputs, ignoreTriggers);
         }
 
         bool changeState(const LayerState* stateTo) {
@@ -142,7 +134,7 @@
                 return false;
             }
             auto stateFrom = stateFromInstance->state();
-            auto outState = m_CurrentState;
+            auto outState = m_CurrentState.get();
             for (size_t i = 0, length = stateFrom->transitionCount();
                  i < length;
                  i++) {
@@ -168,7 +160,7 @@
                         // Make sure we apply this state. This only returns true
                         // when it's an animation state instance.
                         auto instance =
-                            static_cast<AnimationStateInstance*>(m_StateFrom)
+                            static_cast<AnimationStateInstance*>(m_StateFrom.get())
                                 ->animationInstance();
 
                         m_HoldAnimation = instance->animation();
@@ -185,7 +177,7 @@
                         m_CurrentState != nullptr)
                     {
                         auto instance =
-                            static_cast<AnimationStateInstance*>(m_StateFrom)
+                            static_cast<AnimationStateInstance*>(m_StateFrom.get())
                                 ->animationInstance();
 
                         auto spilledTime = instance->spilledTime();
@@ -228,7 +220,7 @@
                 !m_CurrentState->state()->is<AnimationState>()) {
                 return nullptr;
             }
-            return static_cast<AnimationStateInstance*>(m_CurrentState)
+            return static_cast<AnimationStateInstance*>(m_CurrentState.get())
                 ->animationInstance();
         }
     };