{"id":181,"date":"2021-02-20T21:59:31","date_gmt":"2021-02-20T21:59:31","guid":{"rendered":"https:\/\/therenaissanceraven.com\/?p=181"},"modified":"2021-02-20T21:59:31","modified_gmt":"2021-02-20T21:59:31","slug":"project-hasseu-tutorial-2-programming-sentry-turrets","status":"publish","type":"post","link":"https:\/\/therenaissanceraven.com\/?p=181","title":{"rendered":"Project Hasseu &#8211; Tutorial 2 &#8211; Programming Sentry Turrets"},"content":{"rendered":"<p>In this tutorial we are going to go through the process a making sentry turrets. Between tutorial 1 and this one, I made a simple script to spawn monster prefabs &#8211; I figured no need for me to cover this as this is much better covered other places.<\/p>\n<p>Like the last one, here is the youtube video of the tutorial:<\/p>\n<p><iframe loading=\"lazy\" title=\"Unity Tutorial Sentry Turrets\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/q02thbZx-fU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>Below is the important script portion.<\/p>\n<p>Here is the TurretController Script, attached to the turret prefab:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">using<\/span> <span style=\"color: #0e84b5; font-weight: bold;\">System.Collections<\/span>;\r\n<span style=\"color: #008800; font-weight: bold;\">using<\/span> <span style=\"color: #0e84b5; font-weight: bold;\">System.Collections.Generic<\/span>;\r\n<span style=\"color: #008800; font-weight: bold;\">using<\/span> <span style=\"color: #0e84b5; font-weight: bold;\">UnityEngine<\/span>;\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #bb0066; font-weight: bold;\">TurretController<\/span> : MonoBehaviour\r\n{\r\n    <span style=\"color: #888888;\">\/\/ reference to bullet prefab<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> GameObject bulletPreFab;\r\n\r\n    <span style=\"color: #888888;\">\/\/ firing rate s\/projectile<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">float<\/span> fireRate = .<span style=\"color: #6600ee; font-weight: bold;\">01f<\/span>;\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">float<\/span> fireCooldown = <span style=\"color: #6600ee; font-weight: bold;\">0f<\/span>;\r\n\r\n    <span style=\"color: #888888;\">\/\/ holds all monsters that are in range<\/span>\r\n    List&lt;GameObject&gt; inRangeMonsters = <span style=\"color: #008800; font-weight: bold;\">new<\/span> List&lt;GameObject&gt;();\r\n\r\n    <span style=\"color: #008800; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">Start<\/span>()\r\n    {\r\n        \r\n    }\r\n\r\n    <span style=\"color: #888888;\">\/\/ Update is called once per frame<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">Update<\/span>()\r\n    {\r\n        <span style=\"color: #888888;\">\/\/ if there are monsters in range<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span>(inRangeMonsters.Count &gt; <span style=\"color: #6600ee; font-weight: bold;\">0<\/span>)\r\n        {\r\n            fireCooldown += Time.deltaTime;\r\n            <span style=\"color: #008800; font-weight: bold;\">while<\/span> (fireCooldown &gt;= fireRate)\r\n            {\r\n                FireProjectile(inRangeMonsters[<span style=\"color: #6600ee; font-weight: bold;\">0<\/span>]);\r\n                fireCooldown -= fireRate;\r\n            }\r\n        }\r\n        \r\n    }\r\n\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> <span style=\"color: #008800; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">OnTriggerEnter2D<\/span>(Collider2D collision)\r\n    {\r\n        <span style=\"color: #888888;\">\/\/ get game object<\/span>\r\n        GameObject go = collision.gameObject;\r\n\r\n        <span style=\"color: #888888;\">\/\/ we only want to fire at monsters<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span> (go.CompareTag(<span style=\"background-color: #fff0f0;\">\"Monster\"<\/span>))\r\n        {\r\n            <span style=\"color: #888888;\">\/\/ add monster to list<\/span>\r\n            inRangeMonsters.Add(go);\r\n        }\r\n    }\r\n\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> <span style=\"color: #008800; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">OnTriggerExit2D<\/span>(Collider2D collision)\r\n    {\r\n        <span style=\"color: #888888;\">\/\/ get game object<\/span>\r\n        GameObject go = collision.gameObject;\r\n\r\n        <span style=\"color: #888888;\">\/\/ if they get out of range or die<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span> (go.CompareTag(<span style=\"background-color: #fff0f0;\">\"Monster\"<\/span>))\r\n        {\r\n            <span style=\"color: #888888;\">\/\/ remove from list<\/span>\r\n            inRangeMonsters.Remove(go);\r\n        }\r\n    }\r\n\r\n    <span style=\"color: #008800; font-weight: bold;\">private<\/span> <span style=\"color: #008800; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">FireProjectile<\/span>(GameObject targetObject)\r\n    {\r\n        <span style=\"color: #888888;\">\/\/ create the new bullet<\/span>\r\n        GameObject newObject = Instantiate(bulletPreFab);\r\n\r\n        <span style=\"color: #888888;\">\/\/ setting starting position of bullet at turret<\/span>\r\n        newObject.transform.position = <span style=\"color: #008800; font-weight: bold;\">this<\/span>.transform.position;\r\n\r\n        <span style=\"color: #888888;\">\/\/ direction to shoot (target object - turret)<\/span>\r\n        Vector2 trajectory = (Vector2)targetObject.transform.position - (Vector2)<span style=\"color: #008800; font-weight: bold;\">this<\/span>.transform.position;\r\n\r\n        <span style=\"color: #888888;\">\/\/ give trajectory to object<\/span>\r\n        newObject.GetComponent&lt;BulletController&gt;().SetTrajectory(trajectory);\r\n\r\n        <span style=\"color: #888888;\">\/\/ convertering trajectory into rotation angle and setting<\/span>\r\n        <span style=\"color: #333399; font-weight: bold;\">float<\/span> angle = Mathf.Atan2(trajectory.y, trajectory.x) * <span style=\"color: #6600ee; font-weight: bold;\">360f<\/span> \/ (<span style=\"color: #6600ee; font-weight: bold;\">2f<\/span> * Mathf.PI) - <span style=\"color: #6600ee; font-weight: bold;\">90f<\/span>;\r\n\r\n        <span style=\"color: #888888;\">\/\/ rotate turret<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">this<\/span>.transform.rotation = Quaternion.Euler(<span style=\"color: #6600ee; font-weight: bold;\">0f<\/span>, <span style=\"color: #6600ee; font-weight: bold;\">0f<\/span>, angle);\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>The turret pre-fab also needs a CircleCollider2d attached to it to simulate eye-sight\/range. The collider will need to be marked as &#8220;Is Trigger&#8221; to allow the monster objects to pass through and trigger the functions. Additionally, set the radius of the collider to the desired range by modifying the Radius.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial we are going to go through the process a making sentry turrets. Between tutorial 1 and this one, I made a simple script to spawn monster prefabs &#8211; I figured no need for me to cover this as this is much better covered other places. Like the last one, here is the&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-181","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/posts\/181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=181"}],"version-history":[{"count":1,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/posts\/181\/revisions"}],"predecessor-version":[{"id":182,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=\/wp\/v2\/posts\/181\/revisions\/182"}],"wp:attachment":[{"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/therenaissanceraven.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}