Jekyll2023-09-14T20:55:59+00:00https://colorcrow.me/feed.xmlRicardo “Color Crow” RodriguesBoyfriend and friend to great people. Game Developer, Ph.D. student, AI ResearcherOn the Application of the Triad Affect Interpretation Method to Understand Emotional Expression2023-09-10T18:55:56+00:002023-09-10T18:55:56+00:00https://colorcrow.me/on-the-application-of-the-triad-affect-interpretation-method-to-understand-emotional-expression<p>Please, check the page below to learn more about this article:</p>
<p><a href="https://drive.google.com/file/d/1SWlpoELSYDbWZ6tXiGPMrl62iSPeov4L/view?usp=sharing">https://drive.google.com/file/d/1SWlpoELSYDbWZ6tXiGPMrl62iSPeov4L/view?usp=sharing</a></p>ricardorodriguesPlease, check the page below to learn more about this article:Modeling the Interpretation of Animations to Help Improve Emotional Expression2023-05-18T13:39:22+00:002023-05-18T13:39:22+00:00https://colorcrow.me/modeling-the-interpretation-of-animations-to-help-improve-emotional-expression<p>Please, check the page below to know more about this article:</p>
<p><a href="https://drive.google.com/file/d/1QDe4q3fcBOnZhgrpW7XSrsoxEaR5LGi7/view?usp=share_link">https://drive.google.com/file/d/1QDe4q3fcBOnZhgrpW7XSrsoxEaR5LGi7/view?usp=share_link</a></p>ricardorodriguesPlease, check the page below to know more about this article:Presentation at Foundation of Digital Games 20232023-04-30T15:16:35+00:002023-04-30T15:16:35+00:00https://colorcrow.me/presentation-at-foundation-of-digital-games-2023<p>I was lucky to present my work at the <a href="http://fdg2023.org/">Foundation of Digital Games 2023</a> (FDG23). It is part of my Ph.D. work and the first time Adfectus is present in a published article. Feel free to watch it here:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/RxwP-5TXklY?start=122" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
<p>To read more about the work, look at my research gate page.</p>
<p><a href="https://www.researchgate.net/publication/369968848_Believability_Anticipation_and_Timing_Improving_believability_through_timing_manipulation">https://www.researchgate.net/publication/369968848_Believability_Anticipation_and_Timing_Improving_believability_through_timing_manipulation</a></p>ricardorodriguesI was lucky to present my work at the Foundation of Digital Games 2023 (FDG23). It is part of my Ph.D. work and the first time Adfectus is present in a published article. Feel free to watch it here:What a week!2023-04-04T09:07:02+00:002023-04-04T09:07:02+00:00https://colorcrow.me/what-a-week<p>It has been a minute, uhm? Well, a lot is happening and I just wanted to keep you updated!</p>
<p><strong>Why was I missing for so long?</strong> Tons of work! Why am I back now? Well, I still have tons of work, but I have mostly finished the coding for my game and Ph.D. It is a huge step for me and one I was not expecting to reach although I was almost there.</p>
<p><strong>What comes next?</strong> I will now focus on writing and experimenting, rather than coding. I still have a couple of months to finish everything, but I’m almost there.</p>
<p>I do not know when I will return to blogging more often, but I hope soon. It will all depends on the amount of work and time I have to finish my Ph.D.</p>
<p><em>The final stretch!</em></p>
<p>This is it for now, but I can leave you with something more substantial. I have published a newer version of <strong>Adfectus</strong> on itch.io. It adds tons of good stuff since my last update, including emoji-like facial expressions, a color outline for emotion expressions, overhead background to signal emotional changes, a new rage emotion expression, and the obligatory bug fixes.</p>
<iframe src="https://itch.io/embed/654603?bg_color=eee&fg_color=222222&link_color=327345&border_color=333835" width="552" height="167" frameborder="0"><a href="https://quenestil.itch.io/adfectus">Adfectus by Quenestil</a></iframe>
<p>If you are interested in the game and would like to participate in future experiments on it, I invite you to <a href="https://forms.gle/uALkPYyBV3Q99KE48">fill out this form</a>.</p>ricardorodriguesIt has been a minute, uhm? Well, a lot is happening and I just wanted to keep you updated!The Lost Treasure2022-10-19T23:00:00+00:002022-10-19T23:00:00+00:00https://colorcrow.me/the-lost-treasure<p>During my Master’s degree, in 2015, I took a course on 3D Programming. Although I do not remember much of the course, the final project was one of the most exciting challenges in the degree.</p>
<p>The students would propose concepts of sensations to be implemented in a real-time cinematic in a game engine. My group (of three students) decided to tackle the feeling of claustrophobia, mystery, and awe. I was responsible for the sensation of mystery. We decided to design a cinematic where the viewer would start at the entrance of a cave, start moving into it, pass through a claustrophobic corridor almost entirely submerged, and then be led to an old temple with a skylight, where they would find and open an old chest filled with treasures. Here is the report where we describe the whole process (it is written in Portuguese):</p>
<object data="https://colorcrow.me/assets/uploads/the-lost-treasure-report.pdf" width="800" height="500"></object>
<p>I remember exploring a way of painting moss on bricks by using a custom shader and vertex color to define areas where you would want to paint the moss. If the color was black no moss would appear, red color would paint moss in the crevices, while green would scatter moss over the brick (mixing the two colors, resulting in yellow, would present both).</p>
<p><img src="/assets/uploads/moss-vertex-paint.png" alt="Moss painting on brick depending on Vertex color" title="Moss painting on brick depending on Vertex color" /></p>
<p>Check out the final result of the project in the video below:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/CyGn7-4ckyw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>ricardorodriguesDuring my Master’s degree, in 2015, I took a course on 3D Programming. Although I do not remember much of the course, the final project was one of the most exciting challenges in the degree.Adfectus Interest Demonstration Form2022-10-15T13:29:14+00:002022-10-15T13:29:14+00:00https://colorcrow.me/adfectus-interest-demonstration-form<p>Please, fill out the form in the following link to follow our updates:</p>
<p><a href="https://docs.google.com/forms/d/e/1FAIpQLSfGCKqssLfdEnurqb1CLVPH3mKvOfLt__sIKeSNvDa_M67IZg/viewform?usp=sf_link">https://docs.google.com/forms/d/e/1FAIpQLSfGCKqssLfdEnurqb1CLVPH3mKvOfLt__sIKeSNvDa_M67IZg/viewform?usp=sf_link</a></p>ricardorodriguesPlease, fill out the form in the following link to follow our updates:My Thesis’ Proposal2022-07-14T15:58:15+00:002022-07-14T15:58:15+00:00https://colorcrow.me/my-thesis-proposal<p>This past Friday, 14th of July 2022, <strong>I presented my Thesis Proposal</strong>. This step in my Ph.D. is long in the making and marks more than half of the process of a Ph.D. <strong>I had to prepare a document and a presentation</strong>. The former holds a lot of info but also serves as a base for my final thesis. <strong>It covers a diverse set of topics, like emotions, believability, and anticipation.</strong></p>
<p>You can find the <a href="https://colorcrow.me/assets/uploads/CAT_Enriching_Simple_Actions_with_Impactful_Emotions.pdf"><strong>Thesis Proposal document</strong> here</a>:</p>
<object data="https://colorcrow.me/assets/uploads/CAT_Enriching_Simple_Actions_with_Impactful_Emotions.pdf" width="800" height="500"></object>
<p>As for the <strong>presentation</strong>, it is supposed to showcase the core of the work done in 20 minutes, not an easy task. I focused on topics I still haven’t completely figured out, although a lot of my work is on track to a good solution. If you’d like to see the slides, you can do so here:</p>
<div style="position: relative; width: 100%; height: 0; padding-top: 56.2500%;
padding-bottom: 48px; box-shadow: 0 2px 8px 0 rgba(63,69,81,0.16); margin-top: 1.6em; margin-bottom: 0.9em; overflow: hidden;
border-radius: 8px; will-change: transform;">
<iframe loading="lazy" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0; border: none; padding: 0;margin: 0;" src="https://www.canva.com/design/DAFFLqw-LfQ/view?embed" allowfullscreen="allowfullscreen" allow="fullscreen">
</iframe>
</div>
<p><a href="https://www.canva.com/design/DAFFLqw-LfQ/view?utm_content=DAFFLqw-LfQ&utm_campaign=designshare&utm_medium=embeds&utm_source=link" target="_blank" rel="noopener"></a></p>
<p>The presentation went well and I was lucky to receive a lot of great feedback. Interesting input to better my message was that of <strong>linking back to the problem and hypothesis when introducing and closing a section</strong>, chapter, or whenever necessary. This feedback while appearing obvious is something easy to forget when you are writing long documents. Furthermore, another noteworthy suggestion was to <strong>include a personal reflection in the summary of a chapter</strong>, thus adding a view on why that chapter mattered and what are the big messages it should pass on.</p>
<p>In closing, <strong>a lot of work went into the production of this document and presentation, yet a lot more is still to come for my Ph.D. Thesis</strong>. Wish me luck!</p>ricardorodriguesThis past Friday, 14th of July 2022, I presented my Thesis Proposal. This step in my Ph.D. is long in the making and marks more than half of the process of a Ph.D. I had to prepare a document and a presentation. The former holds a lot of info but also serves as a base for my final thesis. It covers a diverse set of topics, like emotions, believability, and anticipation.The Recap of Adfectus at MOJO’222022-06-29T13:08:49+00:002022-06-29T13:08:49+00:00https://colorcrow.me/the-recap-of-adfectus-at-mojo22<p>This week I was lucky to be at <a href="https://labjogos.tecnico.ulisboa.pt/mojo/2022/">MOJO’22</a>, the game showcasing event at <a href="https://tecnico.ulisboa.pt/">Técnico Lisboa</a>. My presence was defined in two different roles, first off I am a <em>teaching assistant</em> in the course of <a href="https://fenix.tecnico.ulisboa.pt/disciplinas/TJS/2021-2022/2-semestre">Game Development Methodology</a> (GDM), secondly, I am a <em>Game Developer</em> showcasing Adfectus.</p>
<p><img src="/assets/uploads/20220627_112920.jpg" alt="Picture overviewing of MOJO'22 booth area" title="MOJO'22 Booth Area" /></p>
<p>The event was originally designed as a showcase of the games developed in the GDM course but grew to host also other student projects that are related to games. As a <strong>teaching assistant</strong>, I was tasked to evaluate most of the games from the GDM course, and while it is a lot of fun, it is also very time and energy-consuming. A lot of games offered interesting mechanics and, while quality varies a lot from game to game, I advise you to try out the games (that are available on the <a href="https://labjogos.tecnico.ulisboa.pt/mojo/2022/">MOJO’22 Website</a>).</p>
<p>As a side-note, a team from RTP Arena visited the event and played the games. They also interviewed the organizers and the GDM head professor for <a href="https://arena.rtp.pt/mojo-2022-tecnico-rtp-arena/">a blog post available on their website</a>.</p>
<p>The responsibilities of my first role also meant that I wasn’t able to be around my booth showcasing my game, nevertheless, <strong>Adfectus captured some attention</strong> and I wanted to share a small <strong>recap of its presence at MOJO</strong>.</p>
<h2 id="pre-event">Pre-Event</h2>
<p>In preparation for the event, it was necessary to step up a couple of things. First, build the game for different platforms, in my case Linux, Windows, and macOS, and upload them to <a href="https://quenestil.itch.io/adfectus">itch.io</a>. The build allows me to share the game online for anyone to play and also to have an easy way to download and install the game on any computer to showcase the game at the event (before the event I wasn’t sure what computer I was going to use).</p>
<p>I also prepared a set of items to display at the booth: a poster, a controls cheatsheet, and a suggestion box (with paper and pens). I choose a clean and simple look and made use of game elements (3D and 2D) to design the items. All items also had a QR code that linked them to the <a href="https://colorcrow.me/adfectus-at-mojo/">previous blog post “Adfectus at MOJO”</a>, this code allowed more people to more easily visit the website.</p>
<p><img src="/assets/uploads/poster.drawio.png" alt="Image of Adfectus' Poster" title="Adfectus' Poster" /></p>
<p>For the controls cheatsheet, I was able to find a <a href="https://julianoferreiradelima.itch.io/gamepads-assets-pixelart">good image of a controller</a>, along with <a href="https://thoseawesomeguys.com/prompts/">controller buttons icons made freely available by Xelu</a>, I could easily design the image below.</p>
<p><img src="/assets/uploads/controls.drawio.png" alt="Image of Adfectus' Controls Cheatsheet" title="Adfectus' Controls Cheatsheet" /></p>
<p>Having all the things I needed, I made my way to set things up at the event. My laptop is too weak to run the game, therefore I needed to carry my desktop (and mouse, and keyboard, and cables) to the event, luckily the event was at my workplace and I just needed to carry it downstairs, and the event organizers (<a href="https://labjogos.tecnico.ulisboa.pt/">LabJogos</a>) provided me with an amazing monitor for me to use. The hassle of setting up the desktop computer shows a big restriction on showcasing the game elsewhere without a good enough laptop (this is relevant for future events).</p>
<h2 id="in-event">In Event</h2>
<p>As previously mentioned, I wasn’t able to stick by the booth for large amounts of time. While I was away, few people interacted with the game, and fewer still read the QR code or made written suggestions. Yet, when I was near the booth and was able to invite onlookers to play, a small crowd would join and watch. I was able to speak with some of them and gather some feedback, I promptly invited them to write the suggestions down on paper and put them in the box. (Stick with your booth, or you won’t have feedback.)</p>
<p><img src="/assets/uploads/20220627_144437.jpg" alt="Picture of visitors playing a match in Adfectus" title="Picture of visitors playing a match in Adfectus" /></p>
<p>Early on I noticed something off with the game, while it wasn’t game-breaking it was providing a different gameplay experience than the one I was expecting. The issue was simple: <strong>weapons were dealing too much damage</strong>. In my lack of time and rushing things, I changed the damage amount dealt by weapons but clearly didn’t test it enough. <strong>While this experience bug was noticed, players seemed to enjoy the game</strong>. From observing some of them, I noticed that they particularly enjoyed the feeling of defeating their opponent (but without formal evaluation, these are just my assumptions).</p>
<p><img src="/assets/uploads/20220627_181104.jpg" alt="Picture of some other visitors playing a match in Adfectus" title="Picture of some other visitors playing a match in Adfectus" /></p>
<h2 id="post-event">Post-Event</h2>
<p>At the end of the day, no other noteworthy bugs were found, neither technical nor experiential. Furthermore, the <strong>suggestion box had received 7 suggestion notes</strong>. All suggestions will be considered, but not all might be added to the game (which is normal, but good to point out). Here are some of the suggestions collected:</p>
<ul>
<li>
<p>More feedback on hits/health.</p>
<ul>
<li>Make parry more noticeable.</li>
<li>Make a red vignette appear when a player is closer to defeat.</li>
</ul>
</li>
<li>Add ability to Dodge.</li>
<li>
<p>Hit damage is unbalanced.</p>
<ul>
<li>Fast attacks appear slower than heavy attacks (look into axe and sword attacks)</li>
<li>This problem is partially due to an error on the build.</li>
</ul>
</li>
<li>
<p>The camera should be over the left shoulder.</p>
<ul>
<li>The participant justified it by saying that it is easier to see the opponent’s attack, as their weapon is on the character’s right hand.</li>
</ul>
</li>
<li>
<p>Limit Sprint.</p>
<ul>
<li>Stamina bar, recovery period, or delay between sprints.</li>
</ul>
</li>
</ul>
<p>In closing, while no response was received on the online form, the results of the event were positive. For the first time, <strong>Adfectus received player feedback “in the wild” and it seemed players enjoyed it</strong>. The game seems good enough to share around and if you want to play it click on the link below.</p>
<iframe src="https://itch.io/embed/654603?bg_color=eee&fg_color=222222&link_color=327345&border_color=333835" width="552" height="167" frameborder="0"><a href="https://quenestil.itch.io/adfectus">Adfectus by Quenestil</a></iframe>
<p>Additionally, if you are interested in the game and would like to participate in future experiments on it, I invite you to <a href="https://forms.gle/uALkPYyBV3Q99KE48">fill out this form</a>.</p>ricardorodriguesThis week I was lucky to be at MOJO’22, the game showcasing event at Técnico Lisboa. My presence was defined in two different roles, first off I am a teaching assistant in the course of Game Development Methodology (GDM), secondly, I am a Game Developer showcasing Adfectus.Adfectus at MOJO2022-06-22T21:59:34+00:002022-06-22T21:59:34+00:00https://colorcrow.me/adfectus-at-mojo<p>Adfectus will be at <a href="https://labjogos.tecnico.ulisboa.pt/mojo/2022/">MOJO</a>, the students’ games showcase at <a href="https://tecnico.ulisboa.pt/">Técnico Lisboa</a>. It will be held on the 27th in Técnico and, for the first time, the public will have the opportunity to try out the game. Fortunately, this is also an opportunity for me to make a demo available for everyone!</p>
<p>If you want to try out the game you can play it now here:</p>
<iframe src="https://itch.io/embed/654603?bg_color=eee&fg_color=222222&link_color=327345&border_color=333835" width="552" height="167" frameborder="0"><a href="https://quenestil.itch.io/adfectus">Adfectus by Quenestil</a></iframe>
<p>Additionally, if you are interested in the game and <strong>would like to participate in future experiments</strong> on it, I invite you to fill out this form:</p>
<p><a href="https://forms.gle/uALkPYyBV3Q99KE48">https://forms.gle/uALkPYyBV3Q99KE48</a></p>
<p>Thank you for being so interested and feel free to leave comments and suggestions below!</p>ricardorodriguesAdfectus will be at MOJO, the students’ games showcase at Técnico Lisboa. It will be held on the 27th in Técnico and, for the first time, the public will have the opportunity to try out the game. Fortunately, this is also an opportunity for me to make a demo available for everyone!Attaching Actors to each other in UE5 C++ | Equipping a Weapon in Adfectus2022-05-20T21:56:59+00:002022-05-20T21:56:59+00:00https://colorcrow.me/attaching-an-actor-to-another-in-ue5-c-creating-and-equipping-a-melee-weapon-in-adfectus<p>This tutorial focuses on creating a weapon that a character can equip in UE5. This is a follow-up to the <a href="https://colorcrow.me/combat-in-adfectus-collisions-in-ue5/">Collisions and Damage in UE5 Tutorial</a>. In this tutorial, we will focus on how you can equip a weapon to a character.</p>
<p>We’ll start by implementing the essential bits in C++, then we move to Blueprints. The behavior in C++ can be defined in a few steps: <strong>(1)</strong> Create the weapon, <strong>(2)</strong> Attach the weapon to the character, and <strong>(3)</strong> Set the character as the wielder of the weapon. The behavior in the Blueprints will only facilitate the creation and equipping of a weapon.</p>
<h2 id="the-weapon-equippable">The Weapon… Equippable</h2>
<p>To equip a weapon, the bulk of the work is performed on the character.</p>
<p>For the weapon itself, we just need to keep the reference to its owner and disable collisions with it. Let’s look at how we can do it.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">UCLASS</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">CPPTHIRDPERSON_API</span> <span class="n">AWeapon</span> <span class="o">:</span> <span class="k">public</span> <span class="n">AActor</span>
<span class="p">{</span>
<span class="n">GENERATED_BODY</span><span class="p">()</span>
<span class="c1">// Weak Pointer to the wielder.</span>
<span class="n">UPROPERTY</span><span class="p">()</span>
<span class="n">TWeakObjectPtr</span><span class="o"><</span><span class="k">class</span> <span class="nc">AActor</span><span class="o">></span> <span class="n">WielderPtr</span><span class="p">;</span>
<span class="nl">public:</span>
<span class="c1">// Function to set the wielder.</span>
<span class="n">UFUNCTION</span><span class="p">(</span><span class="n">Category</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">)</span>
<span class="kt">void</span> <span class="n">SetWielder</span><span class="p">(</span><span class="k">class</span> <span class="nc">AActor</span><span class="o">*</span> <span class="n">Actor</span><span class="p">);</span>
<span class="c1">//...</span>
<span class="p">}</span>
</code></pre></div></div>
<p>In the header, we just need to add the reference and a new function. Recall that the weapon is an actor and can be placed in the scene separate from the character.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">AWeapon</span><span class="o">::</span><span class="n">SetWielder</span><span class="p">(</span><span class="n">AActor</span><span class="o">*</span> <span class="n">Actor</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">AActor</span><span class="o">*</span> <span class="n">Wielder</span> <span class="o">=</span> <span class="n">WielderPtr</span><span class="p">.</span><span class="n">Get</span><span class="p">())</span>
<span class="p">{</span>
<span class="n">WeaponMesh</span><span class="o">-></span><span class="n">MoveIgnoreActors</span><span class="p">.</span><span class="n">Remove</span><span class="p">(</span><span class="n">Wielder</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">WielderPtr</span> <span class="o">=</span> <span class="n">Actor</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Actor</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">WeaponMesh</span><span class="o">-></span><span class="n">MoveIgnoreActors</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">Actor</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The character class will call the <code class="language-plaintext highlighter-rouge">SetWielder</code> function when equipping a weapon. What we want to do here is to define the new wielder and set it to ignore the collisions with that character (also note how we check the previous wielder and re-enable collisions with it). For the weapon that is it.</p>
<p>Let’s look at our character.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Socket name where the weapon will be attached to.</span>
<span class="cp">#define RIGHT_WEAPON_SOCKET "Right_Weapon_Socket"
</span>
<span class="n">UCLASS</span><span class="p">(</span><span class="n">config</span> <span class="o">=</span> <span class="n">Game</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">AMyCharacter</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ACharacter</span><span class="p">,</span> <span class="k">public</span> <span class="n">IInteractor</span>
<span class="p">{</span>
<span class="n">GENERATED_BODY</span><span class="p">()</span>
<span class="c1">//...</span>
<span class="nl">public:</span>
<span class="c1">// Called when this character is being destroyed.</span>
<span class="c1">// If we have a weapon, we want to destroy it.</span>
<span class="n">BeginDestroy</span><span class="p">();</span>
<span class="n">UPROPERTY</span><span class="p">(</span><span class="n">Category</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">,</span> <span class="n">VisibleAnywhere</span><span class="p">,</span> <span class="n">BlueprintReadOnly</span><span class="p">,</span> <span class="n">meta</span> <span class="o">=</span> <span class="p">(</span><span class="n">AllowPrivateAccess</span> <span class="o">=</span> <span class="s">"true"</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">AWeapon</span><span class="o">*</span> <span class="n">EquippedWeapon</span><span class="p">;</span>
<span class="cm">/** Equips given weapon on the character. */</span>
<span class="n">UFUNCTION</span><span class="p">(</span><span class="n">BlueprintCallable</span><span class="p">,</span> <span class="n">Category</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">)</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">EquipWeapon</span><span class="p">(</span><span class="k">class</span> <span class="nc">AWeapon</span><span class="o">*</span> <span class="n">Weapon</span><span class="p">);</span>
<span class="cm">/** Drops Equipped Weapon if it exists. If destroy parameter is true, the weapon is destroyed instead of being dropped. */</span>
<span class="n">UFUNCTION</span><span class="p">(</span><span class="n">BlueprintCallable</span><span class="p">,</span> <span class="n">Category</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">)</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">DropWeapon</span><span class="p">(</span><span class="kt">bool</span> <span class="n">bDestroy</span> <span class="o">=</span> <span class="nb">false</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>In the header of our character, we need a pointer to our weapon and some new functions, to add and remove the weapon.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include "Weapon.h"
</span>
<span class="kt">void</span> <span class="n">AMyCharacter</span><span class="o">::</span><span class="n">BeginDestroy</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">DropWeapon</span><span class="p">(</span><span class="nb">true</span><span class="p">);</span>
<span class="c1">//...</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">AMyCharacter</span><span class="o">::</span><span class="n">EquipWeapon</span><span class="p">(</span><span class="n">AWeapon</span><span class="o">*</span> <span class="n">Weapon</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Weapon</span> <span class="o">!=</span> <span class="nb">nullptr</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* Drop Equipped Weapon */</span>
<span class="n">DropWeapon</span><span class="p">();</span>
<span class="cm">/* OR */</span>
<span class="cm">/* Destroy Equipped Weapon. */</span>
<span class="n">DropWeapon</span><span class="p">(</span><span class="nb">true</span><span class="p">);</span>
<span class="cm">/* Use this weapon and attach it */</span>
<span class="n">EquippedWeapon</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">;</span>
<span class="cm">/* OR */</span>
<span class="cm">/* Create a copy of the weapon and attaching it. */</span>
<span class="n">FActorSpawnParameters</span> <span class="n">parameters</span><span class="p">;</span>
<span class="n">parameters</span><span class="p">.</span><span class="n">Template</span> <span class="o">=</span> <span class="n">Weapon</span><span class="p">;</span>
<span class="n">EquippedWeapon</span> <span class="o">=</span> <span class="n">GetWorld</span><span class="p">()</span><span class="o">-></span><span class="n">SpawnActor</span><span class="o"><</span><span class="n">AWeapon</span><span class="o">></span><span class="p">(</span><span class="n">Weapon</span><span class="o">-></span><span class="n">GetClass</span><span class="p">(),</span> <span class="n">parameters</span><span class="p">);</span>
<span class="c1">// Set the wielder, ignore collisions, and add it to the correct socket.</span>
<span class="n">EquippedWeapon</span><span class="o">-></span><span class="n">SetWielder</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
<span class="n">MoveIgnoreActorAdd</span><span class="p">(</span><span class="n">EquippedWeapon</span><span class="p">);</span>
<span class="n">EquippedWeapon</span><span class="o">-></span><span class="n">AttachToComponent</span><span class="p">(</span><span class="n">GetMesh</span><span class="p">(),</span>
<span class="n">FAttachmentTransformRules</span><span class="o">::</span><span class="n">SnapToTargetNotIncludingScale</span><span class="p">,</span>
<span class="n">TEXT</span><span class="p">(</span><span class="n">RIGHT_WEAPON_SOCKET</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">UE_LOG</span><span class="p">(</span><span class="n">LogAdfectus</span><span class="p">,</span> <span class="n">Warning</span><span class="p">,</span> <span class="n">TEXT</span><span class="p">(</span><span class="s">"Weapon is null."</span><span class="p">))</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">AMyCharacter</span><span class="o">::</span><span class="n">DropWeapon</span><span class="p">(</span><span class="kt">bool</span> <span class="n">bDestroy</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">EquippedWeapon</span> <span class="o">!=</span> <span class="nb">nullptr</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Remove from the socket, making it seperate from the character.</span>
<span class="n">EquippedWeapon</span><span class="o">-></span><span class="n">DetachFromActor</span><span class="p">(</span><span class="n">FDetachmentTransformRules</span><span class="o">::</span><span class="n">KeepWorldTransform</span><span class="p">);</span>
<span class="c1">// Re-enable collisions.</span>
<span class="n">MoveIgnoreActorRemove</span><span class="p">(</span><span class="n">EquippedWeapon</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">bDestroy</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">EquippedWeapon</span><span class="o">-></span><span class="n">Destroy</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">EquippedWeapon</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Here we need a bit more info. Let’s focus on the <code class="language-plaintext highlighter-rouge">EquipWeapon()</code> function. We start by dropping or destroying the former weapon if it exists (explained later). Now, we can either attach the selected weapon or make a copy of it using the selected weapon as a template and then calling <code class="language-plaintext highlighter-rouge">SpawnActor()</code>. Having our internal reference to the weapon, we can <code class="language-plaintext highlighter-rouge">SetWielder()</code> and, the most important part, we attach the weapon to our Skeletal Mesh, more specifically, to a select bone named “Right_Weapon_Socket”.</p>
<p>To drop the weapon, we will perform the logic in reverse, so we detach the weapon from the socket (using <code class="language-plaintext highlighter-rouge">DetachFromActor()</code> ) and if then you want to destroy the weapon, simply call <code class="language-plaintext highlighter-rouge">Destroy()</code> on it.</p>
<p>We just briefly discussed the <code class="language-plaintext highlighter-rouge">MoveIgnoreActorAdd()</code> and <code class="language-plaintext highlighter-rouge">MoveIgnoreActorRemove()</code> functions, but in essence these functions disable the collisions between weapons and wielder. Note how it is called both by the wielder towards the weapon, and the weapon towards the wielder.</p>
<p><em>Now we have all the C++ code we will need. So how do we use them?</em></p>
<h2 id="into-the-blueprints"><em>Into the Blueprints</em></h2>
<p>Let’s define our steps:</p>
<ol>
<li>Create a weapon Blueprint and place a weapon in the level;</li>
<li>Have the character pick up the weapon;</li>
<li>Have the character drop the weapon.</li>
</ol>
<p>Although we could implement a part of this behavior in C++ because of its simple contents, let’s do it in Blueprints.</p>
<h3 id="create-a-weapon-blueprint">Create a Weapon Blueprint</h3>
<p>For this example, we’ll create a sword to equip. In the <code class="language-plaintext highlighter-rouge">Content Drawer > C++ Classes</code> go to your Weapon class, right-click, and create a Blueprint based on the weapon. We’ll name it <code class="language-plaintext highlighter-rouge">BP_Weapon_Sword</code>. A window will now open showing something like this:</p>
<p><img src="/assets/uploads/screenshot-from-2022-06-05-21-55-39.png" alt="Screenshot of the Editor showing our Sword Blueprint" title="Editor showing our Sword Blueprint" /></p>
<p>In the image, you will see a bit more content that you will not see on your weapon (<em>future content hint</em>), don’t worry!</p>
<p>Now let’s populate our weapon. You can change the variables defined in your C++ class by selecting the root element in the <em>Components panel</em> ( <code class="language-plaintext highlighter-rouge">BP_Weapon_Sword (Self)</code> ) and taking a look at the <em>Details panel</em>. For this example, we will just modify our Weapon Mesh to a sword. In the <em>Components panel</em>, we’ll select the <em>Weapon Mesh</em> and, in the <em>Details panel</em>, define our Static Mesh. It will look something like this:</p>
<p><img src="/assets/uploads/screenshot-from-2022-06-05-22-13-16.png" alt="Screenshot of the Editor showing our Sword Blueprint with a Static Mesh" title="Editor showing our Sword Blueprint with a Static Mesh" /></p>
<p>Save and this will be enough for our weapon. For now, we just need to place it on the level.</p>
<h3 id="have-the-character-pick-up-the-weapon">Have the Character pick up the Weapon</h3>
<p>In our current stage, we will have a weapon in the level and a character that we can control. Regarding the character, I will assume we have a Blueprint instance of the C++ character where we did our changes. With this in mind, let’s open our character Blueprint. In the Event Graph, we will implement an event that when a key is pressed (we’ll use <code class="language-plaintext highlighter-rouge">E</code>), we select the nearest weapon and equip it. It should look something like this:</p>
<iframe width="700" height="400" src="https://blueprintue.com/render/ystejp1q/" scrolling="no" allowfullscreen=""></iframe>
<p>The implementation is quite straightforward. We scan for the nearest actor of the Weapon class (ignoring our equipped weapon if there is one), if we find one we cast it to Weapon, and then we call the <code class="language-plaintext highlighter-rouge">EquipWeapon()</code> function we defined in C++. We should now be able to pick up the weapon. Let’s see what it looks like:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/U4RhCozuZFo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<h3 id="have-the-character-drop-the-weapon">Have the Character drop the Weapon</h3>
<p>To drop the weapon, we’ll use an event that when a key is pressed (we’ll use <code class="language-plaintext highlighter-rouge">R</code>), we drop our weapon. It should look something like this:</p>
<iframe width="700" height="400" src="https://blueprintue.com/render/o5vtx4sf/" scrolling="no" allowfullscreen=""></iframe>
<p>Because most of our behavior is done in C++, we just need to call it. Let’s see what it looks like by picking up a weapon and dropping it:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/jS5dlFWd_p8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>Because the weapon does not have any physics, it does not fall and just stays put, but all the behavior is implemented as expected.</p>
<h2 id="in-summary">In Summary</h2>
<p>So, to wrap up, we first added the C++ code to associate and attach a Weapon Actor to a Character, then we created a Blueprint of a weapon (in the shape of a sword), and finally, we implemented simple mechanics that equip the nearest weapon to the character.</p>
<p>As a personal note, this was quite a big undertaking for me, as I am new to this type of content, yet it is very rewarding to explain my work. Feel free to send suggestions and questions below!</p>ricardorodriguesThis tutorial focuses on creating a weapon that a character can equip in UE5. This is a follow-up to the Collisions and Damage in UE5 Tutorial. In this tutorial, we will focus on how you can equip a weapon to a character.