{"id":6018,"date":"2026-03-04T05:38:26","date_gmt":"2026-03-04T05:38:26","guid":{"rendered":"https:\/\/sites.wsagames.com\/hl1d23\/?p=6018"},"modified":"2026-05-07T05:13:31","modified_gmt":"2026-05-07T05:13:31","slug":"npc-interaction-system","status":"publish","type":"post","link":"https:\/\/sites.wsagames.com\/hl1d23\/npc-interaction-system\/","title":{"rendered":"Object &amp; NPC Interaction System"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"6018\" class=\"elementor elementor-6018\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-554fe79 e-flex e-con-boxed e-con e-parent\" data-id=\"554fe79\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-29e97c5 e-con-full e-flex e-con e-child\" data-id=\"29e97c5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-057e452 elementor-widget elementor-widget-heading\" data-id=\"057e452\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">27 Feb Update - Interaction System Refactor<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6484ce2 elementor-widget elementor-widget-image\" data-id=\"6484ce2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf.png\" class=\"attachment-full size-full wp-image-6307\" alt=\"\" srcset=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf.png 1920w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf-300x169.png 300w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf-1024x576.png 1024w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf-768x432.png 768w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/979b4de5a484689f817f4a4cea5144cf-1536x864.png 1536w\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cf474c3 elementor-widget elementor-widget-text-editor\" data-id=\"cf474c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"50\" data-end=\"134\">After discovering the problem with the interaction system on February 26, I restructured the system to make its logic more unified and easier to extend and maintain.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-29c8e3f elementor-widget elementor-widget-heading\" data-id=\"29c8e3f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Press E Prompt Management<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4b447ad elementor-widget elementor-widget-text-editor\" data-id=\"4b447ad\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"50\" data-end=\"134\">To solve the problem that multiple interactions cannot share the Press E prompt UI, I implemented a PressEPromptCoordinator script to unify the display logic of interactive prompts.<br \/><br \/>In the new structure, interaction objects no longer directly control the display of the UI, but instead send requests to the manager. For example:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f5cd456 elementor-widget elementor-widget-html\" data-id=\"f5cd456\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div style=\"background-color: #282c34 !important;color: #abb2bf !important;padding: 20px !important;border-radius: 8px !important;font-family: Consolas, 'Courier New', monospace !important;font-size: 14px !important;line-height: 1.6 !important;border: none !important\">\r\n<pre style=\"margin: 0 !important;background: transparent !important;padding: 0 !important;border: none !important\"><code style=\"font-family: inherit !important\"><span style=\"color: #c678dd\">void<\/span> <span style=\"color: #61afef\">LateUpdate<\/span>()\r\n{\r\n    <span style=\"color: #c678dd\">bool<\/span> shouldShow = playerInRange\r\n        &amp;&amp; !OpeningLock.IsLocked\r\n        &amp;&amp; GameStateManager.IsNormal\r\n        &amp;&amp; (DialogueManager.Instance == <span style=\"color: #56b6c2\">null<\/span> || !DialogueManager.Instance.IsOpen);\r\n\r\n    PressEPromptCoordinator.<span style=\"color: #61afef\">SetRequest<\/span>(pressEUI, <span style=\"color: #56b6c2\">this<\/span>, shouldShow);\r\n}\r\n\r\n<span style=\"color: #c678dd\">void<\/span> <span style=\"color: #61afef\">OnDisable<\/span>()\r\n{\r\n    PressEPromptCoordinator.<span style=\"color: #61afef\">ClearRequester<\/span>(<span style=\"color: #56b6c2\">this<\/span>);\r\n}<\/code><\/pre>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a9b0aaa elementor-widget elementor-widget-html\" data-id=\"a9b0aaa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div style=\"background-color: #282c34 !important;color: #abb2bf !important;padding: 20px !important;border-radius: 8px !important;font-family: Consolas, 'Courier New', monospace !important;font-size: 14px !important;line-height: 1.6 !important;border: none !important\">\r\n<pre style=\"margin: 0 !important;background: transparent !important;padding: 0 !important;border: none !important\"><code style=\"font-family: inherit !important\"><span style=\"color: #c678dd\">private<\/span> <span style=\"color: #c678dd\">static<\/span> <span style=\"color: #c678dd\">readonly<\/span> Dictionary&lt;<span style=\"color: #e5c07b\">GameObject<\/span>, HashSet&lt;<span style=\"color: #c678dd\">int<\/span>&gt;&gt; ActiveRequestersByUI = <span style=\"color: #c678dd\">new<\/span> Dictionary&lt;<span style=\"color: #e5c07b\">GameObject<\/span>, HashSet&lt;<span style=\"color: #c678dd\">int<\/span>&gt;&gt;();\r\n\r\n<span style=\"color: #c678dd\">public<\/span> <span style=\"color: #c678dd\">static<\/span> <span style=\"color: #c678dd\">void<\/span> <span style=\"color: #61afef\">SetRequest<\/span>(<span style=\"color: #e5c07b\">GameObject<\/span> ui, <span style=\"color: #e5c07b\">Object<\/span> requester, <span style=\"color: #c678dd\">bool<\/span> shouldShow)\r\n{\r\n    <span style=\"color: #c678dd\">if<\/span> (ui == <span style=\"color: #56b6c2\">null<\/span> || requester == <span style=\"color: #56b6c2\">null<\/span>) <span style=\"color: #c678dd\">return<\/span>;\r\n\r\n    <span style=\"color: #c678dd\">int<\/span> requesterId = requester.GetInstanceID();\r\n\r\n    <span style=\"color: #c678dd\">if<\/span> (!ActiveRequestersByUI.TryGetValue(ui, <span style=\"color: #c678dd\">out<\/span> HashSet&lt;<span style=\"color: #c678dd\">int<\/span>&gt; requesters))\r\n    {\r\n        requesters = <span style=\"color: #c678dd\">new<\/span> HashSet&lt;<span style=\"color: #c678dd\">int<\/span>&gt;();\r\n        ActiveRequestersByUI[ui] = requesters;\r\n    }\r\n\r\n    <span style=\"color: #c678dd\">if<\/span> (shouldShow)\r\n        requesters.Add(requesterId);\r\n    <span style=\"color: #c678dd\">else<\/span>\r\n        requesters.Remove(requesterId);\r\n\r\n    <span style=\"color: #c678dd\">if<\/span> (requesters.Count == <span style=\"color: #d19a66\">0<\/span>)\r\n        ActiveRequestersByUI.Remove(ui);\r\n\r\n    <span style=\"color: #c678dd\">bool<\/span> hasAnyRequester = ActiveRequestersByUI.TryGetValue(ui, <span style=\"color: #c678dd\">out<\/span> HashSet&lt;<span style=\"color: #c678dd\">int<\/span>&gt; activeSet) &amp;&amp; activeSet.Count &gt; <span style=\"color: #d19a66\">0<\/span>;\r\n    <span style=\"color: #c678dd\">if<\/span> (ui.activeSelf != hasAnyRequester)\r\n    {\r\n        ui.SetActive(hasAnyRequester);\r\n    }\r\n}<\/code><\/pre>\r\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d81d790 elementor-widget elementor-widget-text-editor\" data-id=\"d81d790\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The manager records which objects are currently requesting a prompt. If at least one object requests to be displayed, then the Press E UI remains displayed.<\/p><p>This way, multiple interacting objects can securely share the same Press E prompt UI, avoiding UI conflicts.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cfdb0fa elementor-widget elementor-widget-heading\" data-id=\"cfdb0fa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Game State Management<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6b829e5 elementor-widget elementor-widget-text-editor\" data-id=\"6b829e5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"50\" data-end=\"134\">In this refactor, I also added a <strong data-start=\"1148\" data-end=\"1168\">GameStateManager<\/strong> script to manage the current state of the game.<br \/>This system works as a simple state machine with three states:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9026a92 elementor-widget elementor-widget-code-highlight\" data-id=\"9026a92\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>Normal\r\nTask\r\nInventory<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6d5f6f4 elementor-widget elementor-widget-text-editor\" data-id=\"6d5f6f4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<ul><li data-start=\"1313\" data-end=\"1412\"><strong data-start=\"1313\" data-end=\"1323\">Normal<\/strong><br data-start=\"1323\" data-end=\"1326\" \/>When the player is in the Normal state, they can move freely and trigger interactions.<\/li><li data-start=\"1414\" data-end=\"1510\"><strong data-start=\"1414\" data-end=\"1422\">Task<\/strong><br data-start=\"1422\" data-end=\"1425\" \/>When the player presses <strong data-start=\"1449\" data-end=\"1454\">E<\/strong> to open a task UI, the game state switches to <strong data-start=\"1501\" data-end=\"1509\">Task<\/strong>.<\/li><li><strong data-start=\"1512\" data-end=\"1525\">Inventory<\/strong><br data-start=\"1525\" data-end=\"1528\" \/>When the player presses <strong data-start=\"1552\" data-end=\"1557\">B<\/strong> to open the inventory, the state switches to <strong data-start=\"1603\" data-end=\"1616\">Inventory<\/strong>.<br \/><br \/>By using this state system, the game can restrict player input depending on the current state. For example, when the player is in the <strong data-start=\"1753\" data-end=\"1767\">Task state<\/strong>, they cannot move using <strong data-start=\"1792\" data-end=\"1800\">WASD<\/strong> or open the inventory with <strong data-start=\"1828\" data-end=\"1833\">B<\/strong>.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8cf97f2 elementor-widget elementor-widget-heading\" data-id=\"8cf97f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">=====================================================================<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4914818 e-con-full e-flex e-con e-child\" data-id=\"4914818\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-088214d elementor-widget elementor-widget-heading\" data-id=\"088214d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">26 Feb Update - Interaction System Issue<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-044a161 elementor-widget elementor-widget-image\" data-id=\"044a161\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"250\" height=\"114\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/dad56ae6e7d4a9ce638ec64ff5d4a011.png\" class=\"attachment-full size-full wp-image-6381\" alt=\"\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-313a257 elementor-widget elementor-widget-text-editor\" data-id=\"313a257\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"96\" data-end=\"184\">During development, Iris and I discovered an issue while testing the interaction system.<br \/><br \/><\/p><p data-start=\"186\" data-end=\"384\">In the current version, each interactive object (such as <strong data-start=\"243\" data-end=\"281\">NPCs, Berry Bushes<\/strong>) requires its <strong data-start=\"296\" data-end=\"332\">own Press E prompt UI (TMP Text)<\/strong> in order to display the interaction hint correctly.<br \/><br \/><\/p><p data-start=\"386\" data-end=\"575\">When multiple interactive objects share the same TMP prompt UI, only one interaction script is able to trigger the <strong data-start=\"501\" data-end=\"512\">Press E<\/strong> prompt correctly, while the others fail to display the prompt.<\/p><p data-start=\"729\" data-end=\"895\">As a result, every interactive object in the scene needs its own separate prompt UI, which significantly increases the complexity of managing interaction UI elements.<br \/><br \/><\/p><p data-start=\"897\" data-end=\"1078\">After analysing this issue, I decided to <strong data-start=\"938\" data-end=\"978\">centralize the Press E trigger logic<\/strong> by managing the interaction prompt through a single script that controls when the UI should appear.<br \/><br \/><\/p><p data-start=\"1080\" data-end=\"1296\">It is also worth noting that the <strong data-start=\"1113\" data-end=\"1188\">first version of the Press E interaction system was implemented by Iris<\/strong>. In later development, I modified and expanded the interaction system based on that initial implementation.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7d504bc elementor-widget elementor-widget-heading\" data-id=\"7d504bc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">=====================================================================<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ea03c2b e-con-full e-flex e-con e-child\" data-id=\"ea03c2b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e2724d3 elementor-widget elementor-widget-heading\" data-id=\"e2724d3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">25 Feb Update - Berry Bush Interaction System<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-16843f6 elementor-widget elementor-widget-image\" data-id=\"16843f6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"1607\" height=\"834\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/ezgif.com-animated-gif-maker-4.gif\" class=\"attachment-full size-full wp-image-6299\" alt=\"\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-26eaa88 elementor-widget elementor-widget-heading\" data-id=\"26eaa88\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">Berry Bush Interaction<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b552f97 elementor-widget elementor-widget-text-editor\" data-id=\"b552f97\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"50\" data-end=\"134\">In the current version, I implemented an interaction system for the Berry Bush, allowing players to engage in simple minigames within the scene to obtain items that advance the story.<br \/>When a player enters the trigger range of a bush, the system will display an interactive prompt: <strong>Press E.<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dbe138c elementor-widget elementor-widget-code-highlight\" data-id=\"dbe138c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>void OnTriggerEnter(Collider other)\r\n{\r\n    if (!other.CompareTag(\"Player\")) return;\r\n    playerInRange = true;\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1c8ea9e elementor-widget elementor-widget-text-editor\" data-id=\"1c8ea9e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"482\" data-end=\"554\">This trigger detects whether the player is within the interaction range.<\/p><p data-start=\"556\" data-end=\"661\">When the player presses the <strong data-start=\"584\" data-end=\"593\">E key<\/strong>, the system opens the berry task UI.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5966964 elementor-widget elementor-widget-code-highlight\" data-id=\"5966964\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>if (Input.GetKeyDown(KeyCode.E))\r\n{\r\n    OpenTask();\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-e7dc19e elementor-widget elementor-widget-heading\" data-id=\"e7dc19e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">=====================================================================<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-84b5bf2 e-con-full e-flex e-con e-child\" data-id=\"84b5bf2\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1de02f2 elementor-widget elementor-widget-heading\" data-id=\"1de02f2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h1 class=\"elementor-heading-title elementor-size-default\">24 Feb Update - Press E Interaction Script<\/h1>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-07103ce elementor-widget elementor-widget-image\" data-id=\"07103ce\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"2145\" height=\"1138\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21.png\" class=\"attachment-full size-full wp-image-6531\" alt=\"\" srcset=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21.png 2145w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21-300x159.png 300w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21-1024x543.png 1024w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21-768x407.png 768w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21-1536x815.png 1536w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/03\/Snipaste_2026-05-06_06-53-21-2048x1087.png 2048w\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cf28f24 elementor-widget elementor-widget-text-editor\" data-id=\"cf28f24\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"482\" data-end=\"554\">In the current version, I implemented a basic<strong> Press E<\/strong> interaction system for NPCs. This allows the player to trigger dialogue when they enter the correct interaction range.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d2ead3d elementor-widget elementor-widget-code-highlight\" data-id=\"d2ead3d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>void OnTriggerEnter(Collider other)\r\n{\r\n    if (!other.CompareTag(\"Player\")) return;\r\n    playerInRange = true;\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1f8055b elementor-widget elementor-widget-text-editor\" data-id=\"1f8055b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This trigger detects whether the player is close enough to interact with the object.<\/p><p>When the player presses the E key, the system opens the correct dialogue file through the Dialogue Manager.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-bca37b0 elementor-widget elementor-widget-code-highlight\" data-id=\"bca37b0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-javascript line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-javascript\">\n\t\t\t\t\t<xmp>if (playerInRange &amp;&amp; Input.GetKeyDown(KeyCode.E))\r\n{\r\n    DialogueManager.Instance.StartDialogue(GetDialogueToPlay(), portrait);\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8f203b2 e-con-full e-flex e-con e-child\" data-id=\"8f203b2\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-60a75fa elementor-widget__width-initial elementor-widget elementor-widget-image\" data-id=\"60a75fa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"831\" height=\"690\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/05\/\u56fe\u72471.png\" class=\"attachment-full size-full wp-image-6540\" alt=\"\" srcset=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/05\/\u56fe\u72471.png 831w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/05\/\u56fe\u72471-300x249.png 300w, https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/05\/\u56fe\u72471-768x638.png 768w\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-295343d elementor-widget__width-initial elementor-widget elementor-widget-text-editor\" data-id=\"295343d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p style=\"text-align: left\">The Dialogue Panel was created inside the Canvas. It contains the dialogue text using TextMeshPro, the NPC portrait image, the protagonist portrait image, and the choice buttons.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4f1bd4d elementor-widget elementor-widget-image\" data-id=\"4f1bd4d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img loading=\"lazy\" decoding=\"async\" width=\"842\" height=\"980\" src=\"https:\/\/sites.wsagames.com\/hl1d23\/wp-content\/uploads\/sites\/53\/2026\/05\/ezgif.com-animated-gif-maker-8.gif\" class=\"attachment-full size-full wp-image-6539\" alt=\"\" sizes=\"100vw\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>27 Feb Update &#8211; Interaction System Refactor After discovering the problem with the interaction system on February 26, I restructured the system to make its logic more unified and easier to extend and maintain. Press E Prompt Management To solve the problem that multiple interactions cannot share the Press E prompt UI, I implemented a &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/sites.wsagames.com\/hl1d23\/npc-interaction-system\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Object &amp; NPC Interaction System&#8221;<\/span><\/a><\/p>\n","protected":false},"author":44,"featured_media":6259,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36],"tags":[],"class_list":["post-6018","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-y2_s2_development"],"_links":{"self":[{"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/posts\/6018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/comments?post=6018"}],"version-history":[{"count":121,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/posts\/6018\/revisions"}],"predecessor-version":[{"id":6898,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/posts\/6018\/revisions\/6898"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/media\/6259"}],"wp:attachment":[{"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/media?parent=6018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/categories?post=6018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.wsagames.com\/hl1d23\/wp-json\/wp\/v2\/tags?post=6018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}