您现在的位置是:首页 >学无止境 >Unity中的Vector2的使用方法网站首页学无止境

Unity中的Vector2的使用方法

Jokey.xiao 2024-06-21 06:01:02
简介Unity中的Vector2的使用方法

Vector2表示2D向量和点

1.静态变量

  void Start()
    {
        //静态变量
        print(Vector2.down);
        print(Vector2.up);//Y轴正方向
        print(Vector2.left);
        print(Vector2.right);//X轴正方向
        print(Vector2.one);//单位化向量(1.1)
        print(Vector2.zero);//用来获取坐标原点

    }

2.构造函数

  void Start()
    {
        Vector2 v2 = new Vector2(2, 2);
        print("v2的向量是:"+v2);//输出 v2的向量是:(2.00,2.00) 
    }

3.成员变量(注意:开头小写的)

       print("v2向量的模长是"+v2.magnitude);//√下x²+y²,输出: v2向量的模长是:2.828427
       print("V2向量的模长的平方是:" + v2.sqrMagnitude);// 输出: V2向量的模长的平方是:8
       print("V2向量单位化之后是:" + v2.normalized);//输出v2长度为1的单位向量,输出 V2向量单位化之后是:(0.71, 0.71)
       print("V2向量的XY值分别是:" + v2.x + "," + v2.y);//输出: V2向量的XY值分别是:2,2
       print("V2向量的XY值分别是(使用索引器形式访问):" + v2[0] + "," + v2[1]);//输出: V2向量的XY值分别是(使用索引器形式访问):2,2

4.公共函数(注意:开头大写的)

(1).判断两个向量是否相等(Equals)

  void Start()
    {
        Vector2 v2 = new Vector2(2, 2);
        bool equal = v2.Equals(new Vector2(1, 1));//通过Equals判断V2与new Vector2(1, 1)是否相等
        print("V2向量与向量(1,1)是否相等?" + equal);//输出:V2向量与向量(1,1)是否相等?False

        //通过以下代码可以得出,Equals判断需要两个向量的模长和方向都相等
        //判断(1,3)和(3,1)是否相等
        Vector2 v2E = new Vector2(1, 3);
        bool equalv2E = v2E.Equals(new Vector2(3, 1));
        print("v2E向量与向量(3,1)是否相等?" + equal);//输出:"v2E向量与向量(3,1)是否相等?" False
    }

(2).设置Vector2的值

  void Start()
    {
        Vector2 v2 = new Vector2(2, 2);
        v2.Normalize();//将V2使用Normalize()向量单位化
        print("V2向量是:" + v2);//输出: V2向量是:(0.71, 0.71)

        v2.Set(5, 9);//设置v2的向量为(5,9)
        print("V2向量是:" + v2);//输出:V2向量是:(5, 9)
    }

a. transform.position不可以单独赋值,需要整体赋值

通过查看底层代码可以看到Transform中的position是属性而不是公有字段
position的类型是Vector3,而Vector3是struct结构体

结论1:用属性和方法返回的结构体是不能修改其字段的

public class No7_Vector2 : MonoBehaviour
{
  void Start()
    {
        Vector2 v2 = new Vector2(2, 2);
        //这种写法会报错
        transform.position.x = 4;//不可以单独赋值某一个值,比如x 
        
        //需要整体赋值 
        transform.position=v2;
        transform.position=new Vector2(3,3);
        //或者单独拿出来再进行赋值
        Vector2 vector2 = transform.position;
        vector2.x = 2;
        transform.position = vector2;
    }
}

结论2:直接访问公有的结构体是可以修改其字段的

值类型 Value Type

  • 值类型赋值,是 copy。即值的拷贝。
  • 值类型中,存储的是它的数值
public class No7_Vector2 : MonoBehaviour
{   
    public struct MyStruct
    {
        public string name;
        public int age;
    }
  void Start()
    {
        MyStruct myStruct = new MyStruct();//A
        myStruct.name = "jokey";
        myStruct.age = 10;
        MyStruct yourStruct = myStruct;//B
        yourStruct.name = "xiao";
        yourStruct.age = 20;
        print("原本的结构体对象名字是:" + myStruct.name);//输出 原本的结构体对象名字是:jokey
        print("修改后的结构体对象名字是:" + yourStruct.name);//输出 修改后的结构体对象名字是:xiao
    }
}

