{"id":602,"date":"2016-11-22T18:00:26","date_gmt":"2016-11-22T17:00:26","guid":{"rendered":"http:\/\/piflik.de\/?p=602"},"modified":"2016-11-21T11:22:55","modified_gmt":"2016-11-21T10:22:55","slug":"utilities-bits-and-bobs","status":"publish","type":"post","link":"http:\/\/piflik.de\/?p=602","title":{"rendered":"Utilities: Bits and Bobs"},"content":{"rendered":"<p>Finally, here is a collection of small(ish) utility functions. None of them warrants a separate post. As usual, you can find this, and more, on my <a title=\"Utilities\" href=\"https:\/\/bitbucket.org\/Piflik\/utilities\/src\" target=\"_blank\">Bitbucket Repository<\/a>.<!--more--><\/p>\n<p>First, since Transform.Find() only iterates over the direct children of a Transform, here are two functions to find objects in a hierarchy as DFS and BFS:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/Breadth-first search\r\npublic static Transform FindBroad(this Transform aParent, string aName) {\r\n\tvar result = aParent.Find(aName);\r\n\tif (result != null)\r\n\t\treturn result;\r\n\tforeach (Transform child in aParent)\r\n\t\tresult = child.FindBroad(aName);\r\n\t\tif (result != null)\r\n\t\t\treturn result;\r\n\t}\r\n\treturn null;\r\n}\r\n\r\n\/\/Depth-first search\r\npublic static Transform FindDeep(this Transform aParent, string aName) {\r\n\tforeach (Transform child in aParent) {\r\n\t\tif (child.name == aName)\r\n\t\t\treturn child;\r\n\t\tvar result = child.FindDeep(aName);\r\n\t\tif (result != null)\r\n\t\t\treturn result;\r\n\t}\r\n\treturn null;\r\n}\r\n<\/pre>\n<p>If you need the Canvas object for an UI element, you can use this:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static Canvas GetCanvas(this Transform obj) {\r\n\tCanvas canvas = obj.GetComponent&lt;Canvas&gt;();\r\n\twhile (canvas == null &amp;&amp; obj.parent != null) {\r\n\t\tobj = obj.parent;\r\n\t\tcanvas = obj.GetComponent&lt;Canvas&gt;();\r\n\t}\r\n\treturn canvas;\r\n}\r\n<\/pre>\n<p>This is a small function to copy the values from one Transform to another:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static void Set(this Transform destination, Transform source, Space space = Space.Self) {\r\n\tif (space == Space.Self) {\r\n\t\tdestination.localPosition = source.localPosition;\r\n\t\tdestination.localRotation = source.localRotation;\r\n\t} else {\r\n\t\tdestination.position = source.position;\r\n\t\tdestination.rotation = source.rotation;\r\n\t}\r\n\r\n\tdestination.localScale = source.localScale;\r\n}\r\n<\/pre>\n<p>Here is a function that calculates a random direction vector within a cone around an initial direction. I use it, for example, to controll the spread of a gun.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static Vector3 RandomInCone(this Vector3 dir, float openingAngle) {\r\n\tVector3 deviation = Random.insideUnitSphere;\r\n\tdir = dir.normalized;\r\n\tdeviation -= Vector3.Dot(deviation, dir) * dir;\r\n\r\n\treturn (dir * Mathf.Cos(openingAngle) + deviation * Mathf.Sin(openingAngle)).normalized;\r\n}\r\n<\/pre>\n<p>This here might be a bit niched, but it calculates the angle between a vector and the horizontal plane.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static float Theta(this Vector3 vector) {\r\n\tfloat y = vector.y;\r\n\tfloat x = Mathf.Sqrt(vector.x*vector.x + vector.z*vector.z);\r\n\r\n\treturn Mathf.Atan2(y, x);\r\n}\r\n<\/pre>\n<p>Lastly, here are two functions to calculate the length and the cost of a NavMeshPath (since Unity doesn&#8217;t provide a way to get these, yet). The cost-function can sometimes break at NavMesh borders.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static float Length(this NavMeshPath path) {\r\n\tif (path.corners.Length &lt; 2) return 0;\r\n\tfloat length = 0;\r\n\tfor (int i = 1; i &lt; path.corners.Length; ++i) {\r\n\t\tlength += Vector3.Distance(path.corners[i], path.corners[i - 1]);\r\n\t}\r\n\r\n\treturn length;\r\n}\r\n\r\npublic static float Cost(this NavMeshPath path) {\r\n\tif (path.corners.Length &lt; 2) return 0;\r\n\r\n\tfloat cost = 0;\r\n\tNavMeshHit hit;\r\n\tNavMesh.SamplePosition(path.corners[0], out hit, 0.1f, NavMesh.AllAreas);\r\n\tVector3 rayStart = path.corners[0];\r\n\tint mask = hit.mask;\r\n\tint index = IndexFromMask(mask);\r\n\r\n\tfor (int i = 1; i &lt; path.corners.Length; ++i) {\r\n\r\n\t\twhile (true) {\r\n\t\t\tNavMesh.Raycast(rayStart, path.corners[i], out hit, mask);\r\n\r\n\t\t\tcost += NavMesh.GetAreaCost(index) * hit.distance;\r\n\r\n\t\t\tif (hit.mask != 0) mask = hit.mask;\r\n\r\n\t\t\tindex = IndexFromMask(mask);\r\n\t\t\trayStart = hit.position;\r\n\r\n\t\t\tif (hit.mask == 0) {\r\n\t\t\t\trayStart += (path.corners[i] - rayStart).normalized * 0.01f;\r\n\t\t\t}\r\n\r\n\t\t\tif (!hit.hit) break;\r\n\t\t}\r\n\t}\r\n\r\n\treturn cost;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Finally, here is a collection of small(ish) utility functions. None of them warrants a separate post. As usual, you can find this, and more, on my Bitbucket Repository.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,12],"tags":[],"_links":{"self":[{"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/posts\/602"}],"collection":[{"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/piflik.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=602"}],"version-history":[{"count":8,"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/posts\/602\/revisions"}],"predecessor-version":[{"id":610,"href":"http:\/\/piflik.de\/index.php?rest_route=\/wp\/v2\/posts\/602\/revisions\/610"}],"wp:attachment":[{"href":"http:\/\/piflik.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=602"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/piflik.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=602"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/piflik.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}