ถ้าใครได้ลอง Unity จะได้เห็น type นึงที่ใช้ประจำนั่นคือ Vector2 และ Vector3 ซึ่ง blog นี้ผมจะลองทำความเข้าใจ C# จาก type ทั้งสองอันนี้กัน โดยยกตัวอย่างจาก Vector2 เป็นหลัก
ปล. หน้าตาอาจจะไม่เหมือนกันเป๊ะ แต่จุดประสงค์คือเพื่อให้อ่านโค้ดของ C# รู้เรื่อง -/-
1. Struct
Vector2 ถูกประกาศเป็น type struct เราสามารถประกาศได้แบบนี้
public struct Vector2
{
public float x, y;
}
ข้อดีของ struct คือมันจะ copy data ซึ่งทำให้ไม่มีผลกระทบอะไรเวลาเราส่งค่าไปให้อีก method แล้วมีการ modify เช่น
[TestFixture]
public class LearnStructTests
{
private void ModifyVector2(Vector2 vec)
{
vec.x = 2;
}
[Test]
public void TestStruct()
{
var vec = new Vector2
{
x = 1,
y = 20
};
ModifyVector2(vec);
Assert.AreEqual(1, vec.x);
}
}
ในตัวอย่าง เมื่อเราเรียก ModifyVector2 ซึ่งภายใน method นั้นมีการเปลี่ยน field x
ของตัวแปร vec
แต่ค่าของ vec
ภายใน TestStruct
กลับไม่ถูกเปลี่ยนแปลงแต่อย่างใด
2. Operator Overloading
อีก 1 feature ที่จะถูกใช้บ่อยใน Unity คือการลบ vector เพื่อเอาไปหาทิศทางที่จะเดินไป เช่น
// In Unity.
var target = new Vector2(10, 34);
var player = new Vector2(1, 2);
var direction = (target - player).normalized;
Unity ใช้ feature ของ C# ที่เรียกว่า operator overloading ในการทำให้การลบ vector เหมือนลบเลข โดยเราสามารถ declare operator - ได้แบบนี้
public struct Vector2
{
public float x, y;
public static Vector2 operator -(Vector2 a, Vector2 b)
=> new Vector2{x = a.x - b.x, y = a.y - b.y};
}
3. String formatting
ใน type Vector2 implement interface IFormattable
เพื่อให้ Vector2 สามารถแปลงเป็นข้อความที่อ่านรู้เรื่องใน debug console โดยเราสามารถทำได้แบบนี้
public struct Vector3 : IFormattable
{
public float x, y;
public static Vector2 operator -(Vector2 a, Vector2 b)
=> new Vector2 {x = a.x - b.x, y = a.y - b.y};
public string ToString(string format, IFormatProvider formatProvider)
{
if (string.IsNullOrEmpty(format))
{
format = "F1";
}
return $"({x.ToString(format, formatProvider)}, {y.ToString(format, formatProvider)})";
}
}
IFormattable
จะให้เรา implements string ToString(string, IFormatProvider)
เพื่อคืนค่า string ที่ format แล้วกลับไปให้ เท่านี้เราก็จะใช้ string interpolation ได้แบบนี้
var vec = new Vector2{x = 1, y = 2};
Assert.AreEqual("(1.0, 2.0)", $"{vec}");
สังเกตว่าผมมี check if ตรง format ไว้ใน ToString สาเหตุเพราะว่าใน C# สามารถกำหนดรูปแบบของ format ได้เช่น
Assert.AreEqual("(1.00, 2.00)", $"{vec:F2}");
สังเกตใน string interpolation สามารถกำหนด format โดยใช้ :
ตามด้วย format ที่ต้องการ ผมใช้ F2 เพื่อบอกให้ format เป็นทศนิยม 2 ตำแหน่ง
โค้ดเต็มดูได้ที่นี่ครับ https://gist.github.com/wingyplus/08656ff8da061445f39a0af8c052e0c4/08656ff8da061445f39a0af8c052e0c4
Top comments (0)