引用类型 Reference Type

  • 引用类型赋值,是 引用。传递的是地址
  • 引用类型中,存的是指向它真实数据的地址
public class No7_Vector2 : MonoBehaviour
{   
       public class MyClass
    {
        public string name;
        public int age;
    }
  void Start()
    {
        MyClass myClass = new MyClass();//A
        myClass.name = "jokey";
        myClass.age = 10;
        MyClass yourClass = myClass;//B跟A是同一块内存空间
        yourClass.name = "xiao";
        yourClass.age = 20;
        print("原本的结构体对象名字是:" + myClass.name);//输出: 原本的结构体对象名字是:xiao
        print("修改后的结构体对象名字是:" + yourClass.name);//输出: 修改后的结构体对象名字是:xiao
    }
}

总结导致这个问题的原因:
1.Transform中的position是属性(换成方法也一样,因为属性的实现本质上还是方法)而不是公有字段
2.position的类型是Vector的,而Vector是Struct类型
3.Struct之间的赋值是拷贝而不是引用。也就是你修改的游戏物体A,修改的并不是A,而是经过copy后的B,所以这时你对B进行的任何修改都作用不到A上。
在这里插入图片描述

5.静态函数

  void Start()
    {
        Vector2 va = new Vector2(1, 0);
        Vector2 vb = new Vector2(0, 1);
        print("从va指向vb方向计算的无符号夹角是:" + Vector2.Angle(va, vb));//输出: 从va指向vb方向计算的无符号夹角是:90
        print("va点与vb点之间的距离是:" + Vector2.Distance(va, vb));//输出: va点与vb点之间的距离是:根号2(1.414214)
        print("向量va与向量vb的点积是:" + Vector2.Dot(va, vb));//输出:向量va与向量vb的点积是:0
        
        //具体得到的新向量的结果的计算公式是:a+(b-a)*t,a指va,b指vb,t指计算比例
        print("va向vb按照0.5的比例进行线性插值变化之后的结果是" + Vector2.Lerp(va, vb, 0.5f));//输出:(0.50, 0.50)  

        print("va向vb按照参数为-1的形式进行(无限制)线性插值变化之后的结果是" + Vector2.LerpUnclamped(va, vb, -1));//输出:(2.00, -1.00)

        float maxDistance = 0.5f;
        print("将点va以最大距离不超过maxDistance为移动步频移向vb" + Vector2.MoveTowards(va, vb, maxDistance)); //输出; (0.65, 0.35)

        print("va和vb之间的有符号角度(以度为单位,逆时针为正)是" + Vector2.SignedAngle(va, vb));//输出:90
        print("vb和va之间的有符号角度(以度为单位,逆时针为正)是" + Vector2.SignedAngle(vb, va));//输出:-90

        print("va和vb在各个方向上的分量相乘得到的新向量是:" + Vector2.Scale(va, vb));//输出:(0.00, 0.00)
        
        //平滑阻尼
        Vector2 currentVelocity = new Vector2(1, 0);
        print(Vector2.SmoothDamp(va, vb, ref currentVelocity, 0.1f));
    }

在update()中实测用法

public class No7_Vector2 : MonoBehaviour
{
    public Transform grisTrans;//游戏物体位置
    public Transform targetTrans;//移动到的目标位置

    public float percent;
    public float lerpSpeed;
    Vector2 currentVelocity = new Vector2(1, 0);
void Update()
    {
        //1.使用Lerp()
        grisTrans.position= Vector2.Lerp(grisTrans.position, targetTrans.position, 0.01f);

        //2.使用lerp进行匀速移动
        percent += 1 * lerpSpeed * Time.deltaTime;
        grisTrans.position = Vector2.Lerp(grisTrans.position, targetTrans.position, percent);

        //3.使用moveTowards()
        //lerp是先快后慢,moveTowards匀速
        grisTrans.position = Vector2.MoveTowards(grisTrans.position, targetTrans.position, 0.01f);

        //平滑阻尼SmoothDamp
        //和使用第一种Lerp效果相似   
        Vector2 currentVelocity = new Vector2(1, 0);
        grisTrans.position = Vector2.SmoothDamp(grisTrans.position, targetTrans.position, ref currentVelocity, 1);
    }
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。