{"id":19154680,"url":"https://github.com/paulnonatomic/visualstatemachinev2","last_synced_at":"2025-05-07T06:40:43.019Z","repository":{"id":222013190,"uuid":"751099414","full_name":"PaulNonatomic/VisualStateMachineV2","owner":"PaulNonatomic","description":"A Unity C# Visual State Machine","archived":false,"fork":false,"pushed_at":"2025-04-18T17:14:09.000Z","size":858,"stargazers_count":25,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-19T06:01:50.525Z","etag":null,"topics":["editor","state-machine","state-management","stateflow","tool","tooling","unity"],"latest_commit_sha":null,"homepage":"https://github.com/PaulNonatomic/VisualStateMachineV2","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PaulNonatomic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-31T23:26:41.000Z","updated_at":"2025-04-18T17:14:13.000Z","dependencies_parsed_at":"2024-02-16T01:26:45.398Z","dependency_job_id":"0f7f344e-9a3a-4dbc-a057-64ee145500c6","html_url":"https://github.com/PaulNonatomic/VisualStateMachineV2","commit_stats":null,"previous_names":["paulnonatomic/visualstatemachinev2"],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulNonatomic%2FVisualStateMachineV2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulNonatomic%2FVisualStateMachineV2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulNonatomic%2FVisualStateMachineV2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulNonatomic%2FVisualStateMachineV2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaulNonatomic","download_url":"https://codeload.github.com/PaulNonatomic/VisualStateMachineV2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252830254,"owners_count":21810765,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["editor","state-machine","state-management","stateflow","tool","tooling","unity"],"created_at":"2024-11-09T08:27:53.170Z","updated_at":"2025-05-07T06:40:42.984Z","avatar_url":"https://github.com/PaulNonatomic.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=center\u003e   \n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"Readme~\\logo.png\" width=\"350\"\u003e\n\u003c/p\u003e\n\n### A visual editor for designing state machines in \u003ca href=\"https://unity.com/\"\u003eUnity\u003c/a\u003e\n\nCurrently still a work in progress and subject to breaking changes.\nVisual State Machine is a Unity package designed to simplify the creation and management of state machines in [Unity](https://unity.com/) projects. It provides a visual editor for designing state machines, making it easier to create complex behaviors without writing extensive code.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![PullRequests](https://img.shields.io/badge/PRs-welcome-blueviolet)](http://makeapullrequest.com)\n[![Releases](https://img.shields.io/github/v/release/PaulNonatomic/VisualStateMachineV2)](https://github.com/PaulNonatomic/VisualStateMachineV2/releases)\n[![Unity](https://img.shields.io/badge/Unity-2022.3+-black.svg)](https://unity3d.com/pt/get-unity/download/archive)\n\n\u003c/div\u003e\n\n---\n\nhttps://github.com/user-attachments/assets/61388bea-8bd4-4f92-9f12-c0f5768e1e8f\n\n## Features\n- **Visual Editor**: Design state machines using a user-friendly graphical interface.\n- **Unity Integration**: Seamlessly integrates with Unity, allowing for easy implementation in your game projects.\n- **Custom State Support**: Create your own states to handle specific game behaviors.\n- **Transition Management**: Easily manage transitions between states with intuitive controls.\n\n## Installation\nTo install Visual State Machine in your Unity project, follow these steps:\n1. Open Unity and navigate to the **Package Manager**.\n2. Click on the **+** button and select **Add package from git URL...**\n3. Enter the following URL: `https://github.com/PaulNonatomic/VisualStateMachineV2.git` and press **Add**.\n\n## Migration Steps to Version 0.9.0-beta\n\nWhen upgrading to Visual State Machine V2 (VSM2) version 0.9.0-beta, follow these steps to ensure a seamless transition and maintain functionality within your Unity project:\n\n1. **Commit Changes:** Before starting the upgrade, ensure all your current work is committed to version control.\n2. **Update the package:** Change the package address in your projects Packages/manifest.json file to https://github.com/PaulNonatomic/VisualStateMachineV2.git#0.9.0-migration\n3. **Run the migration tool:** open Tools -\u003e VSM2 -\u003e Migrate to 0.9.0-beta\n4. **Update the package again:** Once the migration has completed update the package to the latest, currently 0.9.6-beta \n\n## Usage\n1. **Create a State Machine Asset**\n\t- In the Project panel, right-click and select **Create -\u003e State Machine -\u003e State Machine**.\u003cbr\u003e\u003cbr\u003e\n2. **Add States**\n\t- Either right-click and select **Add State** or drag out from the **Entry State**.\n\nhttps://github.com/user-attachments/assets/ff8fb491-fc7a-4658-8ee0-de0ddb2e8c0b\n\n3. **State Selection Window**\n\t- The State Selection window appears listing all available states.\n\t\t- States are grouped by namespace with the inbuilt states appearing at the top.\n\t\t- The group of states nearest to the location of the state machine asset will open by default, but all states remain accessible.\n\n![Unity_QcTKNF3bSr](https://github.com/user-attachments/assets/05eb3410-81ef-4085-860c-d95683d24b8b)\n\n4. **Create a Custom State**\n\t- Here's the built-in `DelayState` as an example:\n\t- Add a `Transition` attribute to an exposed event `Action` in order for it to appear upon the state's node in the State Machine Editor.\n\t- Serialized and public properties are also exposed in the state's node in the State Machine Editor. Note fields should be populated with value types and assets, not scene types.\n\n```cs\n[NodeWidth(width:190), NodeColor(NodeColor.Teal), NodeIcon(NodeIcon.Clock)]\npublic class DelayState : BaseDelayState\n{\n\t[Transition(frameDelay:0)]\n\tpublic event Action OnComplete;\n\t\n\t[NonSerialized]\n\tprivate float _elapsedTime;\n\n\t[Enter]\n\tpublic override void OnEnter()\n\t{\n\t\t_elapsedTime = 0f;\n\t}\n\t\n\tpublic override void OnUpdate()\n\t{\n\t\t_elapsedTime += Time.deltaTime;\n\n\t\tif (_elapsedTime \u003c Duration) return;\n\t\tOnComplete?.Invoke();\n\t}\n}\n```\n\n5. **Assign the State Machine**\n\t- Create a GameObject with a StateMachineController component and assign your new state machine asset to it.\u003cbr\u003e\u003cbr\u003e   \n6. **Run the Application**\n\t- With the StateMachineController selected, you can see the state of your state machine within the State Machine Editor window.\n\n## Typed Transitions\n#### Passing Data Between States Using Typed Transitions\n\nTo pass data between states in the Visual State Machine, you utilize transitions. Transitions are defined by public event Actions that are decorated with a TransitionAttribute **[Transition]**. Here's how you can effectively use typed transitions:\n\n### Defining Transitions with Parameters\n\n* **Basic Transitions**\n\t- Use Action for transitions without parameters.\n\n* **Typed Transitions**\n\t- Use Action\u003cT\u003e to pass data between states. Note: The package currently supports a maximum of one parameter per transition. Action\u003cT1, T2\u003e or more parameters are not supported at this time.\n\n### Example: Passing an Integer Between States\n#### Defining the Transition in the Source State\n\n```csharp\npublic class SourceState : State\n{\n\t[Transition]\n\tpublic event Action\u003cint\u003e OnTransitionWithInt;\n\n\tpublic void TriggerTransition()\n\t{\n\t\tint valueToPass = 42;\n\t\tOnTransitionWithInt?.Invoke(valueToPass);\n\t}\n\n\t[Enter]\n\tpublic void OnEnter()\n\t{\n\t\t// Initialization logic\n\t}\n}\n```\n\n#### Receiving the Transition in the Target State\n\n```csharp\npublic class TargetState : State\n{\n\t[Enter]\n\tpublic void OnEnterWithInt(int receivedValue)\n\t{\n\t\tDebug.Log($\"Received value: {receivedValue}\");\n\t}\n}\n```\n\n#### Important Notes:\n* **Single Parameter Limitation:** Currently, only one parameter is supported per transition. Ensure that your transitions use Action\u003cT\u003e with a single type parameter.\u003cbr\u003e\u003cbr\u003e\n* **Entry Method Naming Convention:**\n\t- It's recommended to name your entry methods as OnEnter followed by the type, for example, OnEnterWithInt(int value). This enhances clarity and consistency.\u003cbr\u003e\u003cbr\u003e\n* **[Enter] Attribute Requirement:**\n\t- All entry methods must be decorated with the **[Enter]** attribute.\n\t- **Breaking Change:** In version 0.9.0-beta and above, the OnEnter method is no longer abstract but virtual. If you do not override it and decorate it with the **[Enter]** attribute, it will not be called.\u003cbr\u003e\u003cbr\u003e\n* **Visual Indicators in the Editor:**\n\t- Any method decorated with the **[Enter]** attribute will appear as an input port at the bottom left of your state's node in the Visual State Machine graph, displaying the parameter type.\n\t- Transitions are listed on the bottom right of your state's node with the corresponding type description for typed transitions.\u003cbr\u003e\u003cbr\u003e\n* **Connection Rules:**\n\t- Typed output ports will only connect to matching typed input ports.\n\t- Transitions without types will only connect to input ports without types.\n\t- When dragging out from an output port, valid input ports will remain highlighted while invalid ports are greyed out.\u003cbr\u003e\u003cbr\u003e\n* **Troubleshooting:**\n\t- If your entry method does not appear in the state's input ports list:\n\t\t- Ensure you've added the **[Enter]** attribute.\n\t\t- Verify that you're only using one parameter in your Action\u003cT\u003e.\u003cbr\u003e\u003cbr\u003e\n\n### Example: Implementing Typed Transitions\n#### Multiply State with Typed Transition\n\n```csharp\npublic class MultiplyState : State\n{\n    [Transition] \n    public event Action\u003cfloat\u003e OnCompleteWithResult;\n\n    [SerializeField] \n    private float _multiplyBy = 2;\n    \n    [Enter]\n    public void OnEnterWithFloat(float value)\n    {\n        var result = value * _multiplyBy;\n        OnCompleteWithResult?.Invoke(result);\n    }\n}\n```\n\n#### Result State Receiving Typed Transition\n\n```csharp\npublic class ResultState : State\n{\n\t[Enter]\n\tpublic void OnEnterWithResult(float result)\n\t{\n\t\tDebug.Log($\"Received result: {result}\");\n\t}\n}\n```\n\nBy following this approach, you can effectively pass data between states in your Visual State Machine, enhancing the flexibility and functionality of your state-driven behaviors.\n\n![Unity_AqZI8MraYO](https://github.com/user-attachments/assets/a58aa26d-a207-4fce-bc3d-22d7f8ea0823)\n\n## Loops with Jump Nodes\nAdd JumpOutState state and set it's Id. Then create a JumpInState with the corresponding Id to jump from one node to another.\n\nhttps://github.com/user-attachments/assets/35715234-e532-464b-9031-4b7780efd3ef\n\n## Transition Delay\nThe process of transitioning between nodes originally incurred no delay at all but when wiring up a looping state machine\nit could cause a stack overflow. To prevent this a delay of 1 frame has been added to all transitions by default, but this\ncan be configured on a per transition bases by passing a frameDelay value through the Transition attribute, but please use\nwith caution as a frameDelay of 0 can cause a stack overflow.\n\n## Copy \u0026 Paste\nThe State Machine Editor supports copy and paste within and between state machines.\n\nhttps://github.com/user-attachments/assets/09c1b644-c519-4bfd-8c29-4b0771d8d8b6\n\n## Shared Data\nStates have access to a shared data store\n\n```cs\npublic class StateOne : State\n{\n\t[Transition] public event Action OnComplete;\n\n\t[Enter]\n\tpublic override void OnEnter()\n\t{\n\t\tSharedData.SetData(\"age\", 42);\n\t\tOnComplete?.Invoke();\n\t}\n}\n\t\npublic class StateTwo : State\n{\n\t[Transition] public event Action OnComplete;\n\t\n\t[Enter]\n\tpublic override void OnEnter()\n\t{\n\t\tvar age = SharedData.GetData\u003cint\u003e(\"age\");\n\t\tDebug.Log($\"StateTwo - Age:{age}\");\n\t\t\n\t\tOnComplete?.Invoke();\n\t}\n}\n```\n\nThis same data store is exposed externally to the state machine through the StateMachineController.SharedData\n\n## License\nVisualStateMachineV2 is licensed under the MIT license\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulnonatomic%2Fvisualstatemachinev2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulnonatomic%2Fvisualstatemachinev2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulnonatomic%2Fvisualstatemachinev2/lists"}