C++ Conversion - Antonio Roldan



In my last post I talked about refactoring my contributions to the project to better optimize my enemy AI, and improve the overall performance of our game. The largest part of this process was deciding ultimately to convert all of my blueprints into native C++. Initially I thought I might be able to get away with creating a hybrid of blueprints and C++,  but once I started I quickly realized that it was going to be more work to try to do it that way due to all of my blueprints heavily relying on one another. This also would give me a chance to implement the new Floating Pawn Movement component that I spoke about in my last post, which is much more lightweight than the Character Movement component. Another added bonus was this allowed me to reanalyze problematic and overly complex areas of my logic, specifically how I was handling my enemies. I was able to create more modular functionality for my enemies by changing functions like their attack and death to now be handled the same way, which allowed me to move those functions to their parent class, the base enemy. I was also able to create a base animation instance, which I previously didn't have in the blueprint version of the game, to house the shared functionality between the animations for my enemies.  A major problem I was having with my object pooling was that after respawning from the pool, my enemy's rotation would start to jitter and lose it smoothness. This was fixed after converting my controller which leads me to believe there was some type of conflict between the controller's rotation and the actor's.

I was able to complete a full conversion in just under two weeks, which I was pretty proud of, however there is one major problem that has arisen as a consequence. Since we are aiming for this to be a networked multiplayer game, replication has been a huge part of the majority of the work we've been doing. Learning new terms like RPC and Multicast in the context of how Unreal's replication is set up for networking was a bit confusing at first, but with how user friendly the engine is when doing work purely in blueprint, it wasn't too hard to understand the basic concepts. Replication in native C++ however is a different animal entirely. The concepts are the same, but there is a lot of extra consideration that you need to think about and handle in code, where Unreal automatically handled those types of issues for you in blueprint. One of the most important of those being authority checks when running functions that are supposed to be exclusively run on either the server or the client. There were many areas of my code that would end up throwing exceptions with nullptrs because they were intended to only be run on the server meaning the clients were trying to run those functions as well but obviously didn't have the appropriate information causing a crash. 


Tracking these areas down was tedious but not the biggest challenge I was faced with, which is something I am still currently trying to find a solution for. That being how my animations are being replicated, or rather how they currently aren't. From my research, what I have been able to gather is that Animation Instance classes do not replicate since they are a UObject rather than an Actor. They are meant to be state driven by variables that are being changed on the server side only, meaning not only are you unable to replicate instances of these classes, but you also can't replicate any variables that you would have as members of that class either. Unreal must work some magic behind the scenes because this was something I didn't even have to consider when I was using exclusively blueprint as when testing, all of the state driven animation logic was replicating just fine with me doing very little to make that happen.  It has been a real pain to try and get this to work correctly in code and I have done extensive research at this point. I was able to get some animations replicating today, however this was a short lived victory as on the client side the animations were incredibly laggy. I was able to deduce that this was happening because we were driving our states by updating values using a Tick function in the enemy, and the Native Update in the animation class, which I learned today don't update on the same interval. The good news is nearly all of the logic that doesn't pertain to the animations is working and replicating just fine. Through continuing to debug and research I am confident that I will be able to solve this issue and will give an update on my progress in my next post. 

Leave a comment

Log in with itch.io to leave a comment.