Using Principle DRY
In this Article I Will talk about DRY principle, DRY is an acronym of Don’t Repeat Yourself.
The concept by DRY is very simple to understand.
Basically, He consisting of, to eliminate unnecessary repetitions, as for example:
You have 30 different enemies, and You need to create a damage method. So do You really need 30 different methods for all enemies? With DRY this is not necessary, because with this, You only need to create a method in a script, and after You will reuse, changing only the damage parameter. This is a short abstract about DRY, So Let’s go to practice.
For this example I will use two enemies, and They also will serve for my next article, when I will talk about Refactoring, but now, my focus is DRY, You will see that DRY and Refactoring can walk together.
So here is our Enemy_1
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_1 : MonoBehaviour { float _Speed_X = 5; int _HP = 100; bool _Right_Movementation; bool _Left_Movementation; Rigidbody2D _Rdb; Vector2 _Right_Vector; Vector2 _Left_Vector; void Start() { _Right_Movementation = true; _Rdb = GetComponent<Rigidbody2D>(); _Right_Vector = new Vector2(_Speed_X, _Rdb.velocity.y); _Left_Vector = new Vector2(-_Speed_X, _Rdb.velocity.y); } void Update() { if (_Right_Movementation == true) _Rdb.velocity = _Right_Vector; if (_Left_Movementation == true) _Rdb.velocity = _Left_Vector; } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Left_Limit")) { _Right_Movementation = true; _Left_Movementation = false; } if (collision.gameObject.CompareTag("Right_Limit")) { _Right_Movementation = false; _Left_Movementation = true; } if (collision.gameObject.CompareTag("Player")) { _HP -= 15; if (_HP <= 0) print("Die"); } } }
and here is our Enemy 2
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_2 : MonoBehaviour { float _Speed_X = 5; float _Speed_Y = 5; float _Time; int _HP = 100; bool _Right_Movementation; bool _Left_Movementation; bool _Up_Movementation; bool _Down_Movementation; Rigidbody2D _Rdb; Vector2 _Right_Up_Diagonal; Vector2 _Right_Down_Diagonal; Vector2 _Left_Up_Diagonal; Vector2 _Left_Down_Diagonal; void Start() { _Left_Movementation = true; _Up_Movementation = true; _Rdb = GetComponent<Rigidbody2D>(); _Right_Up_Diagonal = new Vector2(_Speed_X, _Speed_Y); _Right_Down_Diagonal = new Vector2(_Speed_X, -_Speed_Y); _Left_Up_Diagonal = new Vector2(-_Speed_X, _Speed_Y); _Left_Down_Diagonal = new Vector2(-_Speed_X, -_Speed_Y); } void Update() { if (_Right_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Right_Up_Diagonal; if (_Right_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Right_Down_Diagonal; if (_Left_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Left_Up_Diagonal; if (_Left_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Left_Down_Diagonal; _Time += Time.deltaTime; if (_Time > 5) { _Time = 0; if (_Up_Movementation == true) { _Up_Movementation = false; _Down_Movementation = true; } if (_Down_Movementation == true) { _Up_Movementation = false; _Down_Movementation = true; } if (_Left_Movementation == true) { _Left_Movementation = false; _Right_Movementation = true; } if (_Right_Movementation == true) { _Left_Movementation = true; _Right_Movementation = false; } } } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Left_Limit")) { _Right_Movementation = true; _Left_Movementation = false; } if (collision.gameObject.CompareTag("Right_Limit")) { _Right_Movementation = false; _Left_Movementation = true; } if (collision.gameObject.CompareTag("Up_Limit")) { _Down_Movementation = true; _Up_Movementation = false; } if (collision.gameObject.CompareTag("Down_Limit")) { _Up_Movementation = true; _Down_Movementation = false; } if (collision.gameObject.CompareTag("Player")) { _HP -= 15; if (_HP <= 0) print("Die"); } } }
See that We have repetitions in change state’s variables (Enemy 2) and our damage system is repeated in both codes.
So let’s go to apply the DRY principle.
Firstmently, I will create new methods that will manage our change state’s variables. Each method will change for a side.
Here is our methods:
void Change_For_Up_Movementation() { _Up_Movementation = true; _Down_Movementation = false; } void Change_For_Down_Movementation() { _Up_Movementation = false; _Down_Movementation = true; } void Change_For_Left_Movementation() { _Left_Movementation = true; _Right_Movementation = false; } void Change_For_Right_Movementation() { _Left_Movementation = false; _Right_Movementation = true; }
Now I will apply these methods, on local that We changed state according to what was in the code.
So here is our new Enemy 2, with changes has been made:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_2 : MonoBehaviour { float _Speed_X = 5; float _Speed_Y = 5; float _Time; int _HP = 100; bool _Right_Movementation; bool _Left_Movementation; bool _Up_Movementation; bool _Down_Movementation; Rigidbody2D _Rdb; Vector2 _Right_Up_Diagonal; Vector2 _Right_Down_Diagonal; Vector2 _Left_Up_Diagonal; Vector2 _Left_Down_Diagonal; void Start() { _Left_Movementation = true; _Up_Movementation = true; _Rdb = GetComponent<Rigidbody2D>(); _Right_Up_Diagonal = new Vector2(_Speed_X, _Speed_Y); _Right_Down_Diagonal = new Vector2(_Speed_X, -_Speed_Y); _Left_Up_Diagonal = new Vector2(-_Speed_X, _Speed_Y); _Left_Down_Diagonal = new Vector2(-_Speed_X, -_Speed_Y); } void Update() { if (_Right_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Right_Up_Diagonal; if (_Right_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Right_Down_Diagonal; if (_Left_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Left_Up_Diagonal; if (_Left_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Left_Down_Diagonal; _Time += Time.deltaTime; if(_Time > 5) { _Time = 0; if(_Up_Movementation == true) { Change_For_Down_Movementation(); } if (_Down_Movementation == true) { Change_For_Up_Movementation(); } if(_Left_Movementation == true) { Change_For_Right_Movementation(); } if (_Right_Movementation == true) { Change_For_Left_Movementation(); } } } void Change_For_Up_Movementation() { _Up_Movementation = true; _Down_Movementation = false; } void Change_For_Down_Movementation() { _Up_Movementation = false; _Down_Movementation = true; } void Change_For_Left_Movementation() { _Left_Movementation = true; _Right_Movementation = false; } void Change_For_Right_Movementation() { _Left_Movementation = false; _Right_Movementation = true; } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Left_Limit")) { Change_For_Right_Movementation(); } if (collision.gameObject.CompareTag("Right_Limit")) { Change_For_Left_Movementation(); } if (collision.gameObject.CompareTag("Up_Limit")) { Change_For_Down_Movementation(); } if (collision.gameObject.CompareTag("Down_Limit")) { Change_For_Up_Movementation(); } if (collision.gameObject.CompareTag("Player")) { _HP -= 15; if (_HP <= 0) print("Die"); } } }
Now we are going to change the damage of enemies.
For this, We will create a new class, named Health_System_Enemy.
So here is our new class:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Health_System_Enemy : MonoBehaviour { int _HP = 100; public void Reduce_HP(int Damage) { _HP -= Damage; if (_HP <= 0) print("Die"); } }
Now We need to call Reduce_HP in our scripts, Enemy_2, and Enemy_1.
So here is our new Enemy_1
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_1 : MonoBehaviour { float _Speed_X = 5; int _HP = 100; bool _Right_Movementation; bool _Left_Movementation; Rigidbody2D _Rdb; Vector2 _Right_Vector; Vector2 _Left_Vector; Health_System_Enemy _Health_System_Enemy_Script; void Start() { _Right_Movementation = true; _Rdb = GetComponent(); _Health_System_Enemy_Script = GetComponent (); _Right_Vector = new Vector2(_Speed_X, _Rdb.velocity.y); _Left_Vector = new Vector2(-_Speed_X, _Rdb.velocity.y); } void Update() { if (_Right_Movementation == true) _Rdb.velocity = _Right_Vector; if (_Left_Movementation == true) _Rdb.velocity = _Left_Vector; } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Left_Limit")) { _Right_Movementation = true; _Left_Movementation = false; } if (collision.gameObject.CompareTag("Right_Limit")) { _Right_Movementation = false; _Left_Movementation = true; } if (collision.gameObject.CompareTag("Player")) { _Health_System_Enemy_Script.Reduce_HP(15); } } }
And here is our new Enemy_2
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy_2 : MonoBehaviour { float _Speed_X = 5; float _Speed_Y = 5; float _Time; int _HP = 100; bool _Right_Movementation; bool _Left_Movementation; bool _Up_Movementation; bool _Down_Movementation; Rigidbody2D _Rdb; Vector2 _Right_Up_Diagonal; Vector2 _Right_Down_Diagonal; Vector2 _Left_Up_Diagonal; Vector2 _Left_Down_Diagonal; Health_System_Enemy _Health_System_Enemy_Script; // Start is called before the first frame update void Start() { _Left_Movementation = true; _Up_Movementation = true; _Rdb = GetComponent<Rigidbody2D>(); _Health_System_Enemy_Script = GetComponent<Health_System_Enemy>(); _Right_Up_Diagonal = new Vector2(_Speed_X, _Speed_Y); _Right_Down_Diagonal = new Vector2(_Speed_X, -_Speed_Y); _Left_Up_Diagonal = new Vector2(-_Speed_X, _Speed_Y); _Left_Down_Diagonal = new Vector2(-_Speed_X, -_Speed_Y); } // Update is called once per frame void Update() { if (_Right_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Right_Up_Diagonal; if (_Right_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Right_Down_Diagonal; if (_Left_Movementation == true && _Up_Movementation == true) _Rdb.velocity = _Left_Up_Diagonal; if (_Left_Movementation == true && _Down_Movementation == true) _Rdb.velocity = _Left_Down_Diagonal; _Time += Time.deltaTime; if(_Time > 5) { _Time = 0; if(_Up_Movementation == true) { Change_For_Down_Movementation(); } if (_Down_Movementation == true) { Change_For_Up_Movementation(); } if(_Left_Movementation == true) { Change_For_Right_Movementation(); } if (_Right_Movementation == true) { Change_For_Left_Movementation(); } } } void Change_For_Up_Movementation() { _Up_Movementation = true; _Down_Movementation = false; } void Change_For_Down_Movementation() { _Up_Movementation = false; _Down_Movementation = true; } void Change_For_Left_Movementation() { _Left_Movementation = true; _Right_Movementation = false; } void Change_For_Right_Movementation() { _Left_Movementation = false; _Right_Movementation = true; } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Left_Limit")) { Change_For_Right_Movementation(); } if (collision.gameObject.CompareTag("Right_Limit")) { Change_For_Left_Movementation(); } if (collision.gameObject.CompareTag("Up_Limit")) { Change_For_Down_Movementation(); } if (collision.gameObject.CompareTag("Down_Limit")) { Change_For_Up_Movementation(); } if (collision.gameObject.CompareTag("Player")) { _Health_System_Enemy_Script.Reduce_HP(15); } } }
Ready, We apply DRY, in our codes.
For the next article, We will use refactoring principles to create a better organization in our code.
This project is in my github https://github.com/MauroJrDeveloper/DRY_Article
Follow-me in Instagram for stay knowing when I create new posts @mauro_developer
You can also leave your feedback, and your suggestion, I will read all, and I will answer for you.
Thank you for reading.
Bridal Hairstyles
Woah! I’m really loving the template/theme of this website. It’s simple, yet effective. A lot of times it’s challenging to get that “perfect balance” between usability and visual appearance. I must say that you’ve done a excellent job with this. Also, the blog loads super quick for me on Firefox. Excellent Blog!