【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 //浮点类型初始为0doubleVec2.vec=(0.00, 0.00, 0.00)//vecter初始为原点doubleVec2.name= //字符串为空doubleVec2.ints= //数组为空doubleVec2.bo=False   //bool为falsedoubleVec2.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运算符重载方法//参数中必须有一个为DoubleVecpublic 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;}
}

使用方法

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 面试之Glide做了哪些优化?

前言 Glide可以说是最常用的图片加载框架了&#xff0c;Glide链式调用使用方便&#xff0c;性能上也可以满足大多数场景的使用&#xff0c;Glide源码与原理也是面试中的常客。 但是Glide的源码内容比较多&#xff0c;想要学习它的源码往往千头万绪&#xff0c;一时抓不住重点.…

搭建自己的私有 开源LoRaWAN 网络服务器(The ThingsStack)---之配置

介绍 这是使用 Docker 在您自己的硬件上安装 Things Stack Enterprise 或开源代码以运行您自己的私有 LoRaWAN 网络服务器的指南。 运行 The Things Stack 的方法有多种。 Things Stack 开源和企业发行版旨在在您自己的硬件上运行,本指南也对此进行了介绍。 对于具有高吞吐量的…

shell脚本免交互

一.Here Document免交互 1.免交互概述 使用I/O重定向的方式将命令列表提供给交互式程序 是一种标准输入&#xff0c;只能接收正确的指令或命令 2.格式&#xff1a; 命令 <<标记 ....... 内容 #标记之间是传入内容 ....... 标记 注意事项 标记可以使用任意的合法…

Cesium 相机的三种放置方式

文章目录 Cesium 相机的三种放置方式第一种&#xff1a;setView 计算视角1. Cartesian3 方式2. Rectangle 方式 第二种&#xff1a;flyTo第三种&#xff1a;lookAt Cesium 相机的三种放置方式 Cesium 提供了三种方式对相机的位置进行摆放 第一种&#xff1a;setView 计算视角 …

mybatisplus批量写入

