0

I'm using Unity and Vector struct.

I use Vector3.Distance(a, b) function a lot, but I've just noticed that I want a slightly modified version of it which ignores the Y component and gives the distance in horizontal space. Lets call it a Vector3.HorizontalDistance(a, b).

float distance = Vector3.Distance(position1, position2);
float horizontalDistance = Vector3.HorizontalDistance(position1, position2); //I want this 

The horizontal distance method should look like this

public static float HorizontalDistance(Vector3 pos1, Vector3 pos2)
{
    pos1.y = 0f;
    pos2.y = 0f;

    return Vector3.Distance(pos1, pos2);
}

Right now I put this method in my Utils class and call it like this

float distance = Utils.HorizontalDistance(position1, position2);

But it doesn't feel right, it seems out of context without Vector3 name in in, I want to extend the Vector3's functionality and call it like this

Vector3.HorizontalDistance(a, b);

BUT I don't know how to do that, I couldn't find any information on this subject.?

derHugo
  • 83,094
  • 9
  • 75
  • 115
harut9
  • 77
  • 6
  • 1
    Does this answer your question? [Extension methods on a struct](https://stackoverflow.com/questions/4656222/extension-methods-on-a-struct) – gunr2171 Jan 26 '22 at 22:21
  • thanks for your suggestion, but it's not what I wanted. – harut9 Jan 26 '22 at 22:41
  • @harut9 why is this not what you wanted? For a type you didn't write (`UnityEngine.Vector3`) this is your only chance ... The answer to "Can I add a **static** method to an existing type?" I'd say the answer is simply "No, you can't!" ;) – derHugo Jan 27 '22 at 11:40
  • 1
    `But it doesn't feel right, it seems out of context without Vector3 name in` .. how about calling your class `Vector3Utils` then? That would be the most obvious way I guess .. – derHugo Jan 27 '22 at 11:51
  • Hi, totally agree with you, the best case would be to create a Vector3Utils class – harut9 Jan 29 '22 at 09:23
  • I don't know if I should mark this question answered or not? – harut9 Jan 29 '22 at 09:24

1 Answers1

1

You can't directly add code to the Vector3 struct, but you can write an extension method. That's the best option for you to have clean code.

void Main()
{
    var p1 = new Vector3() { X = 2f, Y = 1f };
    var p2 = new Vector3() { X = 7f, Y = 3f };
    
    Console.WriteLine(p1.HorizontalDistance(p2));
}

public static class Ext
{
    public static float HorizontalDistance(this Vector3 pos1, Vector3 pos2)
    {
        pos1.Y = 0f;
        pos2.Y = 0f;

        return Vector3.Distance(pos1, pos2);
    }
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • thanks, I already knew about extension methods, they don't seem clean and intuitive too, but thanks anyway, now I know that I can't add methods to Vector3 the way I wanted, but it's not a big problem – harut9 Jan 26 '22 at 22:36
  • 1
    I'm curious what you might be thinking of (let's say you own the language spec) that might be more _clean and intuitive_ than an extension method – Flydog57 Jan 26 '22 at 23:36
  • Extension methods would work on an instance though, OP is asking if it is possible to add a `static` method to the type itself to be called as `Vector3.XYZ` where I'd say the answer is simply "No, you can't!" ;) – derHugo Jan 27 '22 at 11:38
  • @derHugo - Yes, I think I pretty much said that. I then went on to give the best alternative I could suggest. – Enigmativity Jan 27 '22 at 22:11
  • 1
    @Enigmativity as OP says they know extensions but didn't want that ... I guess the best shot would be rather call their class `Vector3Utils` and call it a day ;) – derHugo Jan 28 '22 at 05:27