如果我有一个自定义类Vector3
并且我有一个类对象Myobject
,该对象使用vector3
类作为属性,并且设置了新的向量
myobject.pos = new vector3(x,y,z);
set
在这种情况下将按预期触发Debug.Log("set")
,但是如果我不想创建新的向量,我只想更改x
但仍然有set
触发了我想做的myobject.pos.x = x
,但这不会触发set
中的MyObject
,但是我的set
类中的vector3
对于x修复此问题后,当我仅更改set
的“ sub属性” x时,将触发MyObject
中的vector3
。
public class MyObject{
private Vector3 p_pos = new Vector3(0, 0, 0);
public Vector3 pos
{
get { return (p_pos); }
set
{
Debug.Log("set");
p_pos = value;
}
}
}
我想到的唯一方法是在MyObject
类中创建一个单独的方法,例如MyObject.SetPosX(x)
:
public void SetPosX(double _x)
{
Debug.Log("set");
p_pos.x = _x;
}
但这不是一种很干净的方法,因此最好使用其他解决方案。
答案 0 :(得分:1)
我认为可以更结构化的方式实现它的方式是允许Vector3在属性更改时通知某人。我的对象类将在必要时监听并做出反应。 在您提供的代码中,它看起来像是开销,但实际上,这取决于实际情况。
代码在下面
using System;
using System.Diagnostics;
public class Program
{
public static void Main()
{
MyObject myObject = new MyObject();
Vector3 vector3 = new Vector3(1, 1, 1);
myObject.p_pos = vector3;
myObject.p_pos.X = 5;
Console.ReadLine();
}
}
public class Vector3
{
public Vector3(double x, double y, double z)
{
X = x; Y = y; Z = z;
}
private double _x;
private double _y;
private double _z;
public double X
{
get
{
return _x;
}
set
{
_x = value;
OnPropertyChanged(EventArgs.Empty);
}
}
public double Y
{
get
{
return _y;
}
set
{
_y = value;
OnPropertyChanged(EventArgs.Empty);
}
}
public double Z
{
get
{
return _z;
}
set
{
_z = value;
OnPropertyChanged(EventArgs.Empty);
}
}
public event EventHandler PropertyChanged;
protected virtual void OnPropertyChanged(EventArgs e)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
}
public class MyObject
{
private Vector3 _p_pos = null;
public Vector3 p_pos { get
{
return _p_pos;
}
set
{
if (_p_pos != null)
_p_pos.PropertyChanged-= _p_pos_PropertyChanged;
_p_pos = value;
_p_pos.PropertyChanged += _p_pos_PropertyChanged;
}
}
private void _p_pos_PropertyChanged(object sender, EventArgs e)
{
Console.Write("_p_pos_PropertyChanged");
}
}
另一种更可取的方法是使vector3不可变,因此每次需要更改值时,都必须创建vector3的新实例。这样一来,您就可以保留vector3的轻量级版本,并且仍然可以控制其值。
答案 1 :(得分:0)
由于似乎无法回答那样的原因,我给它一个机会。
public class TestClass
{
private Vector3 _v = 0;
public Vector3 V { get { return _v; } set { _v = value; } }
void DoSomething ()
{
V = new Vector3 (2, 0, 0); // This will trigger 'set'.
V.x = 2; // This will not.
}
}
如果具有Vector3属性并设置其特定值,则可以在Vector3类本身内设置值,但不影响对所述Vector3的分配/引用。为了更改其x值,请勿为“ V”设置新的Vector3或其他Vector3。正如您已经知道的,一种避免这种情况的方法就是简单地使用一种方法来更改“ V”的值并触发您的额外代码。另一个可能是拥有自己的类,该类会在属性更改时触发您的额外代码(对于Vector3不太可能)。
如果您只想跟踪对Vector3的更改,则必须创建一个值Watcher类,该类将在更新中触发以检测要跟踪的值的更改。要创建此代码,可能会非常复杂,并且至少要使用lambda表达式和泛型,甚至可能会在Unity中通过将全局基类用于应继承自MonoBehavior的所有内容,甚至使用Unity中的整个代码结构。