我想在Unity3d中为Vector3类创建一个扩展方法。但我似乎没有得到它。这就是我所拥有的:
public static class ExtensionMethods{
public static Vector3 MaxValue(this Vector3 _vec3)
{
return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
}
}
现在,我希望使用以下代码行创建Vector3.MaxValue
,就像float.MaxValue
一样:
Vector3 closestPoint = Vector3.MaxValue;
但后来我收到了这个错误:
error CS0117: `UnityEngine.Vector3' does not contain a definition for `MaxValue'
我知道这会奏效:
Vector3 closestPoint = new Vector3().MaxValue();
然后我创建了2个新的Vector3
个实例。一个在MaxValue
电话,一个在外面。是不是可以只使用这种代码制作一个:
Vector3 closestPoint = Vector3.MaxValue;
答案 0 :(得分:9)
首先,这里有一个非常快速的 扩展 教程,适合那些在Google上学习c#/ Unity的人:
制作一个像这样的新文本文件HandyExtensions.cs
...(请注意,有些令人困惑的是,您可以使用任何名称来“保留”您的扩展程序 - 实际该类的名称从未使用过,并且无关紧要)...
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public static class HandyExtensions
{
public static float Jiggled(this float ff)
{
return ff * Random.Range(0.9f,1.1f);
}
}
您现在已经制作了一个新的“命令”Jiggle()
。您可以在任何float
上使用微动。看看它的位置“this float ff”。因为它在那里说“浮动”,所以这个扩展适用于浮动。
正如您所看到的,Jiggled()
扩展名会占用一个浮动并稍微改变一下。试试这个
float x = 3.5f;
Debug.Log("x is " + x);
Debug.Log("x is " + x.Jiggled() );
Debug.Log("x is " + x.Jiggled() );
Debug.Log("x is " + x.Jiggled() );
Debug.Log("x is " + x.Jiggled() );
Debug.Log("x is " + x.Jiggled() );
在你对扩展有一个很好的理解之前做一些类似的测试。尽可能多地了解扩展!这是another教程。
正如Mikael所解释的那样,你所寻找的并不是一个延伸。 (另请注意,如果您尝试向Vector3添加字段,则无法在c#中执行此操作。)
现在,如果你想要返回“那个东西”,你需要预先包含静态类名,而你不要把它作为扩展名。这只是对静态的正常调用。
...误
public static Vector3 MaxValue(this Vector3 _vec3)
{
return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
}
...正确
public static Vector3 MaxValue()
{
return new Vector3(float.MaxValue,float.MaxValue,float.MaxValue);
}
然后你可以这样做......
Debug.Log( ExtensionMethods.MaxValue() );
我认为那可能就是你在那里寻找的东西。
您通常会将ExtensionMethods
简称为Handy
,这样您就可以写
Handy.MaxValue();
的确,既然你不能把“Vector3放在前面”,这样的事情会更清楚:
Handy.MaxVector3();
有道理吗?
如果您正在尝试写这样的内容:Vector3.MaxValue()
您不能这样做...因为“Vector3”部分是一个类(或结构),而不是一个变量。例如,这是整数的扩展名:
375.Jiggle();
,这是整数的扩展名:
int x;
x.Jiggle();
但这没有意义:
int.Jiggle(); // meaningless
为了清楚起见,请注意您问:
我想在Unity3d中为Vector3类创建一个扩展方法[实际上是一个struct]
扩展只能在 实际变量 上调用,而不能在“类或结构”上调用。
Vector3 hero;
Vector3 enemy;
hero.Jiggle(); // works great
enemy.Jiggle(); // works great
Vector3.Jiggle(); // syntax error - meaningless
另外请注意,正如Mikael在答案中提到的那样,事实上你实际上可以这样做:
(new Vector3()).Jiggle();
如果你认为它也有意义。 c#中我最喜欢的一件事是你可以在普通旧常量上使用扩展 :
14.Jiggle();
7.5f.Radians();
除非你从生活中获得快乐,否则你必须要爱它。这是一个例子:
public static Color Colored( this float alpha, int r, int g, int b )
{
return new Color(
(float)r / 255f,
(float)g / 255f,
(float)b / 255f,
alpha );
}
然后你可以写.. Color c = .5f.Colored(.2f,.4f,.2f);
,这是一个alpha值为.5f的pucey颜色。
我一直以为如果你问的语法可用会很好,如果你可以把某种“类型”或“类”作为你所延伸的“东西” - 但事实并非如此。对于你想要做的事情,你必须使用一个方便的词,比如,好吧,Handy,并且这样做
Vector3 big = Handy.MaxVec3();
我希望这可以解释这种情况!
再次为需要扩展的一般介绍的任何人intro。以下是我最喜欢的一些扩展。
在每个游戏项目中都会使用以下内容......
public static float Jiggle(this float ff)
{
return ff * UnityEngine.Random.Range(0.9f,1.1f);
}
public static float PositiveOrNegative(this float ff)
{
int r = UnityEngine.Random.Range(0,2);
if (r==0) return ff;
return -ff;
}
public static bool Sometimes(this int n)
{
if (n<=1) return true;
int r = UnityEngine.Random.Range(0,n);
return (r==0);
}
示例使用..
if ( 10.Sometimes() )
{
explode spaceship
}
它只进行十次。
if ( 3.Sometimes() )
{
laser sparkle
}
在那个例子中,它只在大约三分之一的时间内完成。
(请注意,在可能的情况下,您通常会使扩展使用泛型。为简单起见,此处未显示。)
这是一个handy extension trick。这是一个非常advanced extension。
扩展在Unity工程中无处不在。
如果你是学习使用Unity编码的众多人之一......你应该掌握的第一件事就是扩展。尝试使用扩展名几乎所有。有时在使用Unity时,几乎每行代码都需要一个或多个扩展。享受!
答案 1 :(得分:2)
扩展方法是一种使静态方法看起来像类或接口的一部分的方法。 Vector3上的扩展方法Foo()意味着你可以像你说的那样做新的Vector3()。Foo()。
看起来你希望你的MaxValue属性成为Vector3上的静态成员,扩展方法无法帮助你。无法将静态成员添加到现有类中。
但是,这真的有必要吗?您可以在新类型中定义常量属性。我们称之为“KnownVectors”或其他东西,然后去:
Vector3 closestPoint = KnownVectors.MaxValue;
当然,也许以某种方式把它变成现有的Vector3类会很好,但是它真的会在你的代码中添加任何内容吗?