DEV Community

Thanabodee Charoenpiriyakij
Thanabodee Charoenpiriyakij

Posted on

1

เรียน 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)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay