{"id":313,"date":"2017-06-16T09:59:57","date_gmt":"2017-06-16T14:59:57","guid":{"rendered":"http:\/\/blogs.adosclicks.net\/sergioalba\/?p=313"},"modified":"2017-06-16T19:51:08","modified_gmt":"2017-06-17T00:51:08","slug":"anima2d-detachable-limbs-tutorial","status":"publish","type":"post","link":"https:\/\/blogs.adosclicks.net\/sergioalba\/2017\/06\/16\/anima2d-detachable-limbs-tutorial\/","title":{"rendered":"Anima2D Detachable Limbs Tutorial &#8211; Unity 3D"},"content":{"rendered":"<p>Hi, everyone! I&#8217;m back, this time we are doing something at a more intermediate level.We will be making a system that will allow you to\u00a0make parts of your character &#8220;detachable&#8221; in an Anima2D character like shown below. We will be coding quite a bit, so I hope you are comfortable with C# and scratching your head a little.<\/p>\n<p><a href=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Result.gif\" rel=\"attachment wp-att-276\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-276\" src=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Result.gif\" alt=\"Result\" width=\"480\" height=\"270\" \/><\/a><\/p>\n<p>The inspiration for the tutorial came after playing (a lot!) of Plants Vs Zombies 2. If you&#8217;ve ever played the game, the zombies, as they are losing health, start losing limbs. We will create a similar effect, with a very simple system.<\/p>\n<p><!--more--><\/p>\n<p><iframe loading=\"lazy\" width=\"750\" height=\"422\" src=\"https:\/\/www.youtube.com\/embed\/sZm6yl9CEWo?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<h2 style=\"text-align: center\">Getting Started<\/h2>\n<p>The first thing\u00a0we need to do is to create a new project, make sure you set it to the &#8220;2D&#8221; preset, otherwise Anima2D can cause some trouble. After the project is open, we will import an <a href=\"https:\/\/drive.google.com\/open?id=0B8Zl1dvvnT64blN2Z3V3c1BxeTA\" target=\"_blank\" rel=\"noopener\">Asset Package<\/a> that\u00a0has the character and the scene already set-up. <strong>To import it\u00a0<\/strong>all you need to do is download it, and double-click on the file with Unity opened, a small window will appear, make sure\u00a0<strong>everything<\/strong> is selected, then click\u00a0on &#8220;Import&#8221;. After everything has been imported, navigate to the &#8220;_Scenes&#8221; folder, and open the &#8220;Main&#8221; scene. Then, if everything went right, you should see something like this:<\/p>\n<p><a href=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start.png\" rel=\"attachment wp-att-278\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-278\" src=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start.png\" alt=\"Getting Started\" width=\"1858\" height=\"1080\" srcset=\"https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start.png 1858w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start-300x174.png 300w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start-768x446.png 768w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Main_Start-1024x595.png 1024w\" sizes=\"auto, (max-width: 1858px) 100vw, 1858px\" \/><\/a><\/p>\n<h1><\/h1>\n<h2 style=\"text-align: center\">Setting up the Limb Prefab<\/h2>\n<p>We will start by creating the &#8220;limbs&#8221; that will fall off the character:<\/p>\n<ol>\n<li>Create an empty GameObject and set it as a child of the Zombie GameObject.<\/li>\n<li>Change the name of the new GameObject to &#8220;Limb Pool&#8221;.\n<ul>\n<li>We will be putting all the limbs here<\/li>\n<\/ul>\n<\/li>\n<li>Now add another empty GameObject inside of the &#8220;Limb Pool&#8221; GameObject.<\/li>\n<li>Change the name to &#8220;Limb Head&#8221;.<\/li>\n<li>Add a RigidBody 2D and a Sprite Renderer.<\/li>\n<li>Set the mass of the <em>rigidbody2D<\/em> to 2.5<\/li>\n<li>Set the sprite to the sprite of the body part that we want to make fall, in this case, the sprite of the head (there are a few, we will use &#8220;head&#8221;).<\/li>\n<li>Create a collider in a separate child GameObject.\n<ul>\n<li>That will allow us to rotate and move the collider freely.<\/li>\n<li>I used a circle collider 2D with a radius of 2.15.<\/li>\n<\/ul>\n<\/li>\n<li>Click on Add Component -&gt;; New Script, and call it \u201cLimb\u201d.<\/li>\n<li>Open the new C# Script for editing.<\/li>\n<li>This is the code:<\/li>\n<\/ol>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing UnityEngine;\r\nusing Anima2D;\r\n\r\n&#x5B;RequireComponent(typeof(SpriteRenderer))]\r\n&#x5B;RequireComponent(typeof(Rigidbody2D))]\r\npublic class limb : MonoBehaviour {\r\n\r\n   public IEnumerator FadeTo(float initValue, float duration, float timeUntilStart)\r\n   {\r\n      \/\/Wait\r\n      yield return new WaitForSeconds(timeUntilStart);\r\n      \/\/References and color\r\n      SpriteRenderer renderer = GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;SpriteRenderer&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;();\r\n      Color newColor = new Color(1, 1, 1, 0);\r\n      renderer.color = newColor;\r\n      float alpha = renderer.color.a;\r\n\r\n      for (float t = 0.0f; t &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; 1.0f; t += Time.deltaTime \/ duration) { \/\/Lerp the alpha and apply it newColor = new Color(1, 1, 1, Mathf.Lerp(initValue, alpha, t)); renderer.color = newColor; \/\/If the object is transparent, disable it if(t &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; .98f)\r\n         {\r\n            gameObject.SetActive(false);\r\n         }\r\n\r\n         yield return null;\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<h4 style=\"text-align: center\">Code Breakdown<\/h4>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\n&#x5B;RequireComponent(typeof(Rigidbody2D))]\r\n\r\n&#x5B;RequireComponent(typeof(SpriteRenderer))]\r\n\r\n<\/pre>\n<p>The &#8220;RequireComponent()&#8221; attributes will make sure that the limb has a RigidBody2D and a SpriteRenderer.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\npublic IEnumerator FadeTo(float initValue, float duration, float timeUntilStart)\r\n\r\n<\/pre>\n<p>The FadeTo coroutine takes 3 arguments, &#8220;initValue&#8221; will determine the alpha value from which we start fading, &#8220;duration&#8221; is, well, the duration of the fade, and &#8220;timeUntilStart&#8221; determines how long it waits until it starts to fade.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n \/\/Wait \r\n yield return new WaitForSeconds(timeUntilStart);\r\n \/\/References and color\r\n SpriteRenderer renderer = GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;SpriteRenderer&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;();\r\n Color newColor = new Color(1, 1, 1, 0);\r\n renderer.color = newColor;\r\n float alpha = renderer.color.a;\r\n \r\n for (float t = 0.0f; t &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; 1.0f; t += Time.deltaTime \/ duration) { \/\/Lerp the alpha and apply it newColor = new Color(1, 1, 1, Mathf.Lerp(initValue, alpha, t)); renderer.color = newColor; \/\/If the object is transparent, disable it if(t &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; .98f)\r\n    {\r\n       gameObject.SetActive(false);\r\n    }\r\n \r\n    yield return null;\r\n }\r\n<\/pre>\n<p>Inside the coroutine, we first wait for a number of seconds, determined by &#8220;timeUntilStart&#8221;, we set up a reference to the Sprite Renderer, and we create a new color, white, with an alpha value of 0.\u00a0We set the new color on the SpriteRenderer and then we copy the alpha value. Inside the\u00a0<em>for<\/em> loop is where the magic happens. The\u00a0<em>for<\/em> loop will reiterate for the <em>duration\u00a0<\/em>argument. Inside of it, we use\u00a0<em>MathF.Lerp<\/em> to interpolate the alpha value over time, the amount of interpolation is determined by\u00a0<em>t<\/em>. We then assign the\u00a0<em>newColor<\/em> to the renderer. Lastly, we check if the object is almost transparent, and if it is, we disable it. I went ahead and created another limb for the left arm, that is called &#8220;L_Shoulder_Limb&#8221;, using the same method as above.<\/p>\n<p>If you did everything correctly, you should end up with something like this:<\/p>\n<p><a href=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete.png\" rel=\"attachment wp-att-301\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-301 size-full\" src=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete-e1496269133935.png\" alt=\"Limb_Complete\" width=\"1857\" height=\"798\" srcset=\"https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete-e1496269133935.png 1857w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete-e1496269133935-300x129.png 300w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete-e1496269133935-768x330.png 768w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Limb_Complete-e1496269133935-1024x440.png 1024w\" sizes=\"auto, (max-width: 1857px) 100vw, 1857px\" \/><\/a><\/p>\n<h3 style=\"text-align: center\">The RigidLimb Data Class<\/h3>\n<p>We will use a pure data class to store the references and\u00a0GameObjects that each limb needs to do its function in the Anima2D character. In case you have never made a data class before, I recommend checking out this <a href=\"https:\/\/unity3d.com\/learn\/tutorials\/topics\/scripting\/data-classes\" target=\"_blank\" rel=\"noopener\">Unity tutorial<\/a>. Now that we are on the same page, let&#8217;s make it happen!<\/p>\n<ol>\n<li>Go back into Unity, and\u00a0create a C# script in the Assets folder, then open it.<\/li>\n<li>Delete the &#8220;MonoBehavior&#8221; inheritance and add the &#8220;[System.Serializable]&#8221; attribute above the class declaration, we will also need to add the &#8220;Anima2D&#8221; namespace by adding &#8220;using Anima2D;&#8221;.<\/li>\n<li>This is the code:<\/li>\n<\/ol>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing UnityEngine;\r\nusing Anima2D;\r\n\r\n&#x5B;System.Serializable]\r\npublic class RigidLimb\r\n{\r\n    \/\/Prefab of limb and the bone in the character\r\n    public GameObject limbPrefab, limbBone;\r\n    \/\/The bodyMesh that corresponds to the bone in the character\r\n    public SpriteMeshInstance limbBoneMesh;\r\n    &#x5B;HideInInspector]\r\n    \/\/Reference to SpriteRenderer\r\n    public SpriteRenderer limbPrefabRenderer;\r\n    &#x5B;Range(0, 40)]\r\n    \/\/The forces applied in FallingLimb -&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; LooseNextLimb\r\n    public float detachForce, detachRotationForce;\r\n}\r\n\r\n<\/pre>\n<h4 style=\"text-align: center\">Data class breakdown<\/h4>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\nusing Anima2D;\r\n\r\n&#x5B;System.Serializable]\r\n\r\n<\/pre>\n<p>These two lines are very important, with &#8220;using Anima2D;&#8221; we are adding the Anima2D namespace, that way we can access the class &#8220;SpriteMeshInstance&#8221; which is the core component found in the BodyMeshes in the character. The [System.Serializable] attribute will allow Unity to use this as a pure Data Class (it&#8217;s more complicated, but for our needs that explanation is all you need, check <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Serializable.html\" target=\"_blank\" rel=\"noopener\">this out<\/a> for more info).<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\npublic SpriteMeshInstance limbBoneMesh;\r\n\r\n<\/pre>\n<p>This reference will allow us to access the BodyMesh&#8217;s script, to change the color to transparent when we make the &#8220;swap&#8221;.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\n&#x5B;HideInInspector]\r\n\/\/Reference to SpriteRenderer\r\npublic SpriteRenderer limbPrefabRenderer;\r\n&#x5B;Range(0, 40)]\r\n\/\/The forces applied in FallingLimb - LooseNextLimb\r\npublic float detachForce, detachRotationForce;\r\n\r\n<\/pre>\n<p>The [HideInInspector] attribute will hide the &#8220;limbPrefabRenderer&#8221; in the Editor, this will only be a reference to the SpriteRenderer component, so we don&#8217;t need to show it. The [Range] attribute shows a slider in Unity to adjust the value of the two variables below. &#8220;detachForce&#8221; is the force applied to the &#8220;Limb&#8221; GameObject when we make the effect, giving that &#8220;pop&#8221; effect. &#8220;detachRotationForce&#8221; is a the force we will add with &#8220;detachForce&#8221; to make the limb rotate as well.<\/p>\n<h2 style=\"text-align: center\">The Falling Limb Script<\/h2>\n<p>Once we are done with our first limb, we can create the manager script that will control the limb&#8217;s coroutine and position, as well as make the BodyMesh transparent. The script will be attached to the &#8220;Zombie&#8221; character. So let&#8217;s get started!<\/p>\n<ol>\n<li>Select the \u201cZombie\u201d GameObject and click on Add Component-&gt; New Script, and call it \u201cFalling Limb\u201d, then open it.<\/li>\n<li>Here is the code:<\/li>\n<\/ol>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\nusing UnityEngine;\r\n\r\npublic class FallingLimb : MonoBehaviour {\r\n\r\n    \/\/Amount of time that it will fade, and the time it has to wait to start the fading\r\n    &#x5B;Range(0, 10)]\r\n    public float fadeTime = 1.0f, timeUntilStart = 2.0f;\r\n    \/\/Reference colors\r\n    Color color_a1 = new Color(1,1,1,1);\r\n    Color color_a0 = new Color(0, 0, 0, 0);\r\n    \/\/List of RigidLimb\r\n    public List&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;RigidLimb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; rigidLimbList;\r\n    \/\/Index of current limb\r\n    &#x5B;SerializeField]\r\n    int currentLimb = 0;\r\n    bool isActive = true;\r\n\r\n    private void Start()\r\n    {\r\n        ListInitialize();\r\n        currentLimb = 0;\r\n    }\r\n\r\n    private void Update()\r\n    {\r\n        if (Input.GetMouseButtonDown(0))\r\n        {\r\n            LooseNextLimb();\r\n        }\r\n    }\r\n\r\n    void LooseNextLimb()\r\n    {\r\n        if (isActive)\r\n        {\t\r\n            \/\/Current limb in list\r\n            RigidLimb limb = rigidLimbList&#x5B;currentLimb];\r\n            \/\/Set the color\r\n            limb.limbPrefabRenderer.color = color_a1;\r\n            \/\/Enable the limb and set position and rotation\r\n            limb.limbPrefab.SetActive(true);\r\n            limb.limbPrefab.transform.position = limb.limbBone.transform.position;\r\n            limb.limbPrefab.transform.rotation = Quaternion.identity;\r\n            \/\/Apply the forces\r\n            limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Rigidbody2D&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().AddForce(new Vector2(0, limb.detachForce), ForceMode2D.Impulse);\r\n            limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Rigidbody2D&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().AddTorque(Random.Range(-limb.detachRotationForce,limb.detachRotationForce), ForceMode2D.Impulse);\r\n            \/\/Set the bodyMesh to be transparent\r\n            limb.limbBoneMesh.color = color_a0;\r\n            \/\/Start FadeTo Coroutine\r\n            limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Limb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().StartCoroutine(limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Limb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().FadeTo(1.0f, fadeTime, timeUntilStart));\r\n            \/\/Increase index\r\n            currentLimb++;\r\n        }\r\n        \/\/If we ran out of limbs, stop\r\n        if (currentLimb &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;= rigidLimbList.Count)\r\n        {\r\n            isActive = false;\r\n        }\r\n    }\r\n\r\n    private void ListInitialize()\r\n    {\r\n        for (int i = 0; i &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; rigidLimbList.Count; i++)\r\n        {\r\n            \/\/Setup references and disable\r\n            rigidLimbList&#x5B;i].limbPrefabRenderer = rigidLimbList&#x5B;i].limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;SpriteRenderer&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;();\r\n            rigidLimbList&#x5B;i].limbPrefab.SetActive(false);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<h4 style=\"text-align: center\">Code Breakdown<\/h4>\n<p>First, let&#8217;s take a look at the variables we use:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n    \/\/Amount of time that it will fade, and the time it has to wait to start the fading\r\n    &#x5B;Range(0, 10)]\r\n    public float fadeTime = 1.0f, timeUntilStart = 2.0f;\r\n    \/\/Reference colors\r\n    Color color_a1 = new Color(1,1,1,1);\r\n    Color color_a0 = new Color(0, 0, 0, 0);\r\n    \/\/List of RigidLimb\r\n    public List&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;RigidLimb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; rigidLimbList;\r\n    \/\/Index of current limb\r\n    &#x5B;SerializeField]\r\n    int currentLimb = 0;\r\n    bool isActive = true;\r\n<\/pre>\n<p>We use the [Range()] attribute to make Unity show a slider in the Inspector, it simply makes it look more neat.\u00a0<em>fadeTime<\/em> is the duration of the fading,\u00a0<em>timeUntilStart\u00a0<\/em>is the amount of time that the limbs will &#8220;wait&#8221; until they start fading.\u00a0<em>color_a1\u00a0<\/em> and <em>color_a0\u00a0<\/em>are two colors, one with 100% alpha value and 0% alpha, respectively. \u00a0The RigidLimb list is the list that will contain all the references and limbs we will be using.\u00a0<em>currentLimb<\/em> is the index of the current limb in the list.\u00a0<em>isActive<\/em> is a boolean that we will use to determine if we have reached the end of the list.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprivate void Start()\r\n{\r\n    ListInitialize();\r\n    currentLimb = 0;\r\n}\r\n\r\nprivate void ListInitialize()\r\n{\r\n    for (int i = 0; i &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt; rigidLimbList.Count; i++)\r\n    {\r\n        \/\/Setup references and disable\r\n        rigidLimbList&#x5B;i].limbPrefabRenderer = rigidLimbList&#x5B;i].limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;SpriteRenderer&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;();\r\n        rigidLimbList&#x5B;i].limbPrefab.SetActive(false);\r\n    }\r\n}\r\n<\/pre>\n<p>In the\u00a0<em>Start<\/em>() method we call\u00a0<em>ListInitialize()<\/em> and we set\u00a0<em>currentLimb\u00a0<\/em>to 0. The\u00a0<em>ListInitialize()\u00a0<\/em>function will set-up the reference with the SpriteRenderer in each limb, as well as disabling the limbs.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvoid LooseNextLimb()\r\n    {\r\n        if (isActive)\r\n        {\t\r\n            \/\/Current limb in list\r\n            RigidLimb limb = rigidLimbList&#x5B;currentLimb];\r\n            \/\/Set the color\r\n            limb.limbPrefabRenderer.color = color_a1;\r\n            \/\/Enable the limb and set position and rotation\r\n            limb.limbPrefab.SetActive(true);\r\n            limb.limbPrefab.transform.position = limb.limbBone.transform.position;\r\n            limb.limbPrefab.transform.rotation = Quaternion.identity;\r\n            \/\/Apply the forces\r\n            limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Rigidbody2D&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().AddForce(new Vector2(0, limb.detachForce), ForceMode2D.Impulse);\r\n            limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Rigidbody2D&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().AddTorque(Random.Range(-limb.detachRotationForce,limb.detachRotationForce), ForceMode2D.Impulse);\r\n            \/\/Set the bodyMesh to be transparent\r\n            limb.limbBoneMesh.color = color_a0;\r\n            \/\/Start FadeTo Coroutine\r\n           limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Limb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().StartCoroutine(limb.limbPrefab.GetComponent&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;Limb&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;().FadeTo(1.0f, fadeTime, timeUntilStart));\r\n            \/\/Increase index\r\n            currentLimb++;\r\n        }\r\n        \/\/If we ran out of limbs, stop\r\n        if (currentLimb &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;= rigidLimbList.Count)\r\n        {\r\n            isActive = false;\r\n        }\r\n    }\r\n<\/pre>\n<p>Now where the magic happens, the <em>LooseNextLimb() <\/em>function does the following:<\/p>\n<ol>\n<li>Check if\u00a0<em>isActive<\/em> is true, if it is, we carry on.<\/li>\n<li>We create a RigidLimb variable, mainly to make the code more readable, we then assign the current limb in the list to it.<\/li>\n<li>We set the color of the limbPrefab&#8217;s renderer to 100%.<\/li>\n<li>We set the limbPrefab to active, and we match the position and rotation with those of the limbBone.<\/li>\n<li>We then add the forces to make the &#8220;pop&#8221; effect with AddForce(), for the upwards force, and AddTorque() to make it rotate.<\/li>\n<li>We make the real\u00a0<em>BodyMesh<\/em> be transparent.<\/li>\n<li>We call the coroutine\u00a0<em>FadeTo<\/em> that is inside the limb.<\/li>\n<li>We increase\u00a0<em>currentLimb.<\/em><\/li>\n<li>If\u00a0<em>currentLimb<\/em> is bigger than the number of limbs, we set\u00a0<em>isActive<\/em> to false.<\/li>\n<\/ol>\n<p>The script is relatively simple, so hopefully, your big minds can come up with ways to tweak it and improve it.<\/p>\n<p>The\u00a0<em>LooseNextLimb()<\/em> function will trigger with a left click on the mouse, as shown below.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprivate void Update()\r\n    {\r\n        if (Input.GetMouseButtonDown(0))\r\n        {\r\n            LooseNextLimb();\r\n        }\r\n    }\r\n<\/pre>\n<p>If you wanted to make it so that whenever the zombie gets hit, for example, it looses the next limb, you should\u00a0make the call to the function from\u00a0<em>OnCollisionEnter2D<\/em> or the method that best fits your need.<\/p>\n<h3 style=\"text-align: center\">Using the System<\/h3>\n<p>With all the script and limbs set-up, we can start actually making some limbs pop!<\/p>\n<p>Let&#8217;s jump to the <em>FallingLimb<\/em> script that is in the &#8220;Zombie&#8221;\u00a0<em>GameObject<\/em>, then let&#8217;s set the list&#8217;s size to 2 (depending on how many limbs you have). Once the list has opened, let&#8217;s go into the &#8220;Element 0&#8221; and click to open the dropdown. Inside the &#8220;Limb Prefab&#8221; slot we will drag the limb that we created. In my case, I will drag the left shoulder limb (remember that the order we put the limbs in the list DOES matter). In the Limb Bone slot, we will drag the bone that corresponds to that\u00a0<em>BodyMesh<\/em>, in this case, the L_Arm bone. The last reference will be the\u00a0<em>BodyMesh<\/em> that corresponds to the Sprite in the Limb, in this case, the L_Shoulder\u00a0<em>BodyMesh<\/em>. Last but not least, let&#8217;s set the forces, I will use 6 for &#8220;Detach Force&#8221; and 3 for &#8220;Detach Rotation Force&#8221;.<\/p>\n<p>To add more limbs, simply repeat. If everything went ok, you should have something like this:<\/p>\n<p><a href=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final.png\" rel=\"attachment wp-att-303\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-303\" src=\"http:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final.png\" alt=\"Final_Look\" width=\"1858\" height=\"1080\" srcset=\"https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final.png 1858w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final-300x174.png 300w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final-768x446.png 768w, https:\/\/blogs.adosclicks.net\/sergioalba\/files\/2017\/05\/Final-1024x595.png 1024w\" sizes=\"auto, (max-width: 1858px) 100vw, 1858px\" \/><\/a><\/p>\n<p>And that is it! You are now ready to play around with it, and come up with even better ways to use it!<\/p>\n<hr \/>\n<h3 style=\"text-align: center\">Downloads<\/h3>\n<ul>\n<li>Asset Package: <a href=\"https:\/\/drive.google.com\/open?id=0B8Zl1dvvnT64blN2Z3V3c1BxeTA\" target=\"_blank\" rel=\"noopener\">https:\/\/drive.google.com\/open?id=0B8Zl1dvvnT64blN2Z3V3c1BxeTA<\/a><\/li>\n<li>Scripts: \u00a0<a href=\"https:\/\/drive.google.com\/open?id=0B8Zl1dvvnT64VlliSno1Vi1PQnc\" target=\"_blank\" rel=\"noopener\">https:\/\/drive.google.com\/open?id=0B8Zl1dvvnT64VlliSno1Vi1PQnc<\/a><\/li>\n<li>Zombie Sprite:\u00a0<a href=\"https:\/\/free-game-assets.itch.io\/\" target=\"_blank\" rel=\"noopener\">https:\/\/free-game-assets.itch.io\/<\/a><\/li>\n<li>Background and Tiles:\u00a0<a href=\"https:\/\/bayat.itch.io\/platform-game-assets\" target=\"_blank\" rel=\"noopener\">https:\/\/bayat.itch.io\/platform-game-assets<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hi, everyone! I&#8217;m back, this time we are doing something at a more intermediate level.We will be making a system that will allow you to\u00a0make parts of your character &#8220;detachable&#8221; in an Anima2D character like shown below. We will be coding quite a bit, so I hope you are comfortable [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":315,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6184,6182,6185],"tags":[6187,6184,6904,6903,6194,6907,6906,6905,6191,6189,6190,6188,6192,6193],"class_list":["post-313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-anima2d","category-game-developing","category-tutorials","tag-anima","tag-anima2d","tag-anima2d-documentation","tag-anima2d-tutorial","tag-anima2d-unity","tag-anima2d-unity-3d","tag-anima2d-unity-tutorial","tag-anima2d-youtube","tag-english","tag-howto","tag-teach","tag-tutorial","tag-unity","tag-unity3d"],"_links":{"self":[{"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/posts\/313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/comments?post=313"}],"version-history":[{"count":6,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/posts\/313\/revisions"}],"predecessor-version":[{"id":320,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/posts\/313\/revisions\/320"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/media\/315"}],"wp:attachment":[{"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/media?parent=313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/categories?post=313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.adosclicks.net\/sergioalba\/wp-json\/wp\/v2\/tags?post=313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}