1.新建MybatisPlusConfig /*** MybatisPlusConfig.*/ Configuration MapperScan("com.test.mapper") public class MybatisPlusConfig {/*** 自定义批量插入 SQL 注入器.*/Beanpublic InsertBatchSqlInjector insertBatchSqlInjector() {return new InsertBatchSqlI…

android 申请电池优化,自启动,无障碍权限

代码仅用于自己记忆,都是实际跑过的 /*** 引导开通-无障碍服务 可以跳转到系统的无障碍功能,并高亮自己的app*/fun gotoAccessibilitySetting(context: Context) {val EXTRA_FRAGMENT_ARG_KEY ":settings:fragment_args_key";val EXTRA_SHOW_FRAGMENT_ARGUMENTS &q…

WPF 项目中 MVVM模式 的简单例子说明

一、概述 MVVM 是 Model view viewModel 的简写。MVVM模式有助于将应用程序的业务和表示逻辑与用户界面清晰分离。 几个概念的说明&#xff1a; model :数据&#xff0c;界面中需要的数据&#xff0c;最好不要加逻辑代码view : 视图就是用户看到的UI结构 xaml 文件viewModel …

Docker 的基本概念和优势,以及在应用程序开发中的实际应用

Docker 是一款开源的容器化平台&#xff0c;它可以将应用程序及其依赖项打包成一个运行环境&#xff0c;使得应用程序可以在任何地方运行&#xff0c;而不需要考虑底层系统的差异性。下面是 Docker 的基本概念和优势&#xff1a; 基本概念&#xff1a; Docker 镜像&#xff1…

一文了解汽车芯片的分类及用途介绍

汽车芯片按其功能可分为控制类&#xff08;MCU和AI芯片&#xff09;、功率类、传感器和其他&#xff08;如存储器&#xff09;四种类型。市场基本被国际巨头所垄断。人们常说的汽车芯片是指汽车里的计算芯片&#xff0c;按集成规模可分为MCU芯片和AI芯片&#xff08;SoC芯片&am…

JavaScript模块化历程(一)

文章目录 1. 模块化概述2. 模块化演变[^2]2.1.文件划分模式(了解)2.2.命名空间模式(了解)2.3.IIFE(立即执行函数表达式)和参数依赖声明(了解) 3.模块化规范3.1 CommonJSRequire的基本实现逻辑(重点看) 3.2 AMDAMD的基本实现逻辑(重点看) 3.3 CMD 4.模块化标准规范 1. 模块化概述…

Lua之Lua源文件批量转换为luac字节码文件

准备的工具&#xff1a;luac.exe CSDNhttps://mp.csdn.net/mp_download/manage/download/UpDetailed Unity版: using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine;public static class Bat…

RabbitMQ手动签收消息

RabbitMQ手动签收消息 这里讲解SpringBoot使用RabbitMQ进行有回调的用法和消费者端手动签收消息的用法。 1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"h…

(学习笔记-调度算法)进程调度算法

进程调度算法也称 CPU 调度算法&#xff0c;毕竟进程是由 CPU 调度的。 当 CPU 空闲时&#xff0c;操作系统就选择内存中标的某个 [就绪状态] 的进程&#xff0c;将其分配给 CPU。 什么时候会发生CPU调度呢&#xff1f;通常有以下情况&#xff1a; 当进程从运行状态转换到等待…

BATPowerShell实现本地文件自动上传FTP服务器

运维工作中&#xff0c;经常需要一些脚本来实现自动化&#xff0c;今天分享本地文件自动上传FTP的两种解决办法&#xff1a; 一、使用BAT自动上传FTP 使用批处理&#xff08;BAT&#xff09;命令文件将本地文件夹内容上传到FTP服务器需要使用Windows自带的命令行工具&#xf…

【卷积神经网络】经典网络之 LeNet-5, AlexNet 与 VGG-16

随着计算机硬件的升级与性能的提高&#xff0c;运算量已不再是阻碍深度学习发展的难题。卷积神经网络&#xff08;Convolution Neural Network&#xff0c;CNN&#xff09;是深度学习中一项代表性的工作&#xff0c;其雏形是 1998 年 LeCun 提出的 LeNet-5 模型。如今&#xff…

WPF使用依赖注入

现在依赖注入在.Net里面已经普及&#xff0c;自己常写一些简单的demo倒是无所谓&#xff0c;但偶尔写一点正式的工程&#xff0c;也免不了要使用一下&#xff0c;于是总结了一下在WPF里面使用依赖注入。 在写简单Demo时候&#xff0c;通常是在MainWindow的构造函数里面直接做初…

Python爬虫——scrapy_日志信息以及日志级别

日志级别&#xff08;由高到低&#xff09; CRITICAL&#xff1a; 严重错误 ERROR&#xff1a; 一般错误 WARNING&#xff1a; 警告 INFO&#xff1a; 一般警告 DEBUG&#xff1a; 调试信息 默认的日志等级是DEBUG 只要出现了DEBUG或者DEBUG以上等级的日志&#xff0c;那么这些…

[oneAPI] 基于BERT预训练模型的SQuAD问答任务

[oneAPI] 基于BERT预训练模型的SQuAD问答任务 Intel Optimization for PyTorch and Intel DevCloud for oneAPI基于BERT预训练模型的SQuAD问答任务语料介绍数据下载构建 模型 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Int…

第2章 数据结构和算法概述

2.3线性结构和非线性结构 数据结构包括: 线性结构和非线性结构 2.3.1线性结构 线性结构作为最常用的数据结构&#xff0c;其特点是数据元素之间存在一对一的线性关系线性结构有两种不同的存储结构&#xff0c;即顺序存储结构(数组)和链式存储结构(链表)。顺序存储的线性表称…

回归预测 | MATLAB实现GAM广义加性模型多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现GAM广义加性模型多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现GAM广义加性模型多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本…