Skip to content

Instantly share code, notes, and snippets.

@antonsem
Last active August 13, 2021 09:21
Show Gist options
  • Save antonsem/1b34acd82470f34a1fd45160c180834b to your computer and use it in GitHub Desktop.
Save antonsem/1b34acd82470f34a1fd45160c180834b to your computer and use it in GitHub Desktop.
Feedback_1
public class Original_1 : MonoBehaviour
{
public int boyut;
public bool isWork;
Transform Target;
public float Speed;
public bool Flip;
// Start is called before the first frame update
void Start()
{
}
// Update is called one per frame
void Update()
{
//kaç saniyede 1 çalışır onu ayarlayın.
InvokeRepeating("ters", 6, 6);
giti();
}
public void giti()
{
if (Flip == true)
{
//12,12,12 kısmını kendi karakterinizin boyutuna göre ayarlayın.
transform.localScale = new Vector3(boyut, boyut, boyut);
transform.Translate(-1f * Speed, 0, 0);
}
if (Flip == false)
{
transform.localScale = new Vector3(-boyut, boyut, boyut);
transform.Translate(1f * Speed, 0f, 0f);
}
}
public void ters()
{
//buna dokunmayın
Flip = !Flip;
CancelInvoke();
}
}
// I talked about writing names in the local language over here:
// https://gist.github.com/antonsem/09b4f902ed22adbdf8f664fac539543f
// So I won't go into details. However, what is worse than a bad coding convention,
// is inconsistency. In this script nothing is consistent. Some names are
// Turkish, some are English. Some fields start with an upper case, while
// others with a lower case etc.
public class Original_1_Commented : MonoBehaviour
{
// Is any of these variables used outside the script? If no they should be private.
// If you want to change them from the Inspector window add [SerializeField] attribute
// before them. If you really want to access them from another script make them
// properties. See Refactored_1.cs for an example.
public int boyut;
// isWork and target are not used. Why are they here?
public bool isWork;
Transform Target;
public float Speed;
public bool Flip;
// Methods like Start, Update, OnCollisionEnter, etc. are added to a list and
// are called whenever they are supposed to be called. While it is a
// micro-optimization, and unlikely to be noticed in a real-life scenario,
// technically it harms performance. But more importantly, you don't want to fill
// your code with useless junk. It makes it harder to read. And please delete the
// default comments, they are useless and annoying...
// Start is called before the first frame update
void Start()
{
}
// Update is called one per frame
void Update()
{
// You don't want to rely on code comments. First of all the code should be
// self-documenting. Meaning a programmer should understand what a line does
// just by reading it. Reading some extra information just puts an unnecessary
// cognitive load on your brain. Second, the code can change. And unless you
// are a super disciplined programmer you WILL forget to change the comment, and
// it will be misleading. Even if you are that disciplined, it means you are a
// rare species. Even more so than a unicorn. What are the chances of you finding
// another unicorn, and work with it on the same project?
// The next issue is the usage of Invoke, InvokeRepeating, etc. Invoking methods like this
// is much more expensive than directly calling them. I made a quick test and invoking
// an empty method 1m times took about 0.56 seconds, while calling a method 1m times
// took only 0.001 seconds. So about 500 times faster. "But wait!" I hear you say,
// "I won't be invoking a method one million times per update! Why shouldn't I use it?"
// While this is another micro-optimization from the performance perspective, maintaining
// such code will be a nightmare. Just like I mentioned in my previous feedback session,
// if the name of the method changes, you won't be able to find all instances easily.
// In fact, you won't be able to find who is invoking that method without some work.
// So my advice never ever invoke methods with strings and don't use InvokeRepeating
// Finally, I don't see how it can work. This line asks to invoke a method six times
// with six-second intervals EACH FRAME. Meaning after a short period the
// "ters" method will be invoking hundreds of time each frame (but there is a plot
// twist further down).
//kaç saniyede 1 çalışır onu ayarlayın.
InvokeRepeating("ters", 6, 6);
giti();
}
// Ok, I don't even know what this method's name is. From the looks of it, it moves
// this object to specific positions. All methods should start with an upper case
// according to C# conventions. And by the looks of it, this method is only called
// from this script. So why is it public?
public void giti()
{
// If you have a bool, you don't have to compare it against true or false. Simply
// writing if(Flip) will do the job. Similarly you can write if(!Flip) instead of
// if(Flip == false). It will be easier to read.
if (Flip == true)
{
//12,12,12 kısmını kendi karakterinizin boyutuna göre ayarlayın.
transform.localScale = new Vector3(boyut, boyut, boyut);
// Why do you multiply Speed by -1? Just write -Speed.
transform.Translate(-1f * Speed, 0, 0);
}
// The Flip is a bool. So it can either be true or false. You don't have to write
// another if statement, just adds it as else to the previous one.
if (Flip == false)
{
transform.localScale = new Vector3(-boyut, boyut, boyut);
// Why do you multiply the speed by 1? It doesn't do anything.
transform.Translate(1f * Speed, 0f, 0f);
}
}
// Again, this method is not invoked from outside this script (hopefully). Why is it public?
public void ters()
{
// Yeah, "Don't touch it!" is the best comment for sure. Except it is horrible. It means
// you did something you don't understand, and if it breaks you will be helpless. Of
// course, it is easy to understand what is going on here, but unless you are in the
// middle of disarming a nuclear bomb, don't write comments like this. Just understand
// what is going on there.
//buna dokunmayın
Flip = !Flip;
// And here is the promised plot twist! This method cancels the repeated invocations,
// so it doesn't break. Let's follow the logic one more time. In the Update method, we
// tell this script to invoke this method six times in six-second periods. If this
// cancellation didn't exist, after 6 seconds this method would be invoked in each frame.
// After 12 it would be invoked twice each frame and so on. However, thanks to this
// line this method is invoked only once, and all registered invocations are canceled.
// Assuming the game runs at 60 FPS it means that this method was registered 6 x 60 = 360
// times for invocation. Then we just canceled all of them. So we registered it 359 times
// for nothing. Then the cycle starts all over again because it is in the Update method.
// TL;DR you don't want to use Invoke. And you REALLY don't want to use Invoke in the
// Update method. And you DEFINITELY, NEVER EVER want to use InvokeRepeating in an Update!!!
// All you wanted to do here is to change the value of Flip every 6 seconds.
// See the Refactored_1.cs script for that.
CancelInvoke();
}
}
public class Refactored_1 : MonoBehaviour
{
// From the looks of it, you might want to change the flip timer from outside the script
[SerializeField] private float defaultFlipTimer = 6;
[SerializeField] private float speed;
// I don't know the value you used, and I don't know if you want to change this value
// from outside of this script. I assume you don't. If you do, just add a [SerializedField]
// attribute, and remove the const.
private const int _dimensions = 5;
private bool _isRight = true;
private float _flipTimer = 0;
private void Start()
{
// You might want to reset the _flipTimer beforehand
_flipTimer = defaultFlipTimer;
}
private void Update()
{
// You want to flip the direction at a certain interval. Whenever the _flipTimer hits
// 0, it will reset, the _isRight will flip its value, and FaceDirection will be
// called with the new bool value
_flipTimer -= Time.deltaTime;
if (_flipTimer > 0) return;
_flipTimer = defaultFlipTimer;
_isRight = !_isRight;
FaceDirection(_isRight);
}
private void FaceDirection(bool isRight)
{
// If isRight is true, then do this stuff, and return
if (isRight)
{
transform.localScale = new Vector3(_dimensions, _dimensions, _dimensions);
transform.Translate(-speed, 0, 0);
return;
}
// If the value of isRight is false the method will continue here.
transform.localScale = new Vector3(-_dimensions, _dimensions, _dimensions);
transform.Translate(speed, 0f, 0f);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment