Bootstrap

Unity 不能对transform.position.x直接赋值

一:前言
Unity中不允许对transform.position.x直接赋值,之前认为transform.position.x是只读的所以不能直接赋值,其实并不是这个原因


二:解释
定位到Vector3类中,发现并没有对x、y、z进行读写限制

再定位到Transform类中,发现position是一个Vector3类型的属性,而Vector3是一个结构体,正因为position是一个结构体且是一个属性

也就是说当我们transform.position.x = 1时调用属性的Get方法得到position,属性的get、set本质上也是一个方法,通过方法获取到的值类型是一个副本,所以这个position只是一个副本,对这个副本做的任何修改都对原position无影响,显然这样做是没有意义的,所以编译器禁止你做这样的操作

就例如下面的这段代码

using UnityEngine;
 
public class Test1 : MonoBehaviour
{
    public void Start()
    {
        MyTransform t1 = new MyTransform();
        t1.vector3.x = 1;//报错
        t1.GetVector3().x = 1;//报错
    }
}
 
public class MyTransform
{
    public MyVector3 vector3 { get; set; }
 
    public MyVector3 GetVector3()
    {
        return vector3;
    }
}
 
public struct MyVector3
{
    public float x;
    public float y;
    public float z;
}

但是如下,如果将MyTransform类中的vector3从属性变为字段,就可以赋值了

using UnityEngine;
 
public class Test1 : MonoBehaviour
{
    public void Start()
    {
        MyTransform t1 = new MyTransform();
        t1.vector3.x = 1;
    }
}
 
public class MyTransform
{
    public MyVector3 vector3;
}
 
public struct MyVector3
{
    public float x;
    public float y;
    public float z;
}


所以用属性和方法返回的结构体是不能修改其字段的,用属性和方法返回的类的实例,是可以修改其字段的
这是因为如果vector3是属性,调用t1.vector3则进行了旧数据的值拷贝,假设vector3是A,那么t1.vector3就是B,两者毫无关系。而如果vector3是字段,调用t1.vector3获取到的还是vector3

三:总结
不能对transform.position.x直接赋值的本质是Vector3不但是结构体而且是一个属性,我们通过属性和方法获取到的结构体实际上获取到的是一个值拷贝,值类型在通过方法传递的时候,所传递的只是值的副本
——用属性和方法返回的结构体是不能修改其字段的
——直接访问公有的结构体是可以修改其字段的
——用属性和方法返回的类的实例,是可以修改其字段的
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/Pei_hua100/article/details/140126160

;