<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://ucamo.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ucamo.github.io/" rel="alternate" type="text/html" /><updated>2024-01-14T04:57:31+00:00</updated><id>https://ucamo.github.io/feed.xml</id><title type="html">Game Development Notes</title><subtitle>Blog about Game Development, mostly focused on Unity and Software Development</subtitle><author><name>Uriel Carrillo</name></author><entry><title type="html">C# in Depth</title><link href="https://ucamo.github.io/2023/11/08/csharp-in-depth.html" rel="alternate" type="text/html" title="C# in Depth" /><published>2023-11-08T00:00:00+00:00</published><updated>2023-11-08T00:00:00+00:00</updated><id>https://ucamo.github.io/2023/11/08/csharp-in-depth</id><content type="html" xml:base="https://ucamo.github.io/2023/11/08/csharp-in-depth.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/csharp_in_depth/csharp_in_depth.jpg&quot; width=&quot;60%&quot; height=&quot;50%&quot; alt=&quot;C# in depth fourth edition by jon skeet&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Today we are going to talk about the best book for people who study C#, we are going to review its pros and cons and with this you will be able to know if this book is for you.&lt;/p&gt;

&lt;p&gt;C# in Depth is the most recommended book for people looking to learn C#, it is written by Jon Skeet, who for several years has been the Stack Overflow user with the highest score due to his answers to questions related to C#, .Net, .Net core and similar technologies.&lt;/p&gt;

&lt;p&gt;I had tried to read it other times but couldn’t finish it, this last time I decided to read it in its entirety, and after the first chapters I realized what the tone of the book was.&lt;/p&gt;

&lt;p&gt;As the name implies, it is an in-depth exploration of the C# language, the name can be a little confusing, the book is not about learning C# from start to finish, it is more of a historical explanation from C# 1.0 to making certain bets on What will be the new features of C# 8.&lt;/p&gt;

&lt;p&gt;It should be noted that I still think the book is quite good, but I decided to do this review as a reference to other people about whether it is a suitable book for you.&lt;/p&gt;

&lt;p&gt;The target audience for this book are people who already have knowledge about the development of C# and who have participated in several projects with this language. However, they are not content with knowing how to handle the implementation of the language and seek to know what the compiler does behind the scenes and how it interacts with the platform at a low level.&lt;/p&gt;

&lt;p&gt;It will also help the reader to put the new features of the language in each installment into context and will explain what problems they solve at the language level. It is worth clarifying that not many specific examples will be given of where to implement them, it is more an explanation of what the need of the language at that point in history was and what problem adding a particular feature solves.&lt;/p&gt;

&lt;p&gt;The book has 470 pages and an appendix in which it specifies which features appear in which version. It touches on several topics in depth about why it was decided to integrate such a function into the language, but from a point of view that is too academic in my opinion. &lt;strong&gt;There are times when you can see the author talking about the low-level implementation in great detail, only to comment at the end of the chapter that they will probably never have to use something like this, or that in general implementations of this type are not used in code of production.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Personally, although I thought that the book had good points, and it clarified some doubts about some concepts that I had read in code or in the C# documentation at some point but that were not completely clear to me and therefore I didn’t use them so much, those concepts helped me lose my fear of them and try to implement them in my own code when necessary.&lt;/p&gt;

&lt;p&gt;On the other hand, I do not consider myself an academic programmer, and although I like the C# language, knowing how it works at a low level has never been of my interest, since at the moment I do not feel at a professional level in the that I could contribute to the language repository to extend it, and I am more interested in the implementation and what problems it solves under what circumstances, I am more interested in knowing the context of a feature and how it is applied and why it is applied in this or that way.&lt;/p&gt;

&lt;p&gt;C# in depth takes a different approach, it will present you with a feature, give you the context of what problem it solves at the code level without a real example, and then explain how memory is managed at a low level with translated examples on how does the compter interprets the C# implementation.
I think that my personal impression is not the fault of the book, I feel that the material on which it works is good and the explanations given are quite clear, sometimes overwhelming due to the level of detail it handles, but in general I feel that C# in depth is not a book for me or for the way I am used to work.&lt;/p&gt;

&lt;p&gt;I was interested in delving into the C# language since I want to professionalize my career and one of the main recommendations for C# books was always C# in depth by Jon Skeet, now, once I have read it I can say that it is not a book for me, I will follow it fondly and will probably review it as a reference, but for implementation issues I think that the official Microsoft documentation is still the most practical way to explore any C# topic.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;if you are not like me&lt;/strong&gt;, if you are a person who works in academia, if you are interested in compilers or you are creating your own compiler, &lt;strong&gt;this book is definitely for you&lt;/strong&gt;, it is fresh, the way it is written is very casual in the explanations and deep into the context of the decisions and gives you advice and a unique view on what to expect at the machine level about the code that is being executed.&lt;/p&gt;

&lt;h3 id=&quot;points-in-its-favor&quot;&gt;&lt;strong&gt;Points in its favor:&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;These topics are very well explained: &lt;strong&gt;Generics, Delegates, Anonymous Types, Lambda expressions, Extension Methods, Asynchronous code (Async/Await), Tuples.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions about how to implement any of these topics, I recommend this book, Jon Skeet gives an excellent explanation of them.&lt;/p&gt;

&lt;h3 id=&quot;topics-i-hoped-would-be-better-explained-linq&quot;&gt;&lt;strong&gt;Topics I hoped would be better explained: LINQ&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;There is an entire chapter dedicated to LINQ, and I was waiting to read it because I have seen it in several of my projects that I collaborate on and in general as an answer to various StackOverflow issues. I have worked with LINQ but I always felt that I didn’t really understand what was happening in very long queries or perhaps I was implementing them inappropriately, so, upon picking up a book called “C# in depth” with an entire chapter dedicated to LINQ, I thought it was a great opportunity to master the subject.&lt;/p&gt;

&lt;p&gt;However, the way the topic is approached is to talk about each part that uses LINQ separately (&lt;strong&gt;Implicit typing, Object and collection Initializers, Anonymous types, Lambda expressions, Extension methods, Query expressions&lt;/strong&gt;) and then a brief explanation of how each component is related in the LINQ implementation.&lt;/p&gt;

&lt;p&gt;I would have liked to see more exploration of LINQ implementations and a better explanation of the different combinations of queries that can be used, but they are only superficially reviewed.&lt;/p&gt;

&lt;p&gt;Then the book moves on to the next topics and leaves LINQ aside, and I would like to emphasize that it is not the book’s fault, it is my fault for expecting something from a book that I didn’t know if it was going to be focused on my needs, so I blame myself.&lt;/p&gt;

&lt;h3 id=&quot;would-i-recommend-it&quot;&gt;&lt;strong&gt;Would I recommend it?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;In conclusion, this book is focused on a very particular type of programmers, but I am not a part of that type of programmers.&lt;/p&gt;

&lt;p&gt;If you really like to delve into the implementations of programming languages, if you have thought about making your own programming language or you like to create your own compilers, yes. Totally recommended.&lt;/p&gt;

&lt;p&gt;If you are a programmer looking for solutions to real problems and are looking to deepen your knowledge… I would also recommend it, just give yourself some time to read it between chapters, or use it as guide material for an interview, or reference material on specific topics, You definitely won’t find the entire book useful, but there are some excellent gems and explanations within the book that are highly recommended.&lt;/p&gt;

&lt;p&gt;I would like to clarify that it is not my intention to be harsh with the book, nor do I want to imply that programmers who focus on results are superficial, in the world of software development there are many ways to solve the same problem and we all learn differently. different, don’t get discouraged and keep learning.&lt;/p&gt;

&lt;p&gt;C# in depth by Jon Skeet, is a great book, if you are using C# in your work or projects you will most likely learn several things from it.&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">Update vs. FixedUpdate vs. LateUpdate in Unity</title><link href="https://ucamo.github.io/2022/10/12/update-vs-fixedupdate-vs-lateupdate-unity.html" rel="alternate" type="text/html" title="Update vs. FixedUpdate vs. LateUpdate in Unity" /><published>2022-10-12T00:00:00+00:00</published><updated>2022-10-12T00:00:00+00:00</updated><id>https://ucamo.github.io/2022/10/12/update-vs-fixedupdate-vs-lateupdate-unity</id><content type="html" xml:base="https://ucamo.github.io/2022/10/12/update-vs-fixedupdate-vs-lateupdate-unity.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/update_vs_fixed_vs_lateupdate_in_unity/update-vs-fixedupdate-vs-lateupdate-unity.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Update vs FixedUpdate vs lateUpdate in Unity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.logrocket.com/update-vs-fixedupdate-vs-lateupdate-in-unity/&quot;&gt;Originally posted on LogRocket on October 12,2022&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Unity, the way a game is presented to the player is everything. Both the smoothness of the controls and the gameplay they are experiencing are key, and knowing how this information is shown to the player will give you an advantage in the way you approach your Unity projects.&lt;/p&gt;

&lt;p&gt;For that reason, we’re going to be discussing update functions, learning their implementations, and deciding when to use each.&lt;/p&gt;

&lt;h3 id=&quot;what-is-a-frame-in-unity&quot;&gt;&lt;strong&gt;What is a frame in Unity?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;You can imagine a frame as a picture, and if you have multiple similar pictures showing rapidly, you can create the illusion of movement.&lt;/p&gt;

&lt;p&gt;A frame is a term inherited from animation, where some common values are 24, 30, and 60 frames per second (FPS). When it comes to games, we say that “it’s running at 60 FPS” when there are 60 new images in a second presented to the player. This is called frame rate, and frame interval is the time that happens between each frame.&lt;/p&gt;

&lt;p&gt;In our example of 60 FPS, 60 would be the frame rate, and frame interval would be 1/60 x 1000 = 16.67 milliseconds.&lt;/p&gt;

&lt;p&gt;In Unity, a frame is considered a rendered image presented to the player’s screen. Generally speaking, Unity doesn’t care about time, but it does about frames with its property &lt;strong&gt;Time.DeltaTime&lt;/strong&gt; that calculates time between frames.&lt;/p&gt;

&lt;p&gt;If for some reason, like having heavy processing during gameplay, time between frames slows down, this drops the frame rate and gives the sensation to the player that the game is running slowly.&lt;/p&gt;

&lt;h3 id=&quot;explaining-the-update-functions&quot;&gt;&lt;strong&gt;Explaining the update functions&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;During the lifetime of a script, Unity executes its functions in a specific order. You can read more about the &lt;a href=&quot;https://docs.unity3d.com/Manual/ExecutionOrder.html&quot;&gt;execution order here&lt;/a&gt;, but to keep this article simple, we will be focusing on two stages: physics and game logic.&lt;/p&gt;

&lt;p&gt;During each frame, Unity executes in order all the event functions of the active scripts.&lt;/p&gt;

&lt;p&gt;It will first execute the physics simulation logic, calling &lt;strong&gt;FixedUpdate&lt;/strong&gt; first, then the rest of the physics events.&lt;/p&gt;

&lt;p&gt;Then it will check for Input events from the user.&lt;/p&gt;

&lt;p&gt;Finally, during the game logic, it will execute the &lt;strong&gt;Update&lt;/strong&gt; function, all the game logic functions, and finally &lt;strong&gt;LateUpdate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s important to note that each event is executed in the same order across all the scripts on Unity, so if you have ten scripts that use &lt;strong&gt;FixedUpdate&lt;/strong&gt;, those will have higher execution priority than other ten scripts that have code in their &lt;strong&gt;Update&lt;/strong&gt; method; same thing with &lt;strong&gt;LateUpdate&lt;/strong&gt; with the lower priority in the order for this example.&lt;/p&gt;

&lt;h3 id=&quot;update-functions-order&quot;&gt;&lt;strong&gt;Update functions order&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Here we can see the order of these functions: we would create an empty object in a new Unity scene and attach this script to it.&lt;/p&gt;

