【C#基础】unity中结构体的使用

这篇具有很好参考价值的文章主要介绍了【C#基础】unity中结构体的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C#基础】unity中结构体的使用

结构体(Struct)是值类型数据结构,在栈上分配内存,可以包含字段,属性,方法,构造函数。结构体可以实现接口,但是不能继承。在Dots里有大量依靠Struct实现接口来定义Entities数据类型和实现逻辑。

一、结构体的基本使用

  • 定义结构体
  • 结构体初始化
  • 结构体方法
  • 结构体扩展方法

1.定义结构体

结构体一般用于小型的数据类型,下面定义一个双精度的三维坐标数据为例。

Public struct DoubleVec {}

2.结构体初始化

(1)通常通过构造函数对结构体进行初始化,也可以单独定义后赋值。

结构体

public struct DoubleVec
{
    public double x;
    public double y;
    public double z;

    //构造函数
    public DoubleVec(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

初始化和单独赋值

    DoubleVec doubleVec1;
    DoubleVec doubleVec2;
    void Start()
    {
        doubleVec1 = new DoubleVec(1, 1, 1);
        doubleVec2.x = 3;
        Debug.Log("doubleVec1.x=" + doubleVec1.x);
        Debug.Log("doubleVec2.x=" + doubleVec2.x);
    }

结果

doubleVec1.x=1
doubleVec2.x=3    

(2)没有对结构体进行初始化或者赋值,直接调用结构体的字段

重新定义一个字段类型多的结构体

public struct DoubleVec
{
    public float x;
    public float y;
    public double z;
    public string name;
    public Vector3 vec;
    public bool bo;
    public int[] ints;
}

直接使用字段

    DoubleVec doubleVec2;
    void Start()
    {
        Debug.Log("doubleVec2.y=" + doubleVec2.y);
        Debug.Log("doubleVec2.vec=" + doubleVec2.vec);
        Debug.Log("doubleVec2.name=" + doubleVec2.name);
        Debug.Log("doubleVec2.ints=" + doubleVec2.ints);
        Debug.Log("doubleVec2.bo=" + doubleVec2.bo);
        Debug.Log("doubleVec2.x=" + doubleVec2.x);
    }

结果

    doubleVec2.y=0 //浮点类型初始为0
    doubleVec2.vec=(0.00, 0.00, 0.00)//vecter初始为原点
    doubleVec2.name= //字符串为空
    doubleVec2.ints= //数组为空
    doubleVec2.bo=False   //bool为false
    doubleVec2.x=0

(3)构造函数

实例构造函数:初始化字段信息,构造函数参数必须对没有字段进行赋值

静态构造函数:当结构体构造实例时,静态构造函数会自动调用一次;不带任何参数,不带修饰符。

public struct DoubleVec
{
    public double x;
    public double y;
    public double z;

    //构造函数
    public DoubleVec(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    //静态构造函数
    static DoubleVec()
    {
        Debug.Log("被调用");
    }
}

3.结构体方法

  • get方法
  • 结构体传参方法
  • 逻辑运算

(1)get方法

可以直接在结构体变量后使用,下面以求模长为例

   DoubleVec doubleVec1;
   void Start()
    {
        doubleVec1 = new DoubleVec(1, 1, 1);
        //这里直接可以点出方法
        double mag= doubleVec1.Magnitude;
        Debug.Log("mag=" + mag);
 
    }

创建的方法

public struct DoubleVec
{
    public double x;
    public double y;
    public double z;

    //构造函数
    public DoubleVec(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
   //必须用get方法给方法赋值
    public double Magnitude {
        get {return  magnitude(); }
    }
    //求模长的方法
     double magnitude()
    {
        double a = getLength(x, y);
        double b = getLength(a, z);
        return b;
        double getLength(double a, double b)
        {
            return Math.Sqrt(a * a + b * b);
        }
    }
}

该方法只能使用结构体变量的字段进行逻辑处理,与结构体的字段关联

(2)结构体传参方法

可以在结构类型后面点出方法,传入参数进行逻辑处理,同样以求模长为例

  DoubleVec doubleVec1;
   void Start()
    {
        doubleVec1 = new DoubleVec(1, 1, 1);
        //这里是同结构体类型点出方法,参数为结构体变量
        double mag= DoubleVec.MagnitudeVec(doubleVec1);
        Debug.Log("mag=" + mag);
 
    }

创建方法

public struct DoubleVec
{
    public double x;
    public double y;
    public double z;

    //构造函数
    public DoubleVec(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
   //这里要用静态方法,参数与结构体本身的字段没有关系
    public static double MagnitudeVec(DoubleVec vec)
    { 
        return magnitude(vec);
    }
    //运算方法也要静态
    static double magnitude(DoubleVec vec)
    {
        double a = getLength(vec.x, vec.y);
        double b = getLength(a, vec.z);
        return b;
        double getLength(double a, double b)
        {
            return Math.Sqrt(a * a + b * b);
        }
    }
}

这种方法是很独立的,与结构体本身没有关联,只能算逻辑上的分类

(3)逻辑运算

这里的逻辑运算包括:加、减、乘、除、大于、小于、等于、不等于等。下面以实现加法为例。

    DoubleVec doubleVec1;
    DoubleVec doubleVec2;
    void Start()
    {
        doubleVec1 = new DoubleVec(1, 1, 1);
        doubleVec2 = new DoubleVec(2, 2, 2);
        DoubleVec doubleVec3 = doubleVec1 + doubleVec2;
    }

创建方法

public struct DoubleVec
{
    public double x;
    public double y;
    public double z;

    //构造函数
    public DoubleVec(double x, double y, double z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    //使用operator运算符重载方法
    //参数中必须有一个为DoubleVec
    public static DoubleVec operator +(DoubleVec a, DoubleVec b)
    {
        return new DoubleVec(a.x + b.x, a.y + b.y, a.z + b.z);
    }
}

(4)operator 运算符的用法

一元运算符

一个参变量,直接跟变量使用

   //operator +
    public static DoubleVec operator +(DoubleVec a)
    {
        return new DoubleVec(a.x , a.y , a.z );
    }
  //operator -
    public static DoubleVec operator -(DoubleVec a)
    {
        return new DoubleVec(-a.x , -a.y , -a.z );
    }
  //operator ++
    public static DoubleVec operator ++(DoubleVec a)
    {
        return new DoubleVec(a.x+1 , a.y+1 , a.z+1 );
    }
  //operator --
    public static DoubleVec operator --(DoubleVec a)
    {
        return new DoubleVec(a.x-1 , a.y-1 , a.z-1 );
    }
  //operator !
    public static bool operator !(DoubleVec a)
    {
        return true;
    }

使用方法

        doubleVec1 = new DoubleVec(1, 1, 1);
        DoubleVec doubleVec3 = - doubleVec1;//对应operator +
        doubleVec3 = +doubleVec1;//对应operator -
        doubleVec3 = doubleVec1++;//对应operator ++
        doubleVec3 = doubleVec1--;//对应operator --
        bool bo = !doubleVec1;//对应operator !

二元运算符

需要两个变量进行运算

   //operator +
    public static DoubleVec operator +(DoubleVec a, DoubleVec b)
    {
        return new DoubleVec(a.x + b.x, a.y + b.y, a.z + b.z);
    }
   //也允许其中一个变量不是结构体的类型
    public static DoubleVec operator +(DoubleVec a, double b)
    {
        return new DoubleVec(a.x + b, a.y + b, a.z + b);
    }
  //operator -
    public static DoubleVec operator -(DoubleVec a, DoubleVec b)
    {
        return new DoubleVec(a.x - b.x, a.y - b.y, a.z - b.z);
    }
  //operator *
    public static DoubleVec operator *(DoubleVec a, double b)
    {
        return new DoubleVec(a.x * b, a.y * b, a.z * b);
    }
  //operator /
    public static DoubleVec operator /(DoubleVec a, double b)
    {
        return new DoubleVec(a.x / b, a.y / b, a.z / b);
    }

使用方法

        doubleVec1 = new DoubleVec(1, 1, 1);
        doubleVec2 = new DoubleVec(2, 2, 2);
        DoubleVec doubleVec3 =  doubleVec1;
        doubleVec3 = doubleVec1 + doubleVec2;//对应operator +
        doubleVec3 = doubleVec1 - doubleVec2;//对应operator -
        doubleVec3 = doubleVec1 + 1;//对应operator +
        doubleVec3 = doubleVec1 * 1;//对应operator*
        doubleVec3 = doubleVec1 / 1;//对应operator/

比较运算符

两个变量进行比较

  //operator == 
public static bool operator == (DoubleVec a, DoubleVec b)
    {
        if (a.x==b.x&& a.y==b.y&&a.z==b.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  //operator != 
    public static bool operator !=(DoubleVec a, DoubleVec b)
    {
        if (a.x != b.x && a.y!= b.y && a.z != b.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  //operator >
    public static bool operator >(DoubleVec a, DoubleVec b)
    {
        double magA = a.magnitude();
        double magB = b.magnitude();
        if (magA> magB)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  //operator <
    public static bool operator <(DoubleVec a, DoubleVec b)
    {
        double magA = a.magnitude();
        double magB = b.magnitude();
        if (magA < magB)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  //operator >=
    public static bool operator >= (DoubleVec a, DoubleVec b)
    {
        double magA = a.magnitude();
        double magB = b.magnitude();
        if (magA >= magB)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  //operator <=
    public static bool operator <= (DoubleVec a, DoubleVec b)
    {
        double magA = a.magnitude();
        double magB = b.magnitude();
        if (magA <= magB)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

使用方法

        bool _bool = doubleVec1 == doubleVec2;
        _bool = doubleVec1 != doubleVec2;
        _bool = doubleVec1 > doubleVec2;
        _bool = doubleVec1 < doubleVec2;
        _bool = doubleVec1 <= doubleVec2;
        _bool = doubleVec1 >= doubleVec2;

4.扩展方法

扩展方法可以是对unity中的类,密封类和结构体中的方法进行扩展。也可以对自己创建的结构体和类进行扩展,不过感觉很多余。

创建没有继承的静态类

public static class LearnExtention 
{
}

添加静态扩展方法,第一个参数用this修饰,类型为需要扩展的类型,后面为需要扩展的发方法所需要的参数。

///对上文的结构体进行扩展,求单位向量
public static class LearnExtention 
{
    public static DoubleVec normalized(this DoubleVec doubleVec)
    {
        return doubleVec / doubleVec.Magnitude;
    }
}

使用方法文章来源地址https://www.toymoban.com/news/detail-678272.html

   doubleVec1 = new DoubleVec(2, 2, 2);
//在类型的变量后点出方法使用
   doubleVec2 = doubleVec1.normalized();
//因为方法为静态的,所以可以直接使用
   doubleVec2 = LearnExtention.normalized(doubleVec1);

到了这里,关于【C#基础】unity中结构体的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言第十四课-------结构体的认识和使用-------重要一笔

    🎂        ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂    🎂      作者介绍:                              🎂🎂        🎂 🎉🎉🎉🎉🎉🎉🎉              🎂           🎂作者id:老秦包你会,         🎂 简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂

    2024年02月14日
    浏览(45)
  • C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

    结构是一些值的集合,这些值称为 成员变量 。 结构的每个成员可以是不同类型的变量 。 注意 : 成员列表可以是不同类型的变量; 成员后一定要有分号; 花括号后也有一个分号。 例如描述一个学生: 注意:上述代码没有创建变量,也没有初始化, 只是声明了一个结构体类

    2024年03月13日
    浏览(56)
  • 一般开发Unity 使用什么语言,需要学习什么知识

    一般来说,开发Unity使用的是C#语言。要学习Unity开发,你需要学习的知识包括: C#语言的基础知识 Unity的基本使用方法 常用的游戏编程模式,如游戏循环、场景切换、碰撞检测等 了解游戏对象、资源、动画、物理等概念 了解常用的游戏开发插件和工具,如脚本编辑器、版本

    2024年02月13日
    浏览(59)
  • Unity C# 之 Task、async和 await 、Thread 基础使用的Task的简单整理

    目录 Unity C# 之 Task、async和 await 、Thread 基础使用的Task的简单整理 一、Task、async和 await 、Thread 基础概念 1、线程,多线程 2、Task  3、async (await ) 二、Task 的基础使用,Task 的创建 和 启动 1、创建并运行一个Task 2、创建有返回值的 Task 3、Task提供了 task.RunSynchronously()用于同步

    2024年02月12日
    浏览(47)
  • 【Unity】Unity C#基础(十四)注释

    /// 是智能注释也称xml注释,会在被编译,并生成xml文件在可执行文件中。会影响编译速度,但不会影响代码执行速度。 一级注释 二级注释 另外,还可以自定义 XML 标签 。 注释换行 在 C# 智能注释时,常常希望它能在开发时显示为换行,使得提示更加友好!原来一直想怎么实

    2024年02月03日
    浏览(33)
  • Unity中删除预制体的子物体

    Unity中要删除预制体中的某个子游戏物体,需要先将该预制体UnPack,然后调用DestroyImmediate删除GameObeject,然后再保存预制体。这其实挺麻烦的,因为有时你拿到的gameObject是Asset中的资源,将预制体实例化后不好找到实例中对应的gameObject,拿名字找可以,但还是会有重名的风险

    2024年02月11日
    浏览(72)
  • 【C语言13】结构体的声明,定义与结构体的内存对齐

    通俗的说,结构体就是一个类的集合,如同整形数组是整形数字的集合体,结构体也是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 如果我们要表达一本书,那么这本书的元素有什么呢,书的名字,书的作者,书的创作日期~,而c语言中内置

    2024年02月13日
    浏览(72)
  • 【游戏开发算法每日一记】使用随机prime算法生成错综复杂效果的迷宫(C#,C++和Unity版)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 1.首先全部判定为墙,最外的为路包裹墙( 类似于防止数组越界 ) 2.红色为它的检测范围(假设检测点在如图所示的位置)—

    2024年02月05日
    浏览(43)
  • 【笔记】Unity编程(C#语言详解)

    从灵魂、身体、行为三个层面来看,脚本(Script)为游戏注入了生动的元素。脚本代码并非独立运行的程序,它依赖于Unity引擎的运行环境,并需附加到特定对象上。在Unity脚本中,没有像传统程序中的\\\"main\\\"函数,而是用于更新游戏循环中的对象。Unity为脚本提供了API以便访问

    2024年02月03日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包