DEV Community

Thanabodee Charoenpiriyakij
Thanabodee Charoenpiriyakij

Posted on

เรียน C# Syntax จาก Unity

ถ้าใครได้ลอง Unity จะได้เห็น type นึงที่ใช้ประจำนั่นคือ Vector2 และ Vector3 ซึ่ง blog นี้ผมจะลองทำความเข้าใจ C# จาก type ทั้งสองอันนี้กัน โดยยกตัวอย่างจาก Vector2 เป็นหลัก

ปล. หน้าตาอาจจะไม่เหมือนกันเป๊ะ แต่จุดประสงค์คือเพื่อให้อ่านโค้ดของ C# รู้เรื่อง -/-

1. Struct

Vector2 ถูกประกาศเป็น type struct เราสามารถประกาศได้แบบนี้

public struct Vector2
{
    public float x, y;
}
Enter fullscreen mode Exit fullscreen mode

ข้อดีของ 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);
    }
}
Enter fullscreen mode Exit fullscreen mode

ในตัวอย่าง เมื่อเราเรียก 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;
Enter fullscreen mode Exit fullscreen mode

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};
}
Enter fullscreen mode Exit fullscreen mode

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)})";
    }
}
Enter fullscreen mode Exit fullscreen mode

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}");
Enter fullscreen mode Exit fullscreen mode

สังเกตว่าผมมี check if ตรง format ไว้ใน ToString สาเหตุเพราะว่าใน C# สามารถกำหนดรูปแบบของ format ได้เช่น

Assert.AreEqual("(1.00, 2.00)", $"{vec:F2}");
Enter fullscreen mode Exit fullscreen mode

สังเกตใน string interpolation สามารถกำหนด format โดยใช้ : ตามด้วย format ที่ต้องการ ผมใช้ F2 เพื่อบอกให้ format เป็นทศนิยม 2 ตำแหน่ง

โค้ดเต็มดูได้ที่นี่ครับ https://gist.github.com/wingyplus/08656ff8da061445f39a0af8c052e0c4/08656ff8da061445f39a0af8c052e0c4

Top comments (0)