&lt;p&gt;In this script, we will print out to the console the order of the functions that gets executed. We have set up three flags called &lt;strong&gt;continueUpdate&lt;/strong&gt;, &lt;strong&gt;continueFixedUpdate&lt;/strong&gt;, and &lt;strong&gt;continueLateUpdate&lt;/strong&gt; to prevent our functions from executing the same code multiple times and filling the console with unnecessary results:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UpdateOrder : MonoBehaviour
{
   bool continueUpdate=true;
   bool continueFixedUpdate=true;
   bool continueLateUpdate=true;

   // Start is called before the first frame update
   void Start()
   {
       Debug.Log(&quot;Start&quot;);
   }
   // Awake is called when the object is enabled
   void Awake()
   {
       Debug.Log(&quot;Awake&quot;);
   }

   //FixedUpdate is called before Update, at the same rate based on Delta Time
   void FixedUpdate()
   {
       if(continueFixedUpdate)
       {
           Debug.Log(&quot;Fixed Update&quot;);
           continueFixedUpdate=false;
       }
   }

   // Update is called once per frame
   void Update()
   {
       if(continueUpdate)
       {
           Debug.Log(&quot;Update&quot;);
           continueUpdate=false;
       }
   }
   //Late Update is called after update
   void LateUpdate()
   {
       if(continueLateUpdate)
       {
           Debug.Log(&quot;Late Update&quot;);
           continueLateUpdate=false;
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The output will be something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/update_vs_fixed_vs_lateupdate_in_unity/console-list.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Console List&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Awake&lt;/strong&gt; gets called first since the GameObject was active, then &lt;strong&gt;Start&lt;/strong&gt;, then &lt;strong&gt;FixedUpdate&lt;/strong&gt;, &lt;strong&gt;Update&lt;/strong&gt;, and finally &lt;strong&gt;LateUpdate&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;fixedupdate&quot;&gt;&lt;strong&gt;FixedUpdate&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;FixedUpdate&lt;/strong&gt; is usually used for physics calculations since it has the same frequency as the physics system: by default it executes every 0.02 seconds (50 times per second), but you can double-check it with &lt;strong&gt;Time.fixedDeltaTime&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can also change the frequency of &lt;strong&gt;FixedUpdate&lt;/strong&gt; in Unity by going to &lt;strong&gt;Edit &amp;gt; Project Settings &amp;gt; Time &amp;gt; Fixed Timestep&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/update_vs_fixed_vs_lateupdate_in_unity/time-frequency.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Time Frequency&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;update&quot;&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; is a function that gets called every frame if the &lt;strong&gt;MonoBehaviour&lt;/strong&gt; is enabled.&lt;/p&gt;

&lt;p&gt;If the frame rate is 60 FPS, it will execute 60 times a second; if it’s 30, it will be 30 times a second.&lt;/p&gt;

&lt;p&gt;If the script gets disabled (i.e., &lt;strong&gt;enabled=false&lt;/strong&gt;), it will stop.&lt;/p&gt;

&lt;h3 id=&quot;lateupdate&quot;&gt;&lt;strong&gt;LateUpdate&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Like &lt;strong&gt;Update&lt;/strong&gt;, &lt;strong&gt;LateUpdate&lt;/strong&gt; executes every frame if the &lt;strong&gt;MonoBehaviour&lt;/strong&gt; is enabled, and it will stop if it’s disabled.&lt;/p&gt;

&lt;p&gt;It will execute after all the update functions are called, and it’s recommended to use &lt;strong&gt;LateUpdate&lt;/strong&gt; on camera scripts instead of &lt;strong&gt;Update&lt;/strong&gt; since it can keep track of objects that have already been moved in an &lt;strong&gt;Update&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;Please keep in mind that the order of execution between &lt;strong&gt;Update&lt;/strong&gt; and &lt;strong&gt;LateUpdate&lt;/strong&gt; has nothing to do with speed. &lt;strong&gt;Update&lt;/strong&gt; is not faster than &lt;strong&gt;LateUpdate&lt;/strong&gt;; they are executed in different order to do different stuff. While &lt;strong&gt;Update&lt;/strong&gt; might be used to move objects in a time interval, we would use &lt;strong&gt;LateUpdate&lt;/strong&gt; to reflect the results after those objects have been moved, and it’s safe to assume that they are in a new state.&lt;/p&gt;

&lt;h2 id=&quot;where-to-use-each-update-function&quot;&gt;&lt;strong&gt;Where to use each update function&lt;/strong&gt;&lt;/h2&gt;

&lt;h3 id=&quot;fixedupdate-1&quot;&gt;&lt;strong&gt;FixedUpdate&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;It’s recommended to use &lt;strong&gt;FixedUpdate&lt;/strong&gt; when dealing with physics, like Rigidbodies updates.&lt;/p&gt;

&lt;p&gt;In the following example, we added three cubes with a &lt;strong&gt;Rigidbody&lt;/strong&gt; each.&lt;/p&gt;

&lt;p&gt;What the script does in each case is that it takes a reference of the &lt;strong&gt;Rigidbody&lt;/strong&gt; of each cube and applies a force upwards in the object they are attached to. The only difference between them is the type of update function they use.&lt;/p&gt;

&lt;p&gt;The cube on the left has this script; it will be using &lt;strong&gt;FixedUpdate&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FixedUpdateRigidBody : MonoBehaviour
{
   public Rigidbody rb;
   // Start is called before the first frame update
   void Start()
   {
       rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
   }

   //Is executed based on the Fixed Timestep (by default 50 times per second)
   void FixedUpdate()
   {
       rb.AddForce(10.0f * Vector3.up);
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The cube in the center will be using this one, using &lt;strong&gt;Update&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UpdateRigidBody : MonoBehaviour
{
   public Rigidbody rb;
   // Start is called before the first frame update
   void Start()
   {
       rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
   }

   //Is executed every frame
   void Update()
   {
       rb.AddForce(10.0f * Vector3.up);
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the cube on the right will be using this script, calling &lt;strong&gt;LateUpdate&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LateUpdateRigidBody : MonoBehaviour
{
   public Rigidbody rb;
   // Start is called before the first frame update
   void Start()
   {
       rb = GetComponent&amp;lt;Rigidbody&amp;gt;();
   }

   //Is executed every frame after Update
   void LateUpdate()
   {
       rb.AddForce(10.0f * Vector3.up);
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/update_vs_fixed_vs_lateupdate_in_unity/fixedupdate-update-lateupdate.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;FixedUpdate, Update, LateUpdate&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;From left to right, &lt;strong&gt;FixedUpdate, Update, LateUpdate&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can see a clear representation on how each update function works. &lt;strong&gt;FixedUpdate&lt;/strong&gt; will be executed once every time step is settled in Unity; that is why the movement is constant and steady.&lt;/p&gt;

&lt;p&gt;On the other hand, the cube in the center is using the &lt;strong&gt;Update&lt;/strong&gt; function every frame, so each time the function is called to apply force upward, and since each frame is more frequent than the time step of &lt;strong&gt;FixedUpdate&lt;/strong&gt;, you can see that it goes up way faster. This is because it’s being called many times more than the cube on the left.&lt;/p&gt;

&lt;p&gt;And in the case of the third cube that is using the &lt;strong&gt;LateUpdate&lt;/strong&gt; function, it is being executed each frame too, but after the Update function due the order of execution discussed above.&lt;/p&gt;

&lt;p&gt;Please note that to the human eye, the difference between executing code in the Update function and &lt;strong&gt;LateUpdate&lt;/strong&gt; function is pretty much the same. You couldn’t tell which cube is using the &lt;strong&gt;Update&lt;/strong&gt; or &lt;strong&gt;LateUpdate&lt;/strong&gt; function.&lt;/p&gt;

&lt;h3 id=&quot;update-1&quot;&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; is called every frame, so if you need to read the input of the player, this is the perfect function to handle it so you don’t miss any event.&lt;/p&gt;

&lt;h3 id=&quot;lateupdate-1&quot;&gt;&lt;strong&gt;LateUpdate&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;LateUpdate&lt;/strong&gt; executes after all the Updates functions have been called. This is relevant because the order of execution on Update might be a little chaotic, and you can’t be sure which script will be executed within all your scripts that execute &lt;strong&gt;Update&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, with &lt;strong&gt;LateUpdate&lt;/strong&gt;, you can be sure that you will call this function after all the states changed with &lt;strong&gt;Update&lt;/strong&gt; take place, so you can work with the final results of your objects.&lt;/p&gt;

&lt;p&gt;It’s recommended to use &lt;strong&gt;LateUpade&lt;/strong&gt; when following objects with the camera and updating the UI for the players.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;&lt;strong&gt;Final thoughts&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;There are two main concepts you could take from this article. For one, there is an order of execution that goes: Update is executed each frame; &lt;strong&gt;FixedUpdate&lt;/strong&gt; is executed at a specific rate defined in the editor; and &lt;strong&gt;LateUpdate&lt;/strong&gt; is executed after all the &lt;strong&gt;Update&lt;/strong&gt; functions have been called.&lt;/p&gt;

&lt;p&gt;And the second one is that this order is not based on each script; it’s based on your whole project, meaning that all the &lt;strong&gt;Update&lt;/strong&gt; events will execute at the same time, and after those are finished, &lt;strong&gt;LateUpdate&lt;/strong&gt; will execute. Because of this, one &lt;strong&gt;FixedUpdate&lt;/strong&gt; function could be called at the same time the other two are called, so try your best to order your functions and ideas before executing everything at the same time.&lt;/p&gt;

&lt;p&gt;You should be aware that the states of your objects and positions could be changed during those events and plan ahead for the best approach to have the most stable experience for your players.&lt;/p&gt;

&lt;p&gt;I hope this article has been useful to you. Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">How to use streaming assets in Unity</title><link href="https://ucamo.github.io/2022/08/24/how-to-use-streaming-assets-unity.html" rel="alternate" type="text/html" title="How to use streaming assets in Unity" /><published>2022-08-24T00:00:00+00:00</published><updated>2022-08-24T00:00:00+00:00</updated><id>https://ucamo.github.io/2022/08/24/how-to-use-streaming-assets-unity</id><content type="html" xml:base="https://ucamo.github.io/2022/08/24/how-to-use-streaming-assets-unity.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/how-to-use-streaming-assets-unity.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;How to use streaming assets in Unity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.logrocket.com/how-to-use-streaming-assets-unity/&quot;&gt;Originally posted on LogRocket on August 24,2022&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An asset can be any resource in Unity; those resources can be images, audio, video, scripts, text, etc.&lt;/p&gt;

&lt;p&gt;When building a Unity project to any platform, all the assets in your game will be “packaged” in a file (or more depending on your platform), and the resulting size of the build will depend on the size of the assets you decided to package within your game.&lt;/p&gt;

&lt;p&gt;It’s not the same to create a game with multiple HD textures rather than using a Map Atlas, or using video on 240p rather than using 1080p. It’s expected that the greater the size of your assets, the greater the size of your final build.&lt;/p&gt;

&lt;p&gt;In general, it’s a good practice to keep your build as lightweight as you can, so the player won’t be discouraged from downloading your game due to the size, and your scenes will run considerably faster.&lt;/p&gt;

&lt;p&gt;There are multiple tips and tricks to achieve this, and in this article we will be talking about some of them, starting with streaming assets.&lt;/p&gt;

&lt;h3 id=&quot;what-are-streaming-assets&quot;&gt;&lt;strong&gt;What are streaming assets?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Let’s say you have a nice scene in your game where all the action happens. The player is the enemy base, and in a specific room, you decide to put a video playing on a computer as an easter egg.&lt;/p&gt;

&lt;p&gt;The video is really big, like more than 300MB, and the player might or might not enter that specific room to actually see it. Would it be ok to load it in your scene by default? That might cause unnecessary slowness in your great scene. So it could be great to just load it when we actually need it.&lt;/p&gt;

&lt;p&gt;A streaming asset it just that: an asset placed in a specific folder that would be loaded by the Unity Player when needed. That asset will be placed in an easy to find address within the target platform.&lt;/p&gt;

&lt;p&gt;Please note that any asset placed on a streaming asset folder (named StreamingAssets within Unity) will be copied into the target platform, and if a user searches within the project folder it will be able to see them.&lt;/p&gt;

&lt;p&gt;This is how some of the mods of some games are made.&lt;/p&gt;

&lt;p&gt;Changing the texture of a character? Go into the data folder and find the used texture, then modify it. Changing the voice lines of a tough boss? Just go to the data folder and find the audio track and replace it with another with the same name.&lt;/p&gt;

&lt;p&gt;Streaming assets let the game run smoothly without loading all the assets from memory and serve the bigger ones in an easy to reach path.&lt;/p&gt;

&lt;h3 id=&quot;lets-build-an-easy-example-of-streaming-assets&quot;&gt;&lt;strong&gt;Let’s build an easy example of streaming assets&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;We are going to show how streaming assets work with an easy example by showing a video in your game.&lt;/p&gt;

&lt;p&gt;I downloaded a &lt;a href=&quot;https://www.istockphoto.com/se/video/stream-in-spring-forest-dolly-shot-gm173348974-20348476&quot;&gt;preview of a video from iStockPhoto&lt;/a&gt; for this example.&lt;/p&gt;

&lt;p&gt;Make sure the video you want to use has one of the following extensions: .mov, .mpeg, .mp4, .avi, .asf.&lt;/p&gt;

&lt;p&gt;For our initial example, we are going to create a new folder called Video and place our video inside that folder:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-inside-folder.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video Inside Folder&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then, on our &lt;strong&gt;Hierarchy&lt;/strong&gt; panel, we are going to set up our video player.&lt;/p&gt;

&lt;p&gt;Right-click on your Hierarchy and add an &lt;strong&gt;Empty Game Object&lt;/strong&gt;. I called mine &lt;strong&gt;VideoObject&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Inside of it, I created a cube where we are going to play the video; it can be any shape you want, but I chose a cube for convenience. I call it &lt;strong&gt;Video_Canvas&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And at the same level of &lt;strong&gt;Video_Canvas&lt;/strong&gt;, inside &lt;strong&gt;VideoObject&lt;/strong&gt;, I added a new &lt;strong&gt;Video Player&lt;/strong&gt; object by right-clicking &lt;strong&gt;VideoObject&lt;/strong&gt; and selecting &lt;strong&gt;Video&lt;/strong&gt;, then &lt;strong&gt;Video Player&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-object-folder-structure.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video Object Folder Structure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is how I set up our &lt;strong&gt;Video Player&lt;/strong&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-player-setup.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video Player Setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We set the Source as a &lt;strong&gt;Video Clip&lt;/strong&gt;, and then we selected the video clip from our Video Folder that we created, then we selected &lt;strong&gt;Loop&lt;/strong&gt; so the video would keep playing infinitely.&lt;/p&gt;

&lt;p&gt;Then, select &lt;strong&gt;Render Mode&lt;/strong&gt; as &lt;strong&gt;Material Override&lt;/strong&gt; and drag and drop the Object you want to play the video on — in our case, the &lt;strong&gt;Video_Canvas&lt;/strong&gt; cube. Let &lt;strong&gt;Material Property&lt;/strong&gt; be &lt;strong&gt;_MainTex&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you click on &lt;strong&gt;Play&lt;/strong&gt; in the Unity Editor, you will see something like this: a video being played on each side of the cube.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-on-each-cube-side.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video on Each Cube Side&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You could also create a plane or reduce the scale of the cube to the shape you want if you want a flatter surface, like a screen.&lt;/p&gt;

&lt;p&gt;This demo video is 3.5MB.&lt;/p&gt;

&lt;p&gt;If we build this project for a standalone platform (Windows, Linux, MacOs) we will see that a blank project with a video it’s 87.6MB.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/black-project-video.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Black Project Video&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s see how it looks using the same video as a streaming asset.&lt;/p&gt;

&lt;p&gt;To do so, we are going to create a new folder called &lt;strong&gt;StreamingAssets&lt;/strong&gt; in the &lt;strong&gt;Assets&lt;/strong&gt; folder; this is a special named folder that will treat our video file &lt;strong&gt;video_streamingAssets&lt;/strong&gt; as a regular file with no options in the properties window of the editor.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/streamingassets-folder.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;StreamingAssets Folder&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then in our &lt;strong&gt;Video Player&lt;/strong&gt; object, we could change the &lt;strong&gt;Source&lt;/strong&gt; of the &lt;strong&gt;Video Player Game Component&lt;/strong&gt; to &lt;strong&gt;URL&lt;/strong&gt; and leave the actual URL alone. We will create a new Script called &lt;strong&gt;LoadVideo&lt;/strong&gt; and attach it to our &lt;strong&gt;Video Player GameObject&lt;/strong&gt; like in the image.&lt;/p&gt;

&lt;p&gt;This script takes as a parameter a &lt;strong&gt;Video Player&lt;/strong&gt;, so we will drag and drop our same &lt;strong&gt;Video Player&lt;/strong&gt; that this script it’s attached to.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-player-details.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video Player Details&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s the script of &lt;strong&gt;LoadVideo&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using UnityEngine;
using UnityEngine.Video;

public class LoadVideo : MonoBehaviour
{
   public VideoPlayer myVideoPlayer;
   void Start()
   {
       string videoUrl= Application.streamingAssetsPath +&quot;/&quot;+ &quot;video_streamingAssets&quot; + &quot;.mp4&quot;;
       myVideoPlayer.url = videoUrl;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Basically, at the start of the application it will use &lt;strong&gt;Application.streamingAssetsPath&lt;/strong&gt; to get the path of the &lt;strong&gt;StreamingAssets&lt;/strong&gt; folder in any target platform that has been built into. And then it will reference the name of our video in that folder and its extension.&lt;/p&gt;

&lt;p&gt;Then, it will take &lt;strong&gt;myVideoPlayer&lt;/strong&gt; (that already has the reference of our scene video player) and it will write its url property with the path of our video.&lt;/p&gt;

&lt;p&gt;This will result in the same cube with the playing video.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/video-on-each-cube-side.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Video on Each Cube Side&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, if we build this project, we will see that it has the same size as our previous example, but with one major difference.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/blank-project-with-one-difference.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Blank Project with One Difference&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If we see the &lt;strong&gt;Package contents of this build&lt;/strong&gt;, we can see that on &lt;strong&gt;Contents/Resources/Data&lt;/strong&gt; there is our &lt;strong&gt;StreamingAssets&lt;/strong&gt; folder with our video.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/streamingassets-folder-with-video.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;StreamingAssets Folder with Video&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And if we &lt;strong&gt;replace&lt;/strong&gt; the video in our &lt;strong&gt;StreamingAssets&lt;/strong&gt; folder with &lt;strong&gt;another of the same name&lt;/strong&gt;, we wouldn’t need to build our project again in order to see the changes reflected in our game.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/cube-with-differences.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Cube with Differences&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that we know how we can detach our assets/content from our build. We could also call remote files from the URL on our Video Player. For doing so, we are going to use &lt;a href=&quot;https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4&quot;&gt;this video as example&lt;/a&gt;. It’s almost 10 minutes long and it’s about 151MB.&lt;/p&gt;

&lt;p&gt;If we change our code to:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using UnityEngine;
using UnityEngine.Video;

public class LoadVideo : MonoBehaviour
{
   public VideoPlayer myVideoPlayer;
   void Start()
   {
       string videoUrl= &quot;http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4&quot;;
       myVideoPlayer.url = videoUrl;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…and delete our original video of the &lt;strong&gt;StreamingAssets&lt;/strong&gt; folder, we end up with something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/new-video-cube.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;New Video Cube&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The same functionality, but now the video assets come from an &lt;strong&gt;external source&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now if we build our project without the local video in our &lt;strong&gt;StreamingAssets&lt;/strong&gt; folder, we would see a decrease in the size of our build.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how-to-use-streaming-assets-unity/streaming-assets-decreased-size.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Streaming Assets Decreased Size&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Please keep in mind that this could also be done with an async call or a &lt;strong&gt;UnityWebRequest&lt;/strong&gt; call and a coroutine, but for simplicity, we just add the exact URL of a video to demonstrate the power of streaming assets.&lt;/p&gt;

&lt;h3 id=&quot;using-a-coroutine-to-fetch-a-video-from-an-external-source&quot;&gt;&lt;strong&gt;Using a coroutine to fetch a video from an external source&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;We can modify our &lt;strong&gt;LoadingScript&lt;/strong&gt; like this in order to use a coroutine instead of passing the direct link to our video player:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using UnityEngine;
using UnityEngine.Video;
using UnityEngine.Networking;
using System.Collections;

public class LoadVideo : MonoBehaviour
{
   public VideoPlayer myVideoPlayer;
   void Start()
   {
       StartCoroutine(LoadExternalVideo(&quot;http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4&quot;));
   }

     IEnumerator LoadExternalVideo(string url){
      using (UnityWebRequest request = UnityWebRequest.Get(url))
      {
          //Fetches a page and displays the number of characters of the response.
          yield return request.SendWebRequest();
          myVideoPlayer.url = request.url;
      }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this example, we could use a coroutine to consume an API endpoint and retrieve the URL of the video, but for simplicity, this is a simple example on how to do it with an external link.&lt;/p&gt;

&lt;p&gt;The result will be very similar; we just need to make sure that our &lt;strong&gt;UnityWebRequest&lt;/strong&gt; result is retrieved from the consumed endpoint and make sure that the URL of a video is present before setting it up to the URL property of the video player.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;&lt;strong&gt;Final thoughts&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Streaming assets are just one of the different ways Unity handles assets for your game. It works great when you are trying to get your player base involved by allowing them to mod your game, or if you want to have a lightweight final build of your game, and then upon first launch, download the rest of the assets of your game before the the player takes notice.&lt;/p&gt;

&lt;p&gt;There are many online games that do this approach: their games are very light, you can finish up a little tutorial of the first level, and then you will get a loading screen that downloads the rest of the assets.&lt;/p&gt;

&lt;p&gt;You have to keep in mind the best approach for your game. You can’t have all your assets in a remote server, because what would it happen if the first time the player plays your game their device doesn’t have a good internet connection? What would your game look like without assets?&lt;/p&gt;

&lt;p&gt;One of the best approaches is having a very light version of your assets as default (like materials, textures, images) as a placeholder, and when you are sure that your player will enjoy that content and the device is ready to download that info, do so as seamlessly as possible.&lt;/p&gt;

&lt;p&gt;I hope you have liked this article and find it useful! Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">Using coroutines in Unity</title><link href="https://ucamo.github.io/2022/06/30/using-coroutines-unity.html" rel="alternate" type="text/html" title="Using coroutines in Unity" /><published>2022-06-30T00:00:00+00:00</published><updated>2022-06-30T00:00:00+00:00</updated><id>https://ucamo.github.io/2022/06/30/using-coroutines-unity</id><content type="html" xml:base="https://ucamo.github.io/2022/06/30/using-coroutines-unity.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/using_coroutines_unity/using-coroutines-unity-copy.avif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Using coroutines in Unity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.logrocket.com/using-coroutines-unity/&quot;&gt;Originally posted on LogRocket on June 30,2022&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As your Unity project grows, there will be a need to create more complex logic. You might need to load different resources or prepare time-sensitive scenes. Ultimately, we want players to have the most seamless experience without breaking their immersion.&lt;/p&gt;

&lt;p&gt;With coroutines, you can use various approaches to achieve this. In this tutorial, we will go over different uses of coroutines and when to use them.&lt;/p&gt;

&lt;h3 id=&quot;what-are-coroutines&quot;&gt;&lt;strong&gt;What are coroutines?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Unity uses frames as a way to represent time. Normal methods will execute in one frame and move into the next instruction.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.unity3d.com/Manual/Coroutines.html&quot;&gt;Coroutines can be used to execute a piece of code across multiple frames&lt;/a&gt;. They can also be used to keep executing a section of code until you tell it to stop. A coroutine contains a yield instruction that will wait a certain amount of time you tell it to.&lt;/p&gt;

&lt;h3 id=&quot;when-to-use-coroutines&quot;&gt;&lt;strong&gt;When to use coroutines&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Let’s say you want to use a normal call method with a for loop to fill a health bar from 1–100 HP. The player will see a full health bar at the end of your method. That’s because the time it takes the method to count to 100 is faster than a frame on Unity, and is also faster than your players’ eyes.&lt;/p&gt;

&lt;p&gt;This is a good example of when to use coroutines. You’d tell the coroutine to fill 1 HP, wait a fraction of a second, and do it again until we reach the full 100 HP.&lt;/p&gt;

&lt;p&gt;This way, your players will watch the health bar fill up smoothly over time.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;​​using System.Collections;
using UnityEngine;

public class HealthBar : MonoBehaviour
{
   int maxHP=100;
   int currentHP=0;


   void Start()
   {
       Debug.Log(&quot;Start Increasing Health&quot;);
       StartCoroutine(HealthIncrease());
       Debug.Log(&quot;Finish start event&quot;);
   }

   IEnumerator HealthIncrease(){
       Debug.Log(&quot;Start Coroutine&quot;);
       for(int x=1; x&amp;lt;=maxHP;x++){
           currentHP=x;
           //Increase or decrease the parameter of WaitForSeconds
           //to test different speeds.
           yield return new WaitForSeconds(0.2f);
           Debug.Log(&quot;HP: &quot;+currentHP+&quot; / &quot;+maxHP);
       }
       Debug.Log(&quot;Current health is &quot;+maxHP);
       Debug.Log(&quot;End Coroutine&quot;);
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Another potential use case could be if a player is being hit by an object and you want to add a few seconds when nothing else can hit them. This will create temporary invincibility to avoid an unjust game experience.&lt;/p&gt;

&lt;p&gt;In pseudocode, we would end up with something like this: when an object hits the player, deactivate the player hitbox for two seconds and then activate it again.&lt;/p&gt;

&lt;h3 id=&quot;an-example-of-a-coroutine&quot;&gt;&lt;strong&gt;An example of a coroutine&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;coroutine is a method from MonoBehavior that has an IEnumerator return type. To&lt;/p&gt;

&lt;p&gt;invoke and start using it, you should use the StartCoroutine method and pass your coroutine method and parameters if needed.&lt;/p&gt;

&lt;p&gt;On a coroutine, the yield return is when your code pauses for the next frame and continues afterward. If you don’t need your coroutine to wait, you can use WaitForSeconds (or any other yield instruction), as well as null.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine;

public class Coroutines : MonoBehaviour
{
   void Start(){
       Debug.Log(&quot;Begin Start event&quot;);
       StartCoroutine(WaitCoroutine(2f));
       Debug.Log(&quot;End Start event&quot;);
   }

   private IEnumerator WaitCoroutine(float time){
       Debug.Log(&quot;Inside coroutine&quot;);
       yield return new WaitForSeconds(time);
       Debug.Log(&quot;Finish coroutine after &quot;+time+&quot; seconds&quot;);
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The example above will print:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;Begin Start event
Inside coroutine
End Start event
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It will wait for two seconds, and will print:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;Finish coroutine after 2 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;implementing-a-coroutine-that-never-stops&quot;&gt;&lt;strong&gt;Implementing a coroutine that never stops&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;You can also declare an IEnumerator variable and reference it with your coroutine to invoke it.&lt;/p&gt;

&lt;p&gt;In the example below, since the while loop will always be true, the coroutine will continue executing after waiting for two seconds.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InfiniteLoopCoroutine : MonoBehaviour
{
   IEnumerator myCouroutine;

   void Start(){
       myCouroutine= InfiniteLoop(2f);
       StartCoroutine(myCouroutine);
   }

   IEnumerator InfiniteLoop(float seconds){
       while(true){
           yield return new WaitForSeconds(seconds);
           Debug.Log(&quot;Inside infiniteLoop&quot;);
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please note that WaitForSeconds uses a float parameter divided by Time.timeScale. We do this so we can mimic a real second on the game’s device.&lt;/p&gt;

&lt;h3 id=&quot;how-to-stop-a-coroutine&quot;&gt;&lt;strong&gt;How to stop a coroutine&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Now we have a coroutine that has an infinite loop. But how do we make it stop?&lt;/p&gt;

&lt;p&gt;You can stop a running coroutine with the StopCoroutine method, which will accept either of the following as a parameter:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A string with the name of the coroutine&lt;/li&gt;
  &lt;li&gt;An IEnumerator reference of your coroutine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, in the previous example, we could do:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;StopCoroutine(&quot;InfiniteLoop&quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or…&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;StopCoroutine(myCoroutine);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A coroutine will also stop if the object that it’s attached to is disabled by SetActive(false) or by destroying the object with Destroy().&lt;/p&gt;

&lt;p&gt;The following example will stop the coroutine when the player presses the Space key.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine;

public class InfiniteLoopCoroutine : MonoBehaviour
{
   IEnumerator myCouroutine;

   void Start(){
       myCouroutine= InfiniteLoop(2f);
       StartCoroutine(myCouroutine);
   }

   IEnumerator InfiniteLoop(float seconds){
       while(true){
           yield return new WaitForSeconds(seconds);
           Debug.Log(&quot;Inside infiniteLoop&quot;);
       }
   }

   void Update(){
       if (Input.GetKeyDown(KeyCode.Space))
       {
           StopCoroutine(&quot;InfiniteLoop&quot;);
           Debug.Log(&quot;Coroutine stopped&quot;);
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;pausing-games-with-coroutines&quot;&gt;&lt;strong&gt;Pausing games with coroutines&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;A popular way of pausing a game in Unity is by setting Time.timeScale equal to 0. This sets the property that Unity uses to measure time based on the device running the game.&lt;/p&gt;

&lt;p&gt;Keep in mind that this is all in a game/unity project environment, so it’s not equivalent to the time in the real world.&lt;/p&gt;

&lt;p&gt;When Time.timeScale is set to 0, the game pauses and the Update method is no longer being executed in each frame. Every animation being executed is stopped and every moving object that was using timescale stops in place.&lt;/p&gt;

&lt;p&gt;For coroutines, this is a little different.&lt;/p&gt;

&lt;p&gt;If you are executing a coroutine in a loop and it’s still going when Time.timeScale is set to 0, the coroutine will keep going but WaitForSeconds will not.&lt;/p&gt;

&lt;p&gt;WaitForSeconds uses Time.timeScale to know what a real second is. In this case, it will behave properly, but the rest of the code in the coroutine will continue executing.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine;

public class TimeStop : MonoBehaviour
{
   // Start is called before the first frame update
   void Start()
   {
       StartCoroutine(PrintEverySecond());
   }

   // Update is called once per frame
   void Update()
   {
       if(Input.GetKeyDown(KeyCode.Space)){
           if(Time.timeScale==1.0){
               Debug.Log(&quot;Time Stop&quot;);
               Time.timeScale=0.0f;
               StartCoroutine(PrintOnStop()); //We start a new coroutine after stopping time.
           }else{
               Debug.Log(&quot;Time Continue&quot;);
               Time.timeScale=1.0f;
           }
       }
   }

   IEnumerator PrintEverySecond(){
       while(true){
           yield return new WaitForSeconds(1.0f);
           Debug.Log(&quot;Inside Coroutine&quot;);
       }
   }

   IEnumerator PrintOnStop(){
       for(int x=0;x&amp;lt;=10;x++){
           Debug.Log(&quot;Time is stopped but I'm still running &quot;+x);
       }
       yield return null;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please keep in mind that you can stop a coroutine with StopCoroutine before pausing the game to prevent unexpected behavior.&lt;/p&gt;

&lt;p&gt;You can also stop all coroutines at the same time! We’ll go over this in the next section.&lt;/p&gt;

&lt;h3 id=&quot;using-multiple-coroutines-and-stopping-them-all-at-once&quot;&gt;&lt;strong&gt;Using multiple coroutines and stopping them all at once&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;As you know, you can execute multiple coroutines that behave differently at the same time. They can be stopped all at once by the StopAllCoroutines() method.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine;

public class MultipleCoroutines : MonoBehaviour
{
   void Start()
   {
       //You can use multiple coroutines at the same time,
       //even on the same definition.
       //Each one will behave individually.
       StartCoroutine(MyCoroutine(1f));
       StartCoroutine(MyCoroutine(3f));
       StartCoroutine(MyCoroutine(5f));
   }

   void Update(){
       //If you hit space at runtime, all the coroutines will stop
       if(Input.GetKeyDown(KeyCode.Space)){
           StopAllCoroutines();
           Debug.Log(&quot;All coroutines stopped&quot;);
       }
   }

   IEnumerator MyCoroutine(float sec){
       while(true){
           yield return new WaitForSeconds(sec);
           Debug.Log(&quot;I'm on a loop that prints every &quot;+sec+&quot; seconds&quot;);
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;StopAllCoroutines() doesn’t take a parameter for stopping all the coroutines in the game at the same time.&lt;/p&gt;

&lt;h3 id=&quot;coroutines-vs-threads&quot;&gt;&lt;strong&gt;Coroutines vs. threads&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Keep in mind that coroutines are not threads. Any synchronous code executed in a coroutine will be on the main thread.&lt;/p&gt;

&lt;p&gt;If you want to use threads for consuming an HTTP request, for example, you can use async methods.&lt;/p&gt;

&lt;p&gt;Here’s an example of consuming an HTTP request using coroutines:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine.Networking;
using UnityEngine;

public class HTTP_Request_Example : MonoBehaviour
{
   void Start()
   {
       //Consume an HTTP request with a coroutine
       //It happens on the main thread, which might cause the UI
       //to be unresponsive for a bit
       StartCoroutine(MyRequest(&quot;www.google.com&quot;));
   }

   IEnumerator MyRequest(string url){
       using (UnityWebRequest request = UnityWebRequest.Get(url))
       {
           //Fetches a page and displays the number of characters of the response.
           yield return request.SendWebRequest();
           Debug.Log(&quot;Page length: &quot;+request.downloadHandler.text.Length);
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Although there are a lot of examples of this approach, it’s not ideal for this kind of situation when you don’t have full control of the time responses of these external APIs.&lt;/p&gt;

&lt;p&gt;Here’s the same example using an asynchronous method instead:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-cs&quot;&gt;using System.Collections;
using UnityEngine.Networking;
using UnityEngine;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;

//By default, UnityWebRequest is not async, so you will need this extension
//Credit goes to: https://gist.github.com/mattyellen/d63f1f557d08f7254345bff77bfdc8b3
public static class ExtensionMethods
{
   public static TaskAwaiter GetAwaiter(this AsyncOperation asyncOp)
   {
       var tcs = new TaskCompletionSource&amp;lt;object&amp;gt;();
       asyncOp.completed += obj =&amp;gt; { tcs.SetResult(null); };
       return ((Task)tcs.Task).GetAwaiter();
   }
}

public class HTTP_Request_Async_Example : MonoBehaviour
{
   void Start()
   {
       //Invoke a new thread when the web request will happen without blocking the UI
       ConsumeWebRequest();
   }

   async void ConsumeWebRequest(){
       Debug.Log(await MyRequest(&quot;www.google.com&quot;));
   }

   async Task&amp;lt;string&amp;gt; MyRequest(string url){
       using (UnityWebRequest request = UnityWebRequest.Get(url))
       {
           //Fetches a page and displays the number of characters of the response.
           await request.SendWebRequest();
           string response = &quot;Page length: &quot;+request.downloadHandler.text.Length;
           return response;
       }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Out of the box, Unity uses its own networking package called UnityEngine.Networking.&lt;/p&gt;

&lt;p&gt;By default, this package is not asynchronous. If you use it inside of a coroutine, it could potentially lock the main thread of your app, resulting in some unexpected behavior.&lt;/p&gt;

&lt;p&gt;The second example will use its own thread and leave the main thread free for the player. The game will feel like it’s running as smoothly as ever!&lt;/p&gt;

&lt;h3 id=&quot;additional-thoughts&quot;&gt;&lt;strong&gt;Additional thoughts&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Coroutines are very resource-efficient, so don’t be afraid of trying them out. If you end up in a situation where you have too many coroutines at the same time, you might need to double-check your design for solutions. Two or three coroutines in the same objects that really need them could be enough.&lt;/p&gt;

&lt;p&gt;There are a lot of examples of using coroutines with WebRequest out there, but, in general, if you have to consume external resources that your project can’t control (like the time it takes a server to answer your request), it’s a good idea to use asynchronous methods instead of coroutines. This is because coroutines execute synchronous code and might use the main thread, resulting in a bad experience for your players.&lt;/p&gt;

&lt;p&gt;I’m not saying that async/ await are better than coroutines in Unity, they both are great tools. It really depends on your design and choices about when and where to use them. A general rule of thumb could be that for internal processes, use coroutine and for external processes, use asynchronous methods.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Coroutines are a great tool to have on your belt. They can help you set up the level for your players in front of their eyes, make smooth transitions between events, or create new functionality for you to impress your players.&lt;/p&gt;

&lt;p&gt;I hope you found this article useful and liked reading it as much as I enjoyed writing it!&lt;/p&gt;

&lt;p&gt;Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">How I got into the Game Industry</title><link href="https://ucamo.github.io/2022/05/13/how-i-got-into-the-game-industry.html" rel="alternate" type="text/html" title="How I got into the Game Industry" /><published>2022-05-13T00:00:00+00:00</published><updated>2022-05-13T00:00:00+00:00</updated><id>https://ucamo.github.io/2022/05/13/how-i-got-into-the-game-industry</id><content type="html" xml:base="https://ucamo.github.io/2022/05/13/how-i-got-into-the-game-industry.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_1.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;How I got into the game industry&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hello, my name is Uriel, I’m a .Net Developer that recently changed jobs from Custom/Enterprise software development into Video Games after 9 years. This is how I did it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This is all from my perspective working 10 years as a Full Stack Developer in Mexico, then applying for Game Development jobs, and finally getting into a game company in Sweden.&lt;/p&gt;

&lt;h2 id=&quot;a-little-background&quot;&gt;&lt;strong&gt;A little background&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;I got into software development because I really liked computers, and most of all, I really love video games, I thought that if I got into software development I could end up making games someday.&lt;/p&gt;

&lt;p&gt;The video game industry is hard, so unless a large AAA company in your country is accepting students or internship regularly, or you have the time/resources to fund your own games and are totally OK with not making any profits for awhile, it’s going to be difficult to break into the game industry, simply right after learning how to program.&lt;/p&gt;

&lt;p&gt;So during college and after that I worked as a Software developer doing pretty much everything needed, so my skills were pivoting into Enterprise software development and my tech stack was C#, MS SQL Server and ReactJS, I ended up as a full stack developer.&lt;/p&gt;

&lt;p&gt;During those times, I really wanted to make games, so I kept my day job as a web dev, and in my spare time, I started making my own games as a hobby.&lt;/p&gt;

&lt;p&gt;It was great! I was using the skills that I learned during the day to do the actual stuff that I wanted to make during the night, I would come up with an idea for a small game and I would continue working on it until it was “good enough” to ship it to the Play Store.&lt;/p&gt;

&lt;h2 id=&quot;creating-a-portfolio&quot;&gt;&lt;strong&gt;Creating a portfolio&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_2.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Creating a video game portafolio&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The hard truth is that if you want to work on games as a Software developer, you have to make games, there is no other way around it. So the best way to do it is making small games from start to finish. Ship those games and make it very accessible so others to play those games and give you feedback about it.&lt;/p&gt;

&lt;p&gt;If you are saying you have experience making games, your best shot is to prove it having a &lt;a href=&quot;https://ucamo.github.io/&quot;&gt;portfolio&lt;/a&gt; where you have an easily accessible way of showing up the games you have worked on. Those games can be very small, like the ones you make on game jams, they can be very ugly, they can use placeholder art, the most important thing about those games is that the games are finished. Showing something complete is way better that showing something as a concept.&lt;/p&gt;

&lt;p&gt;This of course doesn’t mean you can’t show a &lt;a href=&quot;https://www.whatgamesare.com/vertical-slice.html&quot;&gt;vertical slice&lt;/a&gt; of a game idea you have, those are totally great too!&lt;/p&gt;

&lt;p&gt;Basically, what recruiters want to see on your portfolio is that you do what you say you can do.&lt;/p&gt;

&lt;h2 id=&quot;applying-to-jobs&quot;&gt;&lt;strong&gt;Applying to Jobs&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_3.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Applying to jobs in the game industry&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once I got a &lt;a href=&quot;https://ucamo.github.io/&quot;&gt;portfolio&lt;/a&gt; I was comfortable with I started applying for a jobs in the game industry.&lt;/p&gt;

&lt;p&gt;There are a lot of job boards with tons of opportunities online (&lt;a href=&quot;https://www.workwithindies.com/&quot;&gt;Work with indies&lt;/a&gt;, &lt;a href=&quot;https://jobs.gamesindustry.biz/&quot;&gt;Video Game Industry Jobs&lt;/a&gt;, &lt;a href=&quot;https://www.gamesjobsdirect.com/&quot;&gt;Games Jobs Direct&lt;/a&gt;, &lt;a href=&quot;https://www.linkedin.com/jobs/video-games-jobs&quot;&gt;LinkedIn&lt;/a&gt;), so make sure to check them out and see who they are hiring right now and where you could be a good fit, or what areas you should explore before applying for those opportunities.&lt;/p&gt;

&lt;h2 id=&quot;a-word-of-advice-here-so-you-dont-make-the-same-mistake-i-was-making&quot;&gt;&lt;strong&gt;A word of advice here, so you don’t make the same mistake I was making:&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;When I start applying for Game Dev jobs, I had experience working on Unity so I was applying for positions that used Unity like “Game Developer”, “Game Designer”, etc, all of this is very valid and you totally should bring it up if that’s your case too during an interview, but in order to work on those positions, it’s expected that you have some knowledge working in another studio full time in a professional manner. That wasn’t my case, all my game projects were made as a hobby on the side.&lt;/p&gt;

&lt;p&gt;So your best chance of getting into an interview is looking into the open positions of the game studio you are aiming to get in, and see which position you could be filling translating your current experience with what they are looking for so you can be a better match for them.&lt;/p&gt;

&lt;p&gt;This is not to discourage you, but it’s the easiest way to get you in, since as any industry, they are looking for people that can be building software in the shortest amount of time possible.&lt;/p&gt;

&lt;h2 id=&quot;what-i-was-looking-for&quot;&gt;&lt;strong&gt;What I was looking for?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;I’m acknowledging that I am privileged, I had a steady job in a great company doing web/power platform development and since I have a wife and a kid to take care of, It would be irresponsible for me to quit my day job and getting into indie game dev or taking the first opportunity that I could.&lt;/p&gt;

&lt;p&gt;When I was looking for a job in games, I was looking for positions that had:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A promising career path.&lt;/li&gt;
  &lt;li&gt;Tech that I if learned it, It could be translated into other industries (something not super niche).&lt;/li&gt;
  &lt;li&gt;Greats benefits for me and my family, better that the ones I already had, this one was non-negotiable for me.&lt;/li&gt;
  &lt;li&gt;A great work environment and life/work balance.&lt;/li&gt;
  &lt;li&gt;Remote from Mexico or with relocation to a 1st world country that is not the United States.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;getting-rejected-learn-from-it-try-again&quot;&gt;&lt;strong&gt;Getting rejected, learn from it, try again&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_4.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Getting rejected in a job interview or applying for a job&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I knew that changing careers wouldn’t be easy, so I prepared for it and made myself a promise that I would get 100 rejections before quitting (and try again later), so between 2020 and 2021 I was applying to Game dev jobs if something was looking promising. I probably sent more than 100 applications, but I heard back with a negative response at least 70 times.&lt;/p&gt;

&lt;p&gt;I really appreciate the feedback that I got, and even the times that it was an automatic message, having that closure was great, so I wouldn’t be worried that my application was still being reviewed or something.&lt;/p&gt;

&lt;p&gt;Having feedback is great because it let you know where you can improve, I was tweaking my resume and portfolio according to the feedback I was receiving, and also I was studying more in the areas that I was having trouble during the interviews.&lt;/p&gt;

&lt;p&gt;There is no way around it, you have to apply for jobs, get rejected, adjust your strategy and try again until you are done.&lt;/p&gt;

&lt;h2 id=&quot;turn-yourself-into-the-best-candidate-you-can-be&quot;&gt;&lt;strong&gt;Turn yourself into the best candidate you can be&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_5.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Turn yourself into the best candidate you can be&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With rejections and feedback you can plan ahead your next move, for me, it was something like “I need to prove that I know what I’m talking about, even if I haven’t work in another game studio besides my own”&lt;/p&gt;

&lt;p&gt;So i came up with a Road map, a spreadsheet to visualize what requirements the positions I was looking for needed and where I was standing regarding those requirements.&lt;/p&gt;

&lt;p&gt;Here’s one of the first positions I was aiming for (orange means that I failed)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_6.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;An spreadsheet showing up basic information of a job offer with dates marked as I applied to it&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I would give 6 months between tries on the same company so I kept track on dates that I was applying to&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here are the requirements for that position, I put everything that I was comfortable with on green, and in orange stuff that I would need to study to.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_7.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;A table with a list of technical requirements for a job position, there is green when I felt that I know about the subject and orange records when I felt that I was missing something&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then I made a list of Activities that would help me understand those subjects, and a list of Deliverables and little steps that would help me learn it. It would also help me to feel a sense of accomplished when I was painting what it was done in green.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_8.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;A Spreadsheet with a list of technical topics focused on Unity, and a list of actions that once done, would gave me a better grasp of the topic in that row.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This exercise resulted in:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It helped me to study&lt;/li&gt;
  &lt;li&gt;It helped me creating my portfolio.&lt;/li&gt;
  &lt;li&gt;Gave the chance to start writing technical posts that I wanted to write.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tips-for-the-interview-process&quot;&gt;&lt;strong&gt;Tips for the Interview process&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/how_i_got_into_the_game_industry/img_9.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Tips for the interview process.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I think for people looking to break into the video game industry and coming from smaller countries outside of the United States, China and the European Union, the biggest challenge is being considered for those jobs, even get your resume read by a human can be challenging, so I would recommend to remove any note of your Country/location from your resume before starting applying for jobs, obviously, your current country will come up during the process, but in doing so, you will avoid the automatic HR programs that discard candidates outside specific locations.&lt;/p&gt;

&lt;p&gt;In the specific case of programming jobs, what you might expect for the process is something like:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;An initial phone screening to check your background and get to know you better.&lt;/li&gt;
  &lt;li&gt;A second interview with the team or a technical interviews, sometimes the steps are different in different companies, sometimes the second interview is a chat with who might be your manager, and sometimes it’s a technical interview. You can always ask to your recruiter about what’s the next step going to look like and if they have tips about what kind of question they might ask. Let’s remember that the interviewer WANT you to be hired, so ask for as much help as you can.&lt;/li&gt;
  &lt;li&gt;Once you pass the technical interview, you are “almost” there, sometimes you will still need to have your Team fit interview, or you might already have it, so the next step is a chat with a manger regarding career goals or what to expect in that position. Just be confident with yourself and be honest about it, in this step you can also ask as much questions as you want, you are also interviewing them.&lt;/li&gt;
  &lt;li&gt;If everyone gives you the thumbs up, you will move forward and will be on the final step: The job offer, with your salary, benefits and everything about the position. We are not going to talk a lot about the offer because it’s an extensive subject that would need it’s own post.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;In a technical interview&lt;/strong&gt; you might be ask to solve 1 to 3 problems in the language of your choice or a language that’s relevant for the position you are applying to, they also might have a “take home” assignment, that’s basically a mini project that you need to finish by a certain date provided for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In a team fit interview&lt;/strong&gt; they would pair you with one or two members of the team that you might be part of, this interview can include some technical or behavioral questions from the team to you, but remember that you can also ask questions about the organization and how the team handles specifics situations in the day to day job.&lt;/p&gt;

&lt;p&gt;The goal of a team fit interview is to know that you are going to be a great part of the team as well as you are going to be comfortable working with team, remember that this step is a two way street, you can ask as many questions as you want if you have some time, they want to get to know you and make sure you are a good fit for them.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;When you don’t have a full time job as a video game developer, changing into the video game industry can be hard, but not impossible. I think this is some of the core aspects that helped me switching careers.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;English as a second language. Most of IT jobs out there require a medium to advance level of English, game development is not different, and it’s a great investment in your future.&lt;/li&gt;
  &lt;li&gt;Have something to show in your portfolio. Small Games, Vertical slices, video game reviews, tutorials, something made by you that can differentiate you from other candidates.&lt;/li&gt;
  &lt;li&gt;Networking. It doesn’t necessary mean assist to in-person events (although it can be fun!), but you can join different discord servers about game development until you find a community that’s a good fit for you.&lt;/li&gt;
  &lt;li&gt;Get involved. Besides networking, I helped our local branch of Unity User Group in setting up meetings (back when we still could!), I didn’t know a lot about Unity back in those days but I wanted to be part of the community so I was there listening to the speakers and helping them out in anything I could do.&lt;/li&gt;
  &lt;li&gt;Don’t be afraid to apply for jobs. Even if you don’t feel 100% qualified for a job, you’ll never know if you’re a good fit for them until you try. Employers have some leeway for a great candidate and I’m sure he’ll be an excellent one if he puts his mind to it. Being rejected can be daunting, but you’ll never learn if you never try.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If changing careers is something you feel like doing so, I wish you all the best, and hope that this have been helpful to you. Feel free to &lt;a href=&quot;https://twitter.com/El_Tutsi&quot;&gt;reach out&lt;/a&gt; if you have any questions!&lt;/p&gt;

&lt;p&gt;Happy Gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">Postmortem: Dots of War</title><link href="https://ucamo.github.io/2021/01/27/postmortem-dots-of-war.html" rel="alternate" type="text/html" title="Postmortem: Dots of War" /><published>2021-01-27T00:00:00+00:00</published><updated>2021-01-27T00:00:00+00:00</updated><id>https://ucamo.github.io/2021/01/27/postmortem-dots-of-war</id><content type="html" xml:base="https://ucamo.github.io/2021/01/27/postmortem-dots-of-war.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_1.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of War Postmortem&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://medium.com/@carrillouriel/postmortem-dots-of-war-1193fb9c1767&quot;&gt;Originally published in spanish on Oct 17,2020&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lunarcrown.com/dotsofwar/&quot;&gt;Dots of War&lt;/a&gt; is a fast online strategy game for mobile devices, it is based on the game &lt;a href=&quot;https://en.wikipedia.org/wiki/Dots_and_Boxes&quot;&gt;Dots and Boxes&lt;/a&gt; and the objective is to conquer the majority of the map by connecting four lines to score points. Once you capture a part of the map, your player’s energy rises and with it you can make special abilities that will allow you to affect your opponent’s turn.&lt;/p&gt;

&lt;p&gt;Dots of War was the first game that was made by the &lt;a href=&quot;http://lunarcrown.com/&quot;&gt;LunarCrown&lt;/a&gt; studio, an independent video game studio based in Hermosillo Sonora, Mexico founded by other local studios in an effort to professionalize our work and reach a wider audience.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/dkBLGVO7Sc4&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;em&gt;Dots of War Trailer&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;how-do-we-choose-the-theme&quot;&gt;&lt;strong&gt;How do we choose the theme?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_2.jpeg&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war early game design sketches&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Early game design sketches&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like most of the decisions that were made in the project, we relied on votes. At the beginning of the project, we asked ourselves to pitch 1 or 2 proposals that we would like to develop as the first game, then we explained them to the team and at the end we would vote for the one that seemed easier to implement, interesting to work on and that we would like to work on.&lt;/p&gt;

&lt;p&gt;From all these pitches the winner was to recreate the game of Dots and Boxes and give it a twist by gaining power-ups to affect the rival.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_3.jpeg&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots and boxes witches game&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_4.jpeg&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war prototype characters a king, a warrior and a witch&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_5.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots and boxes concept art with robots&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Early game design sketches&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After that a “mood board” (a board to inspire us) was made about the type of artistic decisions that would be made, something to point out about how we would like the game to look like, where several photographs were placed to inspire us, &lt;a href=&quot;https://www.pinterest.com.mx/jose3892/puntos/&quot;&gt;you can see the mood board here&lt;/a&gt;, the Professor Layton saga and Advance Wars were a great inspiration for the look and feel we gave to Dots of War.&lt;/p&gt;

&lt;h3 id=&quot;how-long-do-we-though-the-project-would-last&quot;&gt;&lt;strong&gt;How long do we though the project would last?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Initially we thought that the project would last around 3 months, however, once we had the art of the game we decided to extend the development time “a little bit longer” to deliver a better quality product, that would become a process of around 9 months.&lt;/p&gt;

&lt;h3 id=&quot;how-do-we-divide-the-worktimetaskstalent-on-the-project&quot;&gt;&lt;strong&gt;How do we divide the work/time/tasks/talent on the project?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Initially the project began with 8 members, 3 programmers, 2 3D artists, 1 2D artist (who also had the task of art director), a person in charge of user experience and quality, and a person in Game Design and 2D art.&lt;/p&gt;

&lt;p&gt;But like other decisions, each time the team made a proposal for change we took into account what was agreed by the majority, within each sub-team the final decision was left within them, taking into account the opinions that were gave, we did not want to influence decisions that we were not very sure of the opinion we were giving.&lt;/p&gt;

&lt;p&gt;At the beginning, these positions did not exist but we let it be known what type of role we felt most comfortable to work during the project, taking into account the abilities of each person and the area in which we would like to collaborate.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_6.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war stone character&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From the beginning, we decided that this would be a project that we would have to complete in our spare time, when we were not attending our main responsibilities with our work and family.&lt;/p&gt;

&lt;p&gt;Therefore, each week during a small call of 15–30 minutes, we would update our progress during the project and we would end up clarifying how many hours we were going to be able to dedicate to the project that week, normally, it would be 6 to 10 hours per week.&lt;/p&gt;

&lt;p&gt;We respect each member’s time a lot and we didn’t want them to feel that a lot of time was being demanded from them, so we let each member take responsibility for their time.&lt;/p&gt;

&lt;p&gt;To divide the tasks, we used &lt;a href=&quot;https://trello.com/&quot;&gt;Trello&lt;/a&gt;, where each member could select the task they wanted to work on based on their talents and what needed to be done at that time.&lt;/p&gt;

&lt;h3 id=&quot;how-do-we-calculate-how-much-it-costs-to-make-a-game&quot;&gt;&lt;strong&gt;How do we calculate how much it costs to make a game?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;At the beginning of the project, we asked everyone involved to calculate how much they would charge for an hour of their work, that amount would be multiplied by the hours worked in a week, we would take 4 weeks as a month, and that would be the cost of “a month of development”.&lt;/p&gt;

&lt;p&gt;Given that Dots of War was a hobby project, that money would not come from any investor and would be “absorbed” by us, at the end of the day we wanted to know how much it would cost us to make a game of these features between the team. This excersie gave us an idea of the real cost of production for a game like this.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_7.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war human character&quot; /&gt;&lt;/p&gt;

&lt;p&gt;$ 27,650 Mexican pesos (about 1,370 USD) was the average cost per month to maintain the team, this without counting any other operating expenses, licenses or computer equipment, those 27 thousand virtual pesos would be exclusively to pay salaries.&lt;/p&gt;

&lt;p&gt;If the project lasted 3 months, the calculation would be: 3 x $ 1,370 = $ 4,110 USD That would be the amount that the game should earn as profit to come out in black numbers if we had invested in real money wages.&lt;/p&gt;

&lt;p&gt;Every month that we go overboard with the game’s release, $ 1,370 USD should be added to pay for that month’s wages.&lt;/p&gt;

&lt;p&gt;Properly, in a real project, you should have a monetization strategy to try to earn 5 times the development cost, giving a total of: $ 20,550 USD which would keep LunarCrown with enough money to pay the salaries, licenses and the development of the following game.&lt;/p&gt;

&lt;p&gt;As we will see throughout this article, we will find out how we failed to reach those goals.&lt;/p&gt;

&lt;h3 id=&quot;create-an-mvp&quot;&gt;&lt;strong&gt;Create an MVP&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Once we had defined the idea of ​​the game we wanted to do and the tasks that had to be completed to launch the game, we decided to make a Minimum viable product (MVP) or Proof of concept (POC) that is simply to implement the basic mechanics of the game to test it internally and see if it was actually fun.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_8.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war first prototype MVP&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;First version of Dots of War&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The player can connect two dots with a line&lt;/li&gt;
  &lt;li&gt;The player can make a square by connecting four points with lines&lt;/li&gt;
  &lt;li&gt;The game identifies that it is a “square” and gives a score to the player who closed it.&lt;/li&gt;
  &lt;li&gt;The game identifies when it is the turn of each of the two players.&lt;/li&gt;
  &lt;li&gt;The game ends when there are no more possible moves to make and determines which of the two players is the winner.&lt;/li&gt;
  &lt;li&gt;The player can choose to play again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this was done with very rudimentary placeholder art, a user interface that would not be the final but that would help us to know what was happening “behind the scenes” of our game.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_9.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war first prototype MVP two player local&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once we had the basic mechanics of the game, we knew that we could finish such a game and the next thing would be to polish the game to make it more fun and add the art.&lt;/p&gt;

&lt;h3 id=&quot;scope-creep-first-signs-and-how-to-deal-with-them&quot;&gt;&lt;strong&gt;Scope creep first signs and how to deal with them&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Scope creep is a term used in projects when the scope of the project begins to extend from a small project to a larger and larger project.&lt;/p&gt;

&lt;p&gt;It is very easy to get carried away by the hype of wanting to add more features to a game, but it is also part of the responsibility and professionalism of the members to know how to recognize when the project should be adjusted to what has been agreed to and respect the time of everyone in the team.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_10.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war wizard character&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At LunarCrown, we care a lot about the team’s time, so we highly respect the time they put into the project and we like to know that we are making the most of it.&lt;/p&gt;

&lt;p&gt;Once we had the MVP and had a Dots and boxes game that worked and was for two players, making it stand out was part of the next task.&lt;/p&gt;

&lt;p&gt;This can be achieved thanks to amazing art, interesting visuals, or unique mechanics that would set it apart from the rest of the games of this genre.&lt;/p&gt;

&lt;p&gt;But in each of those aspects, it’s easy to get carried away and want to add “just one more thing.”&lt;/p&gt;

&lt;p&gt;For example, in Dots of War you can choose 3 different heroe classes to play, each class has at least 1 2D skin to represent it (with the option to buy additional skins) and 3 3D models to represent when they have captured an area in the game map.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_11.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war 3d prototype Pre alpha build&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pre-Alpha build of Dots of War&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was very tempting for the team to say “Let’s add another class”, but that represents:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create more 2D assets.&lt;/li&gt;
  &lt;li&gt;Balance the character selection user interface (or code a workaround for the selection menu that accommodates each new character, which would also take unbudgeted time)&lt;/li&gt;
  &lt;li&gt;Create 3 extra 3D models.&lt;/li&gt;
  &lt;li&gt;Make a complete regression test with the new combinations between classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_12.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war stone character color&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At times like that we can ask ourselves as a team: Is it really necessary to add a new character? Will it add more value to our game? Is it worth the reward that we will receive in exchange for the effort that has to be made? Are there other pending goals that we could be achieving instead?&lt;/p&gt;

&lt;p&gt;Game development is full of decisions that are not fun, but that have to be made in order for the project to be completed in the end.&lt;/p&gt;

&lt;p&gt;At the start of the project, each class also had a “special ability”, this ability could be used when the player gained 3 energy points and those energy points were obtained by capturing adjacent squares, the amount varied depending on the class.&lt;/p&gt;

&lt;p&gt;Aside from their special ability, all classes have a common ability called “block” that when used, the opponent cannot continue their turn after capturing a square.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Humans could spend their 3 energies to steal a square from the opponent.&lt;/li&gt;
  &lt;li&gt;Stonemen could lock their squares to be un-stealables.&lt;/li&gt;
  &lt;li&gt;Wizards could block a line so that only they could use it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having a special ability for each player was very attractive to the team and to the game, but that functionality had to be programmed individually by each class and tested several times against different combinations of players to balance them.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_13.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war wizard using his special ability&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wizard using his special ability&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Special abilities became a very big problem, the game had to keep moving forward, the programming team had to finish implementing that functionality and test it to see if the mechanics were balanced and if the game became more or less fun with it.&lt;/p&gt;

&lt;p&gt;Something that happens in game development is that we focus so much on the project that sometimes we can no longer trust if what we are trying over and over again is still fun, so we must constantly be testing with people outside the team to listen fresh feedback and opinions.&lt;/p&gt;

&lt;p&gt;Explaining the mechanics of class abilities was so difficult for outside players that the best decision we had was to cut that aspect of the game.&lt;/p&gt;

&lt;p&gt;We had invested a lot of time on this feature, and we still didn’t know if this other great piece of game design was going to fit in with the core mechanic or if it was going to have some detrimental effect when players realized that a certain class had an advantage over others.&lt;/p&gt;

&lt;p&gt;There was an internal vote to talk about this feature, and an agreement was reached to remove it from the game and only leave the general blocking ability for all classes, at this point all classes are the same.&lt;/p&gt;

&lt;h3 id=&quot;make-an-online-game&quot;&gt;&lt;strong&gt;Make an online game&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Some would think that the most difficult part of the project was the online mode, but thanks to plugins like &lt;a href=&quot;https://medium.com/@carrillouriel/unity-multiplayer-tutorial-using-photon-pun-fa6f86e44c44&quot;&gt;Photon&lt;/a&gt; this part was relatively simple.&lt;/p&gt;

&lt;p&gt;In the original scope of the project we wanted to make a game that was multiplayer online, no team member had done a project like this before and it was really challenging for us.&lt;/p&gt;

&lt;p&gt;Very early in the design of the game (and several times it was recommended by acquaintances outside of game development) the option of creating our own client-server logic was contemplated to have a more complete control of the game. It was agreeded not to use our own solution since we didn’t have the estimated time for doing so, and at the end it wouldn’t add value of our end goal.&lt;/p&gt;

&lt;p&gt;We built the online interaction to be scalable in case in future versions we decided to create our own API for it, but for now, no one was going to commit to leaving the development of the game to create those pieces, so we voted not to do it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_14.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war human character color art&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Photon is a tool that manages the logic of receiving and transmitting information from clients to servers.&lt;/p&gt;

&lt;p&gt;It has a free plan that allows you 20 concurrent connections, if there are more than 20 players playing the game at the same time, it begins to deny the service to those who are arriving, but as an account administrator, you can decide at what time to upgrade your account and allow more concurrent connections.&lt;/p&gt;

&lt;p&gt;We concluded that, for an MVP and as an initial version, the free version of Photon would serve us quite well, and that if we had the “problem” that more than 20 players were playing at the same time, it would be worth upgrading, but for now we would monitor the number of concurrent players and we would evaluate the situation according to the data we have.&lt;/p&gt;

&lt;p&gt;The way we implement the logic for the online game is quite simple.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First we finished the whole game so that it could be played with only one person.&lt;/li&gt;
  &lt;li&gt;Then we did the logic for the game to be played with 2 people using the same device and thus see how the turns behaved.&lt;/li&gt;
  &lt;li&gt;Once we polish that part, we create the online mode, where a room is created and we wait for another player to connect, once inside the room the game begins and determines who is player 1 and who is player 2 .&lt;/li&gt;
  &lt;li&gt;The actions of each player are transmitted to the network, and the game is designed to receive the actions and show the same interaction regardless of the devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-devil-is-in-the-details&quot;&gt;&lt;strong&gt;The devil is in the details&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;So what happens when you already have a game, the art is in place, and you already have the online game mechanics in place?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You have to finish the game.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That last 10% to finish a project of this type where you have to correct the bugs, finish doing the complete regression tests, create the images for the stores where the game will be published, prepare the optimized text with ASO (App Store Optimization) So that it has a good ranking in each store, do your best to translate your images and text into other languages, prepare a trailer, and a list of tasks that are not technical but have to be done.&lt;/p&gt;

&lt;p&gt;It is hard to finish a game and when you have invested so much time in a project you can focus a lot on one aspect and start neglecting others, so it is important that team members have a clear goal of what they want to achieve.&lt;/p&gt;

&lt;p&gt;The development of Dots of War began in July 2019 and by October we already had an MVP and from then on it would be a matter of polishing it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_15.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war wizard character color art&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We started the project with 3 programmers, but before the first three months the programming team was reduced to 1 since one programmer had to move to another city for a better job, and another was cut from his job and we understood that making games as a hobby it wasn’t going to be their priority for the next few months.&lt;/p&gt;

&lt;p&gt;At LunarCrown we always think of people first before work, and at the end of the day, it was a joint time that we were giving for the project, so there were no misunderstandings, they remained part of the team and gave their feedback but they were not assigned tasks each week.&lt;/p&gt;

&lt;h3 id=&quot;do-you-know-what-happened-in-late-2019-and-early-2020-too&quot;&gt;&lt;strong&gt;Do you know what happened in late 2019 and early 2020 too?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;COVID-19&lt;/strong&gt; pandemic affected all industries and all jobs included where 2 team members worked, they had to reduce staff, so one was fired, and the one who remained had to take the work from several positions.&lt;/p&gt;

&lt;p&gt;So once again certain tasks were going to be put on hold while everything settled down and they had more free time to dedicate to the project.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_16.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war stone vs human match&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I believe that at this point, more than one person would have put this project on hold and rethink the scope, or perhaps release a simpler game, or some other solution.&lt;/p&gt;

&lt;p&gt;In our case, the art team had finished their assignments, and had done such a good job that it seemed like a waste not to finish Dots of War.&lt;/p&gt;

&lt;p&gt;So we decided to go a little slower but still keep going. After all, the game was almost done, only that last 10% was missing.&lt;/p&gt;

&lt;h3 id=&quot;the-worst-mistake-we-made&quot;&gt;&lt;strong&gt;The worst mistake we made&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_17.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war human samurai skin&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Optional Samurai Skin for Humans&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We are a team that likes to share updates, bugs and other details during the development process of a game, Dots of War was no exception, we did not have a pre-established Marketing campaign apart from the diffusion that we gave to the game with acquaintances, relatives and on social networks.&lt;/p&gt;

&lt;p&gt;We liked to participate in posts where progress was shared or in #screenshotsaturday.&lt;/p&gt;

&lt;p&gt;Given the great progress we had, we made what I consider to be the biggest mistake during the entire project development process.&lt;/p&gt;

&lt;h3 id=&quot;commit-to-a-game-release-date&quot;&gt;&lt;strong&gt;Commit to a game release date.&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;At the end of March 2020 we calculated what had to be done (include the purchases of skins in the game and do the whole submit process for iTunes) and we guess the date when we would have everything ready, so we implemented it and started the submission process to iTunes.&lt;/p&gt;

&lt;p&gt;In this part I was going to comment on a long list of things that displeased me about the process that Apple has to submit its applications but I prefer to summarize it with:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have nothing good to say about the app development process for Apple or its platform.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For people interested in publishing their game with &lt;a href=&quot;https://unity.com/&quot;&gt;Unity&lt;/a&gt; on iOs, here are some tips we learned the hard way.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Have a Mac on hand with the version of Unity you are developing on, there are options such as Unity Cloud build but if there is a slight possibility that you have to alter a configuration file for iOs, get a mac with someone you know or member of your team.&lt;/li&gt;
  &lt;li&gt;The change on status of your application take time, nobody knows how long they can take and you have no control over how long it may take.&lt;/li&gt;
  &lt;li&gt;Keep in mind that iOs is very selective with the plugins that you can use in your project, sometimes certain plugins can alter some permissions of your application that will give you a headache once they start rejecting your application and tracking the error code that apple sends you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;why-do-i-say-that-giving-a-release-date-was-the-worst-mistake-we-made&quot;&gt;&lt;strong&gt;Why do I say that giving a release date was the worst mistake we made?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Because we really didn’t have the need to give a launch date, we could have launched in the same way on some other date and there would have been no problem or angry reviews, coming up with a launch date puts extra weight on the team and on this case it was a Hobby project, no one was asking or expecting one except us.&lt;/p&gt;

&lt;h3 id=&quot;burnout&quot;&gt;&lt;strong&gt;Burnout&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;During this project I had to take two breaks due to the burnout (or exhaustion / fatigue syndrome) that I felt, one in December to have the opportunity to spend more time with my family, and another in May, when the pandemic was on the rise and the stress I had from working manifested itself as a rash on the skin of my hands that so far has not completely gone away (constantly washing my hands and putting alcohol on them to prevent COVID doesn’t help either)&lt;/p&gt;

&lt;p&gt;Right before launch we did the media outreach by sending personalized emails to about 200 websites to cover the launch, we fixed the latest bugs, and we were able to launch the game.&lt;/p&gt;

&lt;h3 id=&quot;when-you-realize-that-the-last-10-is-actually-the-last-30&quot;&gt;&lt;strong&gt;When you realize that the last 10% is actually the last 30%&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_19.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war stone robot skin&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once we launched the game and had the external impressions, we noticed some minor bugs, and a major one (the skins could not be bought), we had a group of alpha users who helped us a lot during development, but we never tested directly that part with them, only internally.&lt;/p&gt;

&lt;p&gt;At that time, since we saw that the effort to contact the press did not give the results we expected (we ended up being covered by some portals, but in general many websites ask you for money to cover your game, money that we did not have budgeted for, so we had to miss that opportunity) and having the whole team really tired, we decided to take a few days to rest, and return to the project with fresher eyes.&lt;/p&gt;

&lt;p&gt;In the end the errors were corrected and the project was complete in its first version, we had made a game together with a 100% remote team and we finished Dots of War.&lt;/p&gt;

&lt;h3 id=&quot;what-to-do-in-case-of-fire&quot;&gt;&lt;strong&gt;What to do in case of fire?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;We had an entire marketing strategy planned before launch that included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Attend local events&lt;/li&gt;
  &lt;li&gt;Attend national video game development events&lt;/li&gt;
  &lt;li&gt;Make public presentations where attendees could test the game, give us their comments, win prizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But any face-to-face activity was totally ruled out as of March 2020 here in Mexico when the quarantine plans officially began.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_20.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of war wizard cowboy skin art&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Being a team that already worked remotely, it did not affect us at the time of work but we were quite affected in other areas, both in our formal work and in our interpersonal relationships, there were months of a lot of personal stress so we didn’t asked anyone to do more work than they were comfortable with and we relaxed the notion of due dates quite a bit.&lt;/p&gt;

&lt;p&gt;Even so, working your full shift from home, taking care of your family and working on a project like this, even if it is a hobby, takes a price on one, many team members experience burnout to a greater or lesser extent.&lt;/p&gt;

&lt;p&gt;The best thing to do in these cases is to take a step back, take a deep breath and evaluate what your priorities are, take time to rest and when we are in a better state of mind, continue.&lt;/p&gt;

&lt;p&gt;We are very grateful to be part of a team that understands and is responsible for its members, who knows how to demand results but who also really cares about the person who is delivering them, after all, we started as a group of friends. with a common goal, and our relationship is more important than any project.&lt;/p&gt;

&lt;h3 id=&quot;what-did-we-learn-how-can-we-end-this-on-a-happy-note&quot;&gt;&lt;strong&gt;What did we learn? How can we end this on a happy note?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The development of Dots of War is not a commercial or media success story, but it is a success story for game development on remote teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any game that is completed is a success.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many opportunity areas in Dots of War, but we are also very happy with what we achieved, a precedent was made for this type of development, no funds, no third-party money injections, no loans or government aid, all valid ways to start making games, but not the only ones.&lt;/p&gt;

&lt;p&gt;There will always be a way to move a project forward, and not even a pandemic or the end of the world can stop it.&lt;/p&gt;

&lt;h3 id=&quot;what-could-have-gone-much-worse&quot;&gt;&lt;strong&gt;What could have gone much worse?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Good and bad decisions were made during the development of Dots of War, some based on time and some based on money.&lt;/p&gt;

&lt;p&gt;Long before starting this project, we talked to team members about creating a game for PC and consoles with a development model very similar to what we had (but including an office provided by a group of investors), in the middle of the development of Dots of War we realized that if we had committed ourselves to making that game with that much larger scope, it would have placed us in a much more difficult situation and not at all redeemable as this project was.&lt;/p&gt;

&lt;p&gt;We are very happy with the results we had and with the decisions we made, but we are also very happy with the other decisions that we did not make.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_21.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;LunarCrown logo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;&lt;strong&gt;What’s next?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;As a final note, we want to thank everyone involved during the development of Dots of War, all beta and alpha testers, the &lt;a href=&quot;https://www.facebook.com/UnityHmo/&quot;&gt;Unity user group HMO&lt;/a&gt; community that supported us from the beginning, the people who found out about the project and they gave their words of encouragement to us and to all Dots of War players.&lt;/p&gt;

&lt;p&gt;Thank you very much, we did the best we could at the time that we could.&lt;/p&gt;

&lt;p&gt;Now as we recover from burnout, it becomes clear to us that there will always be more games to do, a next project to do and when you develop as a hobby and to learn, you do not have to be accountable to anyone.&lt;/p&gt;

&lt;p&gt;It‘s OK to learn from our experiences and not think that they were a failure, it’s OK to take a step back or stay for a while to catch your breath, everyone advances at their own pace and we are very happy to know that we keep trying.&lt;/p&gt;

&lt;p&gt;For &lt;a href=&quot;http://lunarcrown.com/&quot;&gt;LunarCrown&lt;/a&gt; there are surely more projects, but given the current situation, we do not know what form they may take in the immediate future, but we are sure that we will count on each other to continue supporting each other.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/postmortem_Dots_of_War/img_22.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Dots of War logo&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;credits&quot;&gt;Credits&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Game Design, 2D art&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Arvin Valenzuela&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UX-UI, Quality Assurance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jose Miguel Angulo&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Art Director, 2D art&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.instagram.com/carlosnlart/&quot;&gt;Roberto Carlos Nuñez&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3D art&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.instagram.com/rojasmariel/&quot;&gt;Mariel Rojas Pérez&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://smirelesz.artstation.com/&quot;&gt;Sergio Mireles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programming&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gatomocho.com/&quot;&gt;Antonio Martinez&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://ucamo.github.io/&quot;&gt;Uriel Carrillo&lt;/a&gt;&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">Unity Best Practices</title><link href="https://ucamo.github.io/2021/01/10/unity-best-practices.html" rel="alternate" type="text/html" title="Unity Best Practices" /><published>2021-01-10T00:00:00+00:00</published><updated>2021-01-10T00:00:00+00:00</updated><id>https://ucamo.github.io/2021/01/10/unity-best-practices</id><content type="html" xml:base="https://ucamo.github.io/2021/01/10/unity-best-practices.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_best_practices/img_1.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Best Practices&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this post, we are going to list a series of Best practices to use while working on a Unity Project, please keep in mind that not all of these practices are the necesary to include in each project, and as you get more experience working on Unity, you will get a better judgment about when or which ones to use for your own projects.&lt;/p&gt;

&lt;h3 id=&quot;project-organization&quot;&gt;&lt;strong&gt;Project Organization&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Project Folders&lt;/strong&gt;
Try to keep your scripts in an organized way, something that can be easy for you to navigate to when looking for a specific script, having multiple folders inside your script folder is also a good way to keep your logic organized.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_best_practices/img_2.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Project folder structure best practices&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Some assets or pluggins from the Unity Asset Store, will include a Folder called “Scripts” whith their own scripts from another author, to prevent confusion, name the script folder for your project something that makes sense to you plus it’s easily described for your project (I go with “MyScripts” because those are scripts made by me)&lt;/p&gt;

&lt;h3 id=&quot;grouping-objects-in-the-hierarchy&quot;&gt;&lt;strong&gt;Grouping Objects in the Hierarchy&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_best_practices/img_3.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Hierarchy best practices&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_best_practices/img_4.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity child game objects&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To avoid clutter in your Hierarchy window, you can drag and drop Game Objects inside each other to group them, doing so let you expand the “parent” Game Object and still have control for the childs.&lt;/p&gt;

&lt;p&gt;If you don’t want to have the parent-child relationship, you can add an Empty Object as a Holder for all the childs, just to have a cleaner look in your Hierarchy window.&lt;/p&gt;

&lt;h3 id=&quot;general-tips&quot;&gt;&lt;strong&gt;General Tips&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use source control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unity projects can get mesy really fast, and having the ability to “make everything as it was before” it’s a huge time saver.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://ucamo.github.io/2020/12/01/how-to-use-git-with-unity.html&quot;&gt;I personally recomend Git and wrote another article about how to use it with Unity.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;While working on a Team project, make some ground rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Out of the box, Unity doesn’t really like that 2 or more persons are updating the same Scene or Prefab at the same time. Make sure that everyone that it’s going to interact with the scene has the latest version and will only change something specific and push their changes to the repository.&lt;/p&gt;

&lt;p&gt;Have somebody in charge of putting all together in case that a merge conflict it’s in place. After the merge conflict is resolved, talk with your team about it in order to prevent those, everyone should be on the same page regarding what’s need to be changed.&lt;/p&gt;

&lt;p&gt;A general rule of thumb is, if you update something, and other stuff got updated but you didn’t intend to update it, leave it out of your commit, and reverse it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep the same version of Unity for your project across your team&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If somebody has a newer or lower version of the team that the rest, this might cause unnecesary and unexpected behavior while other member tries to open the project, Unity will try to update the version of the project and this might cause something to broke, it’s relative easy to fix, but this is totally unnecesary.&lt;/p&gt;

&lt;p&gt;Using the latest long-term support release of Unity (LTS) it’ recommended for most projects, unless you are planing to use some super-specific feature that is in an unstable version, or not fully integrated to the Edior yet, thats totally not a bad thing!, but just keep in mind that everyone is aware of the version that your project is using.&lt;/p&gt;

&lt;p&gt;While in mid-project, updating to a newer version should be done if that’s absolutely necesary. Unity Hub let’s you handle multiple versions of the Editor, so you can have for example, One project that started with Unity 2019, and it will stay with that version until completion, and having newer projects with Unity 2020. It’s up to the team to decide.&lt;/p&gt;

&lt;h3 id=&quot;working-with-prefabs&quot;&gt;&lt;strong&gt;Working with Prefabs&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Prefabs are your friends&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prefabs make it easier to make changes without changing the scene, try to work with prefabs as much as posible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prefabs reference&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While reference an instance of Game Object, this should be made from a Prefab to Prefab and not between instances on the scene.&lt;/p&gt;

&lt;p&gt;That’s it for today, Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry><entry><title type="html">Unity Multiplayer Tutorial using Photon PUN</title><link href="https://ucamo.github.io/2020/12/27/unity-multiplayer-tutorial-using-photon-pun.html" rel="alternate" type="text/html" title="Unity Multiplayer Tutorial using Photon PUN" /><published>2020-12-27T00:00:00+00:00</published><updated>2020-12-27T00:00:00+00:00</updated><id>https://ucamo.github.io/2020/12/27/unity-multiplayer-tutorial-using-photon-pun</id><content type="html" xml:base="https://ucamo.github.io/2020/12/27/unity-multiplayer-tutorial-using-photon-pun.html">&lt;p&gt;&lt;strong&gt;Photon&lt;/strong&gt; is a networking engine and multiplayer platform that can handle all the requests on their servers, and through the Unity (or other game engines) we can consume it, add the logic in our projects, focus on gameplay and features and let the part of the networking to Photon.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_1.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon PUN totorial&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PUN (Photon Unity Networking)&lt;/strong&gt; is one out of the box solution for handling multiplayer on Unity Projects, in this tutorial, we are going to lear how to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a Room for other players to connect to&lt;/li&gt;
  &lt;li&gt;Having up to 20 players connect to the same game&lt;/li&gt;
  &lt;li&gt;Learn how can the players can interact with each other through custom actions and affect our game.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the end of this tutorial, we are going to learn how to create a simple game with this features, and learn how we can scale it to add more features in the future.&lt;/p&gt;

&lt;p&gt;I recommend that you check out the &lt;a href=&quot;https://github.com/Ucamo/Unity-Photon-PUN-Tutorial&quot;&gt;&lt;strong&gt;Github repository for this tutorial&lt;/strong&gt;&lt;/a&gt; if you want to get more details as you read by, but we are still going to go step by step about how to achieve a Unity game with a multiplayer feature, &lt;a href=&quot;https://el-tutsi.itch.io/unity-photon-pun-tutorial&quot;&gt;you can also check out a live version of this tutorial here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, we would need to create a Photon account &lt;a href=&quot;https://www.photonengine.com/en-US/Photon&quot;&gt;over here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we are done with that, we can go To &lt;strong&gt;Dashboard &amp;gt; Public Cloud &amp;gt; Your Applications&lt;/strong&gt; and we are going to click on &lt;strong&gt;“Create a New App”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are going to choose &lt;strong&gt;“Photon PUN”&lt;/strong&gt; for &lt;strong&gt;“Photon Type”&lt;/strong&gt; and write a unique name on the field, after that we can fill out the rest of the optional fields and click on &lt;strong&gt;“Create”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_2.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unityh Photon pun create app&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This will create our Application on Photon, that we will need for the next steps on this tutorial, whate we want from here is the &lt;strong&gt;“App ID”&lt;/strong&gt; if we click on the numbers, the rest of the Id will show up, and we can copy it for later use.&lt;/p&gt;

&lt;p&gt;Here on the dashboard we can also get access to the metrics of how the app has been used, how many &lt;strong&gt;CCU (Concurrently Connected Users)&lt;/strong&gt; have been connected accross all the rooms in your game.&lt;/p&gt;

&lt;p&gt;Photon have a &lt;strong&gt;free tier&lt;/strong&gt; that lets us test it (or go live if we want) with &lt;strong&gt;20 CCU&lt;/strong&gt; and we can choose to upgrade whenever we want, I personally think this is a great deal as Proof of concept and small games (that’s what we end up using on &lt;a href=&quot;https://medium.com/@carrillouriel/postmortem-dots-of-war-1193fb9c1767&quot;&gt;Dots of War&lt;/a&gt;), also if you want to upgrade to 100 CCU the &lt;a href=&quot;https://assetstore.unity.com/packages/tools/network/photon-pun-2-120838&quot;&gt;Photon PUN 2+ Unity asset&lt;/a&gt; includes &lt;strong&gt;100 CCU&lt;/strong&gt; for &lt;strong&gt;60 months at $95 USD&lt;/strong&gt; you can also check out the pricing plans on their &lt;a href=&quot;https://www.photonengine.com/en-US/PUN/pricing&quot;&gt;official website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you feel the need to have more control over what’s going on on the server side of things, they have a solution for &lt;strong&gt;Self-Hosted servers&lt;/strong&gt;, the same implementation but instead of going to theirs servers, it goes to yours.&lt;/p&gt;

&lt;p&gt;Anyway, let’s go back to the tutorial, Let’s &lt;strong&gt;open up Unity&lt;/strong&gt; and create a new &lt;strong&gt;3D project&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&quot;part-1-creating-a-lobby&quot;&gt;Part 1: Creating a Lobby&lt;/h3&gt;
&lt;p&gt;Go to &lt;strong&gt;Window &amp;gt; Asset Store&lt;/strong&gt; (make sure you are logged in), and search for &lt;strong&gt;“Photon Pun”&lt;/strong&gt; in the searchbar. Here we are goint to select &lt;strong&gt;“PUN 2 - Free”&lt;/strong&gt; and Import it to our Project.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_3.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Photon 2 Unity Network free on the Asset store&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once we finish up importing the package, a window like this will show up:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_4.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Editor PUN setup wizzard window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;AppId&lt;/strong&gt; we are going to paste the &lt;strong&gt;AppId we got from the Photon platform that we just created&lt;/strong&gt;, and we are going to click &lt;strong&gt;“Setup project”&lt;/strong&gt;, this will link our Unity app with our Photon app.&lt;/p&gt;

&lt;p&gt;If we go to &lt;strong&gt;Window &amp;gt; Photon Unity Networking &amp;gt; Highlight Server Settings&lt;/strong&gt; we can configure our Unity app a little more.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_5.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Editor PhotonServerSettings window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For this Tutorial, I changed the &lt;strong&gt;“Fixed Region”&lt;/strong&gt; property to &lt;strong&gt;“us”&lt;/strong&gt; (United states) that will make all the connection to my Unity Game throught that region.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The way regions works on Photon&lt;/strong&gt; is that it will evaluate which region is the &lt;strong&gt;best fit&lt;/strong&gt; for the player that is connecting on our Game, that way it can reduce the lag and have an overall better experience in-game for all players.&lt;/p&gt;

&lt;p&gt;However, since this is a demo, and it can happen that somebody in Australia and somebody in Canada can connect at the same time, if we leave the “Fixed Region” as blank, it will evaluate that the each person will be part of different region,and they wouldn’t be able to be part of the same Room and thus, not being able to play together.&lt;/p&gt;

&lt;p&gt;You can read more about &lt;strong&gt;Photon Regions&lt;/strong&gt; &lt;a href=&quot;https://doc.photonengine.com/en-us/pun/current/connection-and-authentication/regions&quot;&gt;over here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Creating a multiplayer game from scratch can be overwhelming, so for this Tutorial, we are going to use some of the pre-made assets from this package, and implment the bare minimum in our own in order to make it easier to diggest.&lt;/p&gt;

&lt;p&gt;Let’s re-name our &lt;strong&gt;default scene&lt;/strong&gt; as &lt;strong&gt;“Lobby”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_6.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon Demo Scene Lobby&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;lobby&lt;/strong&gt;, there is going to be 5 elements to a &lt;em&gt;Canvas&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Number Of Players”&lt;/strong&gt; and &lt;strong&gt;“Status Text”&lt;/strong&gt; are going to be replaced with their values at runtime, being the number of players that are connected to the app at the same time (CCU) and &lt;strong&gt;“Status text”&lt;/strong&gt; will help us to show up in which part of the process our game is on, this is helpful because when we are debugging multiplayer games ourselves, we need a builded version of the game and our Editor version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Enter your Name…”&lt;/strong&gt; it’s an input text that will write up a &lt;strong&gt;PlayerPref&lt;/strong&gt; with our name to differentiate when we are online.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Join Room”&lt;/strong&gt; will start the process of Joining or Creating a Room, and if everything works right, will change us to the gameplay scene.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Leave Room”&lt;/strong&gt; will disconnect us from the current Room.&lt;/p&gt;

&lt;p&gt;For creating this simple menu, &lt;strong&gt;I Right clicked on the Hierarchy Window&lt;/strong&gt;, and select &lt;strong&gt;UI &amp;gt; Canvas&lt;/strong&gt; and inside of the canvas I added the rest of the controllers.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_7.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon Hierarchy window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;On The &lt;strong&gt;Hierarchy Window, create an empty object&lt;/strong&gt; by right clicking on it and click on &lt;strong&gt;“Create Empty”&lt;/strong&gt;. Rename it to &lt;strong&gt;“NetworkController”&lt;/strong&gt; and look for a component called &lt;strong&gt;“NetworkController”&lt;/strong&gt; (From the &lt;strong&gt;Photon assets&lt;/strong&gt;) and attach it to your empty GameObject.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_8.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity NetworkController inspector window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;NetworkController&lt;/strong&gt; class will connect to Photon at the Start() event using our configured settings.&lt;/p&gt;

&lt;p&gt;All our Scripts for this tutorial will be on the &lt;strong&gt;Assets &amp;gt; Scripts&lt;/strong&gt; Folder.&lt;/p&gt;

&lt;p&gt;Let’s create an &lt;strong&gt;Empty Object&lt;/strong&gt; and Rename it &lt;strong&gt;PhotonLobby&lt;/strong&gt;, and add the Script from that Folder called &lt;strong&gt;PhotonLobby.cs&lt;/strong&gt;, we are going to fill it out with elements from our Canvas.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_9.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity PhotonLobby inspector tab&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s add the &lt;strong&gt;“OnClick”&lt;/strong&gt; events from our &lt;strong&gt;btnJoin&lt;/strong&gt; Button and &lt;strong&gt;btnLeave&lt;/strong&gt; Button like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_10.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity PhotonLobby OnClick join event&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;btnJoin Button OnClick Event&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_11.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity PhotonLobby OnClick leave event&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;btnLeave Button OnClick Event&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Also, let’s make sure our &lt;strong&gt;“Name InputField”&lt;/strong&gt; looks like this in the inspector&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_12.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Player Name Input Field&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Player Name Input Field” is a script in the Photon Folder&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;PhotonLobby&lt;/strong&gt; class it’s commented so feel free to &lt;a href=&quot;https://github.com/Ucamo/Unity-Photon-PUN-Tutorial&quot;&gt;read the explanation of each method&lt;/a&gt;, but basically it show and hide the &lt;strong&gt;btnJoin/btnLeave&lt;/strong&gt; button as needed in order to prevent trying to connect multiple times at the same Room.&lt;/p&gt;

&lt;p&gt;It also:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Show up the number of players connected to our Unity game&lt;/li&gt;
  &lt;li&gt;Try to Join a Random Room, but if it fails to do so (because there is none or otherwise) it will Create a new Room.&lt;/li&gt;
  &lt;li&gt;If it fails to create a Room, it will try again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s create a &lt;strong&gt;new Empty GameObject&lt;/strong&gt; and rename it to &lt;strong&gt;“PhotonRoom”&lt;/strong&gt;, and add the component &lt;strong&gt;“PhotonRoom”&lt;/strong&gt; to it from the &lt;strong&gt;Assets &amp;gt; Script&lt;/strong&gt; Folder, and configure it like so:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_13.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon Room inspector&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;PhotonRoom&lt;/strong&gt; class will activate once we are connected to a Room. It takes as properties indexes from the scenes of the projects, being &lt;strong&gt;Current Scene&lt;/strong&gt; (the Lobby) Index 0, and &lt;strong&gt;“Multiplayer Scene”&lt;/strong&gt; 1 (our GameScene scene that we will create in a bit)&lt;/p&gt;

&lt;p&gt;This class waits for the event &lt;strong&gt;“OnJoinedRoom”&lt;/strong&gt; to be triggered when we sucessfully connect to or Create a Room. And loads up which scene is the one with the actual game on it.&lt;/p&gt;

&lt;p&gt;That’s the first part, creating the Lobby, now &lt;strong&gt;let’s create a new Scene&lt;/strong&gt; and call it &lt;strong&gt;“GameScene”&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;part-2-creating-a-game-scene&quot;&gt;Part 2: Creating a Game Scene&lt;/h3&gt;

&lt;p&gt;Since this Tutorial is focused on how to implement PUN, we are going to use some of the Prefabs for the Gameplay part of this demo.&lt;/p&gt;

&lt;p&gt;Let’s create an &lt;strong&gt;Empty Game Object&lt;/strong&gt; in our GameScene Hierarchy window, and we will add the Component &lt;strong&gt;GameManager.cs&lt;/strong&gt; to it&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_14.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Editor Game manager script inspector&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s add on &lt;strong&gt;“Player Prefab”&lt;/strong&gt; a Prefab made by Photon called &lt;strong&gt;“My Robot Kyle -done-”&lt;/strong&gt; that is on the &lt;strong&gt;Assets/Photon/PhotonUnityNetworking/Demos/PunBasics-Tutorial/Resources&lt;/strong&gt; Folder.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_15.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Kyle Photon PUN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is Kyle&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;GameScene&lt;/strong&gt;, let’s create a &lt;strong&gt;Plane&lt;/strong&gt; on &lt;strong&gt;Position 0,0,0&lt;/strong&gt; so kyle don’t end up falling once it’s spawned.&lt;/p&gt;

&lt;p&gt;I ended up creating a basic scene with a plane and walls so the players don’t fall over&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_16.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Demo scene Photon PUN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to change a little bit &lt;strong&gt;GameManager.cs&lt;/strong&gt; , we are going to change the name of the scenes in the script to match the ones we have in our project like so:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_17.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon Load Scene Lobby&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_18.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon On load scene lobby&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_19.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon Load Scene Game Scene&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GameManager&lt;/strong&gt; makes sure that the player is connected to a room, if it’s not, it will load up the &lt;em&gt;“Lobby”&lt;/em&gt; scene where we connect to a Room. If it it’s connected, it will load up the &lt;strong&gt;“GameScene”&lt;/strong&gt; scene.&lt;/p&gt;

&lt;p&gt;So now, before testing, let’s go to &lt;strong&gt;File &amp;gt; Build Settings&lt;/strong&gt; and make sure our scenes are added to the Settings like so and hit the Play Button on Unity.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_20.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Build Settings&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We are going to be redirected to the &lt;strong&gt;Lobby&lt;/strong&gt; like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_21.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Lobby Photon PUN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And if we fill out the Name input with our name and click &lt;strong&gt;Join Room&lt;/strong&gt;, we will see something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_22.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon PUN kyle set up the name of the player&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That is, if we made a ground for our robot to land on.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;want-to-see-something-cool&quot;&gt;Want to see something cool?&lt;/h3&gt;

&lt;p&gt;Let’s test the game with two players connected at the same time, for this, we will need to build our game, I recommend trying with a standalone windows or mac version first since it’s easier to iterate that with other builds, but Photon is platform agnostic, so it any platform should be working the same.&lt;/p&gt;

&lt;p&gt;So let’s go to &lt;strong&gt;File &amp;gt; Build Settings&lt;/strong&gt; we choose the &lt;strong&gt;PC, Mac &amp;amp; Linux Standalone&lt;/strong&gt; platform and we click on &lt;strong&gt;“Build”&lt;/strong&gt;, and we wait for the build to be complete.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_23.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon PUN two players interacting&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Left Unity Editor, Right Standalone Build.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then we launch the &lt;strong&gt;.exe&lt;/strong&gt; project and the &lt;strong&gt;editor&lt;/strong&gt; at the same time. That’s pretty much what’s needed for having two or more players connected to the same Game with Unity using Photon PUN.&lt;/p&gt;

&lt;p&gt;You might have noticed those &lt;strong&gt;extra buttons&lt;/strong&gt; I added on the GameScene, that’s the final topic I would like to talk about.&lt;/p&gt;

&lt;h3 id=&quot;how-can-players-interact-with-each-other&quot;&gt;How can players interact with each other?&lt;/h3&gt;

&lt;p&gt;In this tutorial, we have different players in the same room, but what about interacting with each other through the game?&lt;/p&gt;

&lt;p&gt;To achieve this, we will need something like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A Player does an action&lt;/li&gt;
  &lt;li&gt;The action get’s sended over to the server&lt;/li&gt;
  &lt;li&gt;All the rest of the Players (clients) receive the info of that action and it get’s replicated on their own game.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what’s called a &lt;strong&gt;Remote Procedure Calls&lt;/strong&gt; or &lt;strong&gt;RPC&lt;/strong&gt; this is basically a way for a method to be invoked on the clients of the same room.&lt;/p&gt;

&lt;p&gt;For this tutorial, we are going to do a really simple and quick example of an RPC Method, and you can learn about all the other options for them or came up with different implementation reading the &lt;a href=&quot;https://doc.photonengine.com/en-us/pun/v2/gameplay/rpcsandraiseevent&quot;&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On our &lt;strong&gt;GameManager&lt;/strong&gt; object, let’s add our own script from &lt;strong&gt;Assets &amp;gt; Script&lt;/strong&gt; called &lt;strong&gt;GamePlayController&lt;/strong&gt; to it, we also are going to &lt;strong&gt;txtNumberToIncrease&lt;/strong&gt; Text GameObject from the &lt;em&gt;Canvas&lt;/em&gt; to it, and add a &lt;strong&gt;Photon View Component&lt;/strong&gt; with the &lt;strong&gt;Add Component&lt;/strong&gt; button while selected.&lt;/p&gt;

&lt;p&gt;You &lt;strong&gt;GameManager GameObject&lt;/strong&gt; should look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_24.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Editor Game Manager inspector Photon PUN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Canvas&lt;/strong&gt;, I also added a new &lt;strong&gt;UI Button&lt;/strong&gt; and called it &lt;strong&gt;btnAction&lt;/strong&gt;, and on their &lt;strong&gt;OnClick&lt;/strong&gt; Event I set it up to the &lt;strong&gt;IncreaseNumber&lt;/strong&gt; Method from the &lt;strong&gt;GamePlayController&lt;/strong&gt; class referenced by the &lt;strong&gt;GameManager&lt;/strong&gt; GameObject&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_25.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon GameManager onClick setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;GamePlayController&lt;/strong&gt; Class have a very simple implementation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_26.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity code GamePlay Controller&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It References the PhotonView Component at the Start() Event, needed in order to call and receive RPC&lt;/li&gt;
  &lt;li&gt;It reflects the globalNumber variable in the Update() Event to show always the latest value.&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;IncreaseNumber()&lt;/strong&gt; Method will locally call our RPC Method (marked with [PunRPC], the second parameter “RpcTarget.AllViaServer” refers that it will call the &lt;strong&gt;RPC_IncreaseNumber()&lt;/strong&gt; Method for all the clients, but firstly will reach out the main server, so all the clients will receive the same message in &lt;strong&gt;order&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Finally the &lt;strong&gt;RPC_IncreaseNumber&lt;/strong&gt; Method will be called by &lt;strong&gt;Photon&lt;/strong&gt; to execute the order, in this case, increasing the &lt;strong&gt;globalNumber&lt;/strong&gt; variable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_Multiplayer_Tutorial_using_Photon_PUN/img_27.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Photon PUN RPC example increase a number&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While clicking on any of the “Increase Number” buttons, the Number to increase goes up for all the clients&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s it! you just created a multiplayer game!&lt;/p&gt;

&lt;h3 id=&quot;where-to-go-from-here&quot;&gt;Where to go from here?&lt;/h3&gt;

&lt;p&gt;RPC are super powerfull, and need to be designed in a way that makes sense for your game, you can pass parameters to it, serialize information through clients, and make all kinds of actions with them, this tutorial just cover the very basic for it just to get you started and not feel overwhelm by all this new information.&lt;/p&gt;

&lt;p&gt;While designing your game you should take into consideration what kind of actions would the player be able to do, and how would the rest of the players in the room are going to be affected by those actions.&lt;/p&gt;

&lt;h3 id=&quot;whats-something-to-keep-in-mind-while-using-photon&quot;&gt;What’s something to keep in mind while using Photon?&lt;/h3&gt;

&lt;p&gt;As you can see, implementing Photon in your Unity game is very easy, you have your free tier to prototype and play around with it, but you should also think on the way it can &lt;em&gt;scalate&lt;/em&gt; and &lt;em&gt;design a business plan&lt;/em&gt; on how the game could be profitable to pay for the plans if there is need of increasing the number of CCU in your game.&lt;/p&gt;

&lt;p&gt;Personally, I think it’s a great service, having the option to relay on a third party service to handle all the networking events, scalability, downtimes, responses, regions, match making, it’s truly a great way to get started in the world of multiplayer games, that doesn’t mean that you can’t implement your own solution instead of using the ones on Photon, it’s not an all-or-nothing, you can implement some features and having the rest of the features being handled by yourself.&lt;/p&gt;

&lt;p&gt;I hope that this tutorial has been helpful, and if you want to check out the source code for it, feel free to do so in the Github Repository.&lt;/p&gt;

&lt;p&gt;Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html">Photon is a networking engine and multiplayer platform that can handle all the requests on their servers, and through the Unity (or other game engines) we can consume it, add the logic in our projects, focus on gameplay and features and let the part of the networking to Photon.</summary></entry><entry><title type="html">Unity Cinemachine + Timeline Tutorial</title><link href="https://ucamo.github.io/2020/12/22/unity-cinemachine-timeline-tutorial.html" rel="alternate" type="text/html" title="Unity Cinemachine + Timeline Tutorial" /><published>2020-12-22T00:00:00+00:00</published><updated>2020-12-22T00:00:00+00:00</updated><id>https://ucamo.github.io/2020/12/22/unity-cinemachine-timeline-tutorial</id><content type="html" xml:base="https://ucamo.github.io/2020/12/22/unity-cinemachine-timeline-tutorial.html">&lt;p&gt;Unity has some major features regarding handling animation and Cinemachine and Timeline are modules that will give you the tools to create cinematics in your game, camera switching, custom mini-animations, or whole projects that are just animation like &lt;a href=&quot;https://www.youtube.com/watch?v=iQZobAhgayA&amp;amp;ab_channel=Unity&quot;&gt;The Heretic short film.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_1.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Cinemachine Timeline Tutorial&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to create the basics of a little cinematic animation, using Cinemachine and Timeline with 3 different shots and angles to familiarize with the process.&lt;/p&gt;

&lt;p&gt;You can think of &lt;em&gt;Timeline&lt;/em&gt; like where all the planification of the shot takes place, it handles the animation events, can trigger sounds, keep track of changes and switches the objects, and can be used to interpolate between changes in the camera for smoother transitions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cinemachine&lt;/em&gt; it’s a set of tools that enhance the Unity cameras with different features, make them dynamic, smart and without the need of adding extra code, and works great with timeline out of the box too!&lt;/p&gt;

&lt;p&gt;You can follow along to create your first project with Cinemachine and Timeline, &lt;a href=&quot;https://github.com/Ucamo/Unity-Cinemachine-Timeline&quot;&gt;or you can download my repository to see how it was implemented.&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;creating-a-cinematic&quot;&gt;Creating a cinematic&lt;/h3&gt;
&lt;p&gt;First, let’s open Unity, we are going to create a &lt;em&gt;new empty 3D project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then, we need to enable &lt;em&gt;Cinemachine&lt;/em&gt; and timeline for your new project. By going to &lt;em&gt;Window &amp;gt; Package Manager&lt;/em&gt;, and make sure that Timeline and Cinemachine are “Selected” on the right checkbox, any version should work, but I would recommend the latest stable.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_2.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity package manager&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you don’ see Cinemachine at first, you can search the package in the &lt;em&gt;“in Project”&lt;/em&gt; tab, and change it to &lt;em&gt;“Unity Registry”&lt;/em&gt; that will make the other optional packages to show up, and you can search for Cinemachine from the list.&lt;/p&gt;

&lt;p&gt;After this, and since we were going to upload our project to &lt;a href=&quot;https://github.com/Ucamo/Unity-Cinemachine-Timeline&quot;&gt;Github&lt;/a&gt;, I decide to not use assets that I didn’t have the license to re-publish in other platforms, so today’s example it’s going to be with a 3D cube , so let’s add a 3D cube to our scene, by right clicking the &lt;em&gt;Hierarchy&lt;/em&gt; window and select &lt;em&gt;3D object &amp;gt; Cube.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I ended up adding a &lt;em&gt;3D Object &amp;gt; Plane&lt;/em&gt; too, just to give a little more of sense and I scale it up to look like a ground where the 3D cube will be on.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_3.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Two 3d cubes in unity&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The hero of our next big hit&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s re-name our cube by right-clicking the cube and selecting &lt;em&gt;“Rename”&lt;/em&gt;, I rename it to &lt;em&gt;“AnimatedCube”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then, we are going to start animating our cube directly on the timeline, to do so, Open up the &lt;em&gt;Timeline&lt;/em&gt; window by going to &lt;em&gt;Window &amp;gt; Sequencing &amp;gt; Timeline.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_4.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity timeline empty&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And let’s create an &lt;em&gt;Empty GameObject&lt;/em&gt; in our &lt;em&gt;Hierarchy&lt;/em&gt; Window, by right clicking and select &lt;em&gt;“Create Empty”&lt;/em&gt;. Let’s rename that new empty Game Object to “Timeline”, that would work as the controller of our scene.&lt;/p&gt;

&lt;p&gt;While having our “Timeline” object, go to the Timeline window and click on &lt;em&gt;“Create”&lt;/em&gt; on the following option.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_5.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity timeline create director component&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then, as you do with making new animations, a prompt will show up asking you to name your &lt;em&gt;.playable&lt;/em&gt; object and save it in a location within your project, you can name it as you want, I name it “cutscene”.&lt;/p&gt;

&lt;p&gt;Once created, click on the three dots that appear in you animator by default, and delete it&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_6.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity timeline options&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then, &lt;em&gt;right click&lt;/em&gt; on that space and create a new &lt;em&gt;“Animation Track”&lt;/em&gt;. This track on Timeline, will handle the animations in our cube. Since this is an entirely new project, the cube doesn’t have animation, so in this example we are going to animate it ourselves.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drag and drop your 3D cube&lt;/em&gt; into the &lt;em&gt;“GameObject {Animator}”&lt;/em&gt; of the &lt;em&gt;Animation Track&lt;/em&gt;. This will assign the 3D cube to the track and will let us animate it.&lt;/p&gt;

&lt;p&gt;If we hit the &lt;em&gt;red circle in our track&lt;/em&gt;, we are going to &lt;em&gt;“Record”&lt;/em&gt; whatever it happens with our 3D cube, in this example, hit the Record button, and move the 3D cube around every 40 or 60 frames, then change directions.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_7.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity 3d cube moving with timeline on third person view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please not that at the bottom, the keyframes are marked where the movement stoped and continue.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now we are using Timeline, if we wanted to involve more objects in our shot, we would need to add more “Tracks” and add the animation when needed.&lt;/p&gt;

&lt;p&gt;Now, to add Cinemachine to our project. We need to select our &lt;em&gt;“Main Camera”&lt;/em&gt;, and in the Inspector window, click on &lt;em&gt;“Add Component”&lt;/em&gt; and look for &lt;em&gt;“CinemachineBrain”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_8.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity cinemachine brain setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We don’t need to do anything else with our Main Camera, but this will be used as the “Main controller” of the rest of our Cinemachine cameras.&lt;/p&gt;

&lt;p&gt;What we are going to do, as in cinema, when there is an important scene and there is some shots from different angles, and different cameras at the same time, we are going to create those extra cameras and let them know what we want from them.&lt;/p&gt;

&lt;p&gt;Let’s create our first Virtual Camera, by right clicking our &lt;em&gt;Hierarchy Window&lt;/em&gt; and select &lt;em&gt;Cinemachine &amp;gt; Virtual Camera.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; This might cause that your main camera end up not where it was before, but you can re position it whenever you want, let’s move around the Virtual Camera in an angle you like, and you will notice that there is a component on the Inspector Window called &lt;em&gt;“CinemachineVirtualCamera”&lt;/em&gt;, let’s add our &lt;em&gt;animated 3D cube&lt;/em&gt; to the &lt;em&gt;“Follow”&lt;/em&gt; and &lt;em&gt;“Look At”&lt;/em&gt; properties by drag and drop our cube into those fields.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_9.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity cinemachine virtual camera properties&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You might notice that in the &lt;em&gt;“Game”&lt;/em&gt; Window, when you have your virtual camera selected it might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_10.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity virtual camera view in editor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Those guidelines will help you in the composition of your shot, and the red border it’s a guide to let you know that the object will be harder to see in those places.&lt;/p&gt;

&lt;p&gt;Now, if you click &lt;em&gt;Play&lt;/em&gt; in Unity, you will notice that your 3D cube moves around for the animation, and the virtual camera follow it around.&lt;/p&gt;

&lt;p&gt;That’s a very easy example of how to use Cinemachine, now for mix it up with Timeline, let’s select the &lt;em&gt;“Timeline” game object&lt;/em&gt; from our &lt;em&gt;Hierarchy Window&lt;/em&gt;, and &lt;em&gt;Drag and drop our “Main Camera”&lt;/em&gt; object to create a &lt;em&gt;Cinemachine Track.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_11.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity timeline with diferent properties&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then, we can adjust where the virtual camera will come into play during the shot and by how long, but the fun begins when we add more virtual cameras.&lt;/p&gt;

&lt;p&gt;Let’s add two more Virtual cameras by &lt;em&gt;right clicking the Hierarchy window&lt;/em&gt; and select &lt;em&gt;Cinemachine &amp;gt; Virtual Camera&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Position your second virtual camera where you pleased and on the &lt;em&gt;CinemachineVirtualCamera&lt;/em&gt; of that second virtual camera, let’s make it just &lt;em&gt;“Look At”&lt;/em&gt; our cube, but not follow it&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_12.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Cinemachine virtual camera inspector&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This will give the effect of a stationary Camera that just follows a target in movement.&lt;/p&gt;

&lt;p&gt;And for the Third virtual camera, I position it in a different place in the scene and gave it this properties&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_13.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Cinemachine 3 virtual cameras&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It will work like the first Virtual Camera but from a different angle.&lt;/p&gt;

&lt;p&gt;Now, if we go back to the &lt;em&gt;Hierarchy Window&lt;/em&gt;, and select our &lt;em&gt;“Timeline” game object&lt;/em&gt;, we can add the rest of the virtual cameras to our &lt;em&gt;“Cinemachine Track”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_14.png&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Timeline in editor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And if we adjust the duration of the virtual cameras in the Cinemachine Track, we can get some very interesting result, if we try to &lt;em&gt;overlap two virtual cameras&lt;/em&gt;, it will result on Timeline, &lt;em&gt;interpolating thos two cameras into a smooth transition&lt;/em&gt;. Let’s see the result:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/Unity_cinemachine_timeline_tutorial/img_15.gif&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Timeline in editor animated with different virtual cameras&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s it, you just created your fist cinematic using Unity Cinemachine and Timeline.&lt;/p&gt;

&lt;p&gt;From now on you can play around with these basic concepts and explore the different types of Cameras from Cinemachine, and Tracks from Timeline to get some really impresive results.&lt;/p&gt;

&lt;p&gt;Hope you had like it this little tutorial and remember that you can get the whole project in my &lt;a href=&quot;https://github.com/Ucamo/Unity-Cinemachine-Timeline&quot;&gt;github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html">Unity has some major features regarding handling animation and Cinemachine and Timeline are modules that will give you the tools to create cinematics in your game, camera switching, custom mini-animations, or whole projects that are just animation like The Heretic short film.</summary></entry><entry><title type="html">Unity Cloud Build Tutorial.</title><link href="https://ucamo.github.io/2020/12/14/unity-cloud-build-tutorial.html" rel="alternate" type="text/html" title="Unity Cloud Build Tutorial." /><published>2020-12-14T00:00:00+00:00</published><updated>2020-12-14T00:00:00+00:00</updated><id>https://ucamo.github.io/2020/12/14/unity-cloud-build-tutorial</id><content type="html" xml:base="https://ucamo.github.io/2020/12/14/unity-cloud-build-tutorial.html">&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_cloud_build_Tutorial/img_1.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;Unity Cloud build tutorial&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Cloud build is a service included on Unity Teams Advance that let you set up your existing source control repository to automate the compiling, deployment and tests of your games so you can iterate quickly with your team.&lt;/p&gt;

&lt;p&gt;Basically you can set up a branch on your repository that Unity Cloud Build will pick up and deploy to the target platform/s of your choosing, you can set up different platforms (like Desktop, iOs, Android, Web) and configure an email alert that will let you know once the build has been completed of if there were some errors with it.&lt;/p&gt;

&lt;p&gt;The advantages of using Unity Cloud Build is that all of that workflow is handled by the service, giving you more time to use your local hardware in more usefull stuff (or taking a well deserved rest).&lt;/p&gt;

&lt;h2 id=&quot;what-do-you-need&quot;&gt;What do you need?&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;A Unity Teams Advance license ($9 USD per month, which include 3 team seats and 25GB of Cloud storage) or a Unity Pro license.&lt;/li&gt;
  &lt;li&gt;A Source control repository (like Git)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-do-you-set-it-up&quot;&gt;How do you set it up?&lt;/h2&gt;
&lt;p&gt;You can lear how to set up Unity Cloud build in this super easy to follow official tutorial&lt;/p&gt;

&lt;h2 id=&quot;does-this-mean-i-can-build-for-ios-without-a-mac&quot;&gt;Does this mean I can build for iOs without a Mac?&lt;/h2&gt;
&lt;p&gt;This is a tricky question. The short answer is no (sorry, I would also like this to be a Yes). But let’s elaborate on that.&lt;/p&gt;

&lt;p&gt;Yes, you can build for the iOs platform on Unity Cloud Build, but to do that, you will need the certificates that will sign up your iOs build to upload it to the App Store. So at least you will need to get access to a Mac once to get those certificates.&lt;/p&gt;

&lt;p&gt;After that, you can continue using Unity Cloud Build to make new versions of that project without the need to use a Mac. But please note that for uploading your project to the App Store, you will need to do so through XCode, so you will also need access to a Mac for that.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/Ucamo/ucamo.github.io/main/assets/images/unity_cloud_build_Tutorial/img_2.webp&quot; width=&quot;80%&quot; height=&quot;50%&quot; alt=&quot;a macbook pro in a desk&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Personally, I have been down that rabbit hole before, and comming up from a Microsoft/Windows based background, this transition was hard for me. Some stuff that I learnead along the way:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can rent a virtual mac if you don’t want to spend the money on one for you on MacInCloud to get the certificates and you can pay by the hour.&lt;/li&gt;
  &lt;li&gt;The process of uploading your game to the App Store can be long (not in time, but on multiple back and fort with the process of getting your game accepted on the App Store), so if you can get a friend or co-worker with a Mac that can help you with this process it’s super recomendable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;advantages-and-disadvantages-of-using-unity-cloud-build&quot;&gt;Advantages and Disadvantages of using Unity Cloud Build.&lt;/h2&gt;

&lt;h3 id=&quot;advantages&quot;&gt;Advantages:&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;It let you focus on the important things, like improving your game.&lt;/li&gt;
  &lt;li&gt;It’s a very straightforward way to deliver continuosly, once it’s set up, it’s done and will work until you decide to do some other changes in the way to present the build.&lt;/li&gt;
  &lt;li&gt;Building can be very time consuming, and if’s made in another computer it’s a time saver.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;disadvantages&quot;&gt;Disadvantages:&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Working with Unity and adding third party assets can mess up your automatic builds. Sometimes it can work on the editor, and in your local build, but on the remote build will fail, luckily Unity Cloud Build count with a very good log system that will let you know where the error is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This has been a very basic approach to Cloud Build but in general this is a very good way to standarize your project and get to know how continuos integration work with Unity.&lt;/p&gt;

&lt;p&gt;Hope you like it and happy gamedev!&lt;/p&gt;</content><author><name>Uriel Carrillo</name></author><category term="Other" /><summary type="html"></summary></entry></feed>