【C#知识树】基于Unity的常用C#函数、类、方法

 

【获取对象】

(1)GameObject go = GameObject.Find("游戏对象名");

(2)Transform body = transform.Find("Body");【查找transform的子物体获取body对象】


【读取资源】

(1)string fname = "AudioMixerGroup";AudioMixer mixer = Resources.Load(fname);【读取一个混音文件 Assets/Resources/AudioMixerGroup.mixer】


【动态加载】

(1)GetComponent().material.mainTexture = image; 

【案例】

using UnityEngine;
/// 
/// 挂Player身上
/// 
public class PlayerCharacter : MonoBehaviour
{
    Rigidbody rigid; //声明变量:刚体组件
    Transform body; //声明变量:身体
    Transform hand; //声明变量:手臂
    private void Start()
    {
        //获取刚体组件
        rigid = GetComponent();//给变量赋初值
        //加载图片资源设置主角纹理
        Texture image = Resources.Load("Image");
        GetComponent().material.mainTexture = image; //动态加载网格渲染器MeshRender
        //根据名称获取身体并设置成黑色
        body = transform.Find("Body");//查找transform的子物体获取body对象
        body.GetComponent().material.color = Color.black;
        //根据名称获取双臂,从而获取两只手臂,都并设置成黑色
        hand = body.Find("Hands");//查找body的子物体获取hand对象,Hands=左手+右手
        BoxCollider[] hands = hand.GetComponentsInChildren();
        foreach (var hand in hands)
        {
            hand.GetComponent().material.color = Color.black;
        }
    }

【Transform】
(1)transform.position=new vector2(xx,xx)【unity默认写法,更改一个坐标值的时候要给他一个新的值】
(2)GameObject.transform.Rotate(0,15 * Time.deltaTime,0,Space.Self)【使游戏对象按自己的y轴旋转】


【创建变量】
(1)void Awake()【无论脚本script是否启用,都在点击开始时运行,Unity预制的函数,而void Start是只有启用了该脚本后,才会执行一次】
(2)public class PlayerController :MonoBehaviour*【class后面的PlayerCountroller是这个C#的文件代码的名称,MonoBehaviour是它所调用的类的库,里面包含很多函数和方法,所有的unity脚本的驱动都要调用它】*
(3)public GameObject player【GameObject是Unity自带的变量类型,所以所有在Hierarchy里出现的东西都叫gameobject,是一个项目】


【启动和禁用组件】
(1)例:A.enable=!A.enable;【!A.enable意思是将它设为非当前值,不是true就是false,该处代码可以在每次执行时支持反复开关而不需要各种判断语句】


【函数Function】
(1)void Start(){}【void是一个无任何返回值的函数,Start代表函数名】
(2)int Start(){return;}【在有返回值的情况下一定要在后面加上return,不然会报错,其中返回的值保存在Start函数,在调用时直接写上Start这个函数名即可】
(3)FixedUpdate(){}【物理运动;在每帧当中都会执行,同时大概每0.02秒执行一次,可以在unity设置中调节,通常使用物理运动或物理刚体中使用】


【MeshRenderer、MeshFilter】

(1)创建网格面的核心就是为其添加2个组件:Mesh Renderer(网格渲染器)和Mesh Filter(网格过滤器)。

 //添加MeshFilter
 gameObject.AddComponent();
 //添加MeshRenderer
 gameObject.AddComponent();
 //获得Mesh
 mesh = GetComponent().mesh;

(2)
        //获得Mesh
        mesh = GetComponent().mesh;
        //修改Mesh的颜色
        GetComponent().material.color =Color.green;
        //选择Mesh中的Shader
        GetComponent().material.shader = Shader.Find("Transparent/Diffuse");
        //清空所有点,用于初始化!
        mesh.Clear();       

(3)

        //设置顶点坐标

        mesh.vertices = vertices;

        //设置顶点索引

        mesh.triangles = triangles;

 

 【案例】拖动鼠标来绘制一个圆弧

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class MeshTest : MonoBehaviour {
 
    //用于存储绘制三角形的顶点坐标
    private Vector3[] vertices;
    //用于记录绘制三角形所需要的顶点ID顺序
    private int[] triangles;
    //记录顶点数
    private int count=0;
    //定义Mesh
    private Mesh mesh;
    //定义一个链表用于记录所有点的坐标
    private List list;
 
	void Start () {
 
        //添加MeshFilter
        gameObject.AddComponent();
        //添加MeshRenderer
        gameObject.AddComponent();
        //new一个链表
        list = new List();
        //获得Mesh
        mesh = GetComponent().mesh;
        //修改Mesh的颜色
        GetComponent().material.color =Color.green;
        //选择Mesh中的Shader
        GetComponent().material.shader = Shader.Find("Transparent/Diffuse");
        //清空所有点,用于初始化!
        mesh.Clear();       
        
	
	}
	
	
	void Update () {
 
        //点击鼠标左键
        if (Input.GetMouseButton(0))
        {    
            //顶点数+1
            count++;
            //将获得的鼠标坐标转换为世界坐标,然后添加到list链表中。
            list.Add(Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0.8f)));
            
        }
 
        //如果顶点数>=3,那么就开始渲染Mesh
        if (count >= 3)
        {
            //根据顶点数来计算绘制出三角形的所以顶点数
            triangles = new int[3 * (count - 2)];
            //根据顶点数来创建记录顶点坐标
            vertices = new Vector3[count];
            //将链表中的顶点坐标赋值给vertices
            for (int i = 0; i < count; i++)
            {
                vertices[i] = list[i];
 
            }
 
            //三角形个数
            int triangles_count = count - 2;
            //根据三角形的个数,来计算绘制三角形的顶点顺序(索引)
            for (int i = 0; i < triangles_count; i++)
            {
                //这个算法好好琢磨一下吧~
                triangles[3 * i] = 0;
                triangles[3 * i + 1] = i + 2;
                triangles[3 * i + 2] = i + 1;
            }
            //设置顶点坐标
            mesh.vertices = vertices;
            //设置顶点索引
            mesh.triangles = triangles;
        }
	
	}
}

【Unity中代码的生命周期ScriptLifecycle】
(1)代码执行周期和顺序:https://docs.unity3d.com/Manual/ExecutionOrder.html
(2)常用方法执行循序,与代码摆放位置无关:Awake()最先执行—>到OnEnable()【当脚本启用时执行】—>到Start()—>到FixedUpdate()—>到OnTrigger系列()—>到OnCollision系列()—>到OnMouse系列()—>到Update()—>到LateUpdate【在当前帧执行完成后才执行,比Update晚】—>到OnGUI()【渲染图形用户界面,界面按钮啥的】—>到OnDestroy()【会在代码最后部分执行】


【数组Array】
(1)基本写法:type[] name = new type[number];【在定义变量的时候,在变量类型后接上中括号,代表它是一个数组变量,然后在接上它的名字,第一种写法就是可以让它等于新的变量类型,然后中括号里记录这个变量类型的数组有多少个数据】
(2)另一种写法:type[] name=(data1;data2);【大括号里直接写上想要保存的数据,用分号隔开】
(3)第三种写法:Public type[] name;【用public生成一个数组的类型变量,不给他赋值,在unity中赋值】
(4)例1:int[] num=new int[3]【代表数组里可以存储三个数据】,输入数据:num[0]=4,num[1]=10;…【最多可以输入三个数据】
(5)例2:public string[] name={“zhao”,“cai”,“bo”}【创建一个字符型的数组,系统会自动判断多少个数据,为3个】,输出数组的数据个数(长度):name.Length
(6)例3:public GameObject[] cubes;【生成一个类型为gameobject来存放方块,在unity中来输入长度,并拖入gameobject到element】
【同时数组也可以用来检测游戏中某一个物体的总个数:cubes=GameObject.FindGameObjectsWithTag(“cube”);,之后系统会检测到物体的个数并设置为这个数组的个数(长度)】


【List】
(1)List与数组最大的不同是:数组长度是固定的,而List在使用的时候长度是可变的
(2)定义时:List itemList = new List();
(3)添加元素:itemList.Add(XXX);【不断添加元素长度会不停的变化】
(4)移除元素:itemList.Remove(itemList[itemIndex]);【比如删除了中间的元素后,后面的元素会自动补上原先被删除的序列号并自动排序】
(5)查找元素:itemList.Contains(XXX);【通过输入项目的名字来查找列表中是否有该元素,有则返回true】
(6)查询列表长度:itemList.Count;


【foreach遍历数组】
(1)例:foreach(Transform item in test){}【Transfrom是变量类型,(自定名称)item是变量,test是需要循环读取的数组名】
(2)foreach(var item in test){}【循环test里面的每一个数据并保存到item中,直到结束】


【var:variable可变的】
(1)会自动识别所需要的类型:var Data ={ “阿巴阿巴阿巴”};,等同于string[] Data={“阿巴阿巴阿巴”};


【Coroutine协程】
(1)协程处理需要与yield return new WaitForSeconds(时间/秒)配合使用,当使用时,协程会通过你设置的秒数来暂停后续代码的执行,例如对话打字系统,可以通过协程来实现一字一字的显示效果
(2)协程定义代码:IEnumerator 协程名(){yield return new WaitForSeconds(0.3);}【执行该协程时,会暂停0.3秒后执行后续语句,update不受影响
(3)协程调用代码:StartCoroutine( 协程名());


【UI调整】
(1)UI界面中的Rect Transform居中对其方法,按住Alt健+鼠标左键点击相关的对其图片即可自动对其
(2)ctrl+D可以快速复制一个物体


【ScriptableObject】
(1)与MonoBehaviour类似,ScriptableObject是一个特殊的类,它不需要挂载在任何一个gameobject上,可以直接存储在文件夹当中,可以用来保存游戏数据
(2)通常与CreateAssetMenu配合起来一起工作,用于创建右键菜单来创建Asset文件,而Asset文件就是用来保存游戏数据的数据库,例如:[CreateAssetMenu(fileName =“itemData”,menuName = “Datas/itemData”)],【其中itemData是创建出来的默认文件名(可修改),而Datas/itemData是右键菜单的路径】


【Sorting Layers】
(1)排序越靠下的越在镜头前面显示,越上面的反之】


【Gravity Scale】
(1)RigidBody中的Gravity Scale重力比例是由一个基数乘以Unity系统设置中的默认重力-9.81
(2)修改系统重力方法:Edit—》Project Settings—》Physics2D


【方法重载的方法需要有返回值】
(1)专门为一个方法创建方法函数来添加我想要的值,例如:RaycastHit2D Raycast(XXX,XXX,XXX,XXX){ }


【return函数】
(1)在一个函数后面加上return后,return后面的函数将不会执行,这个方法会不断return,直到跳过它才会执行后面的函数


【Polygon Collider 2D】
(1)要删除无用顶点可以按住ctrl后,将鼠标移动至边界线上,出现红色即可删除


【获得父级组件方法】
(1)XXX=GetComponentInParent();


【Audio系列】
(1)引用命名空间:using UnityEngine.Audio; 组件介绍:Audio Listener:相当于耳朵,接收声音,由摄像机挂载。Audio Source:相当于播放器,用来播放音频。Audio Clips:音源,也就是声音片段。
(2)添加Audio Source后如果左边出现蓝条,代表这个组件还没有保存到预制体中,是临时的。若要保存,可以点击右上角的Overrides进行添加
(3)为了方便管理很多音频,可以专门创建一个空项目GameObject来管理所有的音效,之后为其创建一个音频管理脚本来控制播放。
(4)在音频管理脚本中为了方便其他脚本的调用,而不用反复在其他脚本中生成示例去调用这个音频管理脚本,可以让音频管理脚本的这个类进行原地实例化,这样就可以通过这个实例化后的实体来访问这个脚本中的所有函数
(5)实例化方法:static 类名 实体名(自定名称); 之后在Awake函数中(一开始就执行),让实体名=this; ,因为你创建的这个类是无法为它赋值的,所以只能让这个实例的变量等于这个类的本身,也就是this,之后就可以在其他脚本中通过这个实体名来调用音频管理脚本中的所有函数(类名.实体名.函数名())
例如:
public class Audio : MonoBehaviour
{
public static Audio GameAudios;
public void footAudio()
{
XXX;
}
}

调用时:Audio.GameAudios.footAudio();即可

(6)代码添加组件方法:先定义:AudioSource Sound;-------》初始化并赋值Sound=gameObject.AddComponent();


【SerializeField序列化】
(1)如果你想设置某一函数为private,又想在Unity中可以进行拖拽操作赋值,就可以在你想这么做的函数前写上头命令:[SerializeField]


【DontDestroyOnLoad】
(1)如果你不希望当前的某个项目在场景重新加载时被销毁,可以用DontDestroyOnLoad(GameObject);【GameObjet为当前项目,可以用于背景音乐的组件管理,避免音乐被暂停】


【Random.Range范围界定】
(1)当Range的参数是float时,返回一个随机浮点数,在min(包含)和max(包含)之间,此时包括临界值
(2)当Range的参数是int时,返回一个随机整数,在min(包含)和max(排除)之间,是一个左闭右开的,只包含最小值,不包含最大值,例如:Random.Range(1,4);这个结果就是随机一个1,2,3不含4


【Cull Transparent Mesh】
(1)Canvas Renderer中的Cull Transparent Mesh,具体功能是说当UI组件完全透明的时候是否剔除,如果不勾选,完全透明的物体也会参与渲染计算,占用一个批次,如果勾选,则将其忽略;


【ToString()】
(1)使用ToString可以将数值型int,float等转为字符型,用来将游戏数据以字符型的形式保存在UI界面中的text文本中


【理解脚本中gameObject和GameObject的区别】
(1)Gameobject不是对象,通常需要获取一个对象,就像你定义一个public GameObject A;
那么属性里就会出现一个可托选的框,那就是Unity告诉你,你定义的这个物体是哪个物体要你选择,无论你拖拽也好,脚本里获取也好,都是要给A赋予对象的。它是一个类型,所有的游戏物件都是这个类型的对象。
(2)而gameobject是一个对象,指的是这个脚本所附着的游戏物件


【游戏时间统计】
(1)如果单纯使用Time.time,它只会显示几点几秒而不是正常的几时几分几秒,因此要将秒数换算成分钟
(2)方法:
1、int Minutes= (int)(time.time/60);【通过对时间强制转换为整数秒后除以60可得分钟数】
2、int Seconds= Time.time % 60;【通过对运行时间取余60可得以60为最大值的秒数,例如119秒对60取余可得59秒,当运行时间到120秒时,对60取余将为0,而显示的秒数将不会超出60】
(3)输出:text = Minute.ToString(“00”)+":"+ Seconds.ToString(“00”);【这样就会输出00:00的格式,其中ToString(“00”)代表输出格式,为两位数的分钟,三个0同理】


【Rigidbody系列】
(1)如果想要改变rigibody中的bodytype让游戏角色静止,可以用:
Rigi.bodyType = RigidbodyType2D.Dynamic;或者Rigi.bodyType = RigidbodyType2D.Static;


【游戏暂停】
(1)Time.timeScale=0f时,可以使游戏的运算速度为0,那么游戏将会暂停。【这可用于慢动作效果或加快应用程序速度。当设置时间刻度为 1.0 时,时间流逝的速度与实时一样快。当时间刻度为 0.5 时,时间比实时慢 2 倍,‎当 timeScale 设置为零时,如果所有函数都与帧速率无关,则应用程序的行为就像暂停一样。负值将被忽略】
【注意:‎FixedUpdate 函数和具有 ‎‎WaitForSeconds 的‎‎挂起的协程在 timeScale 设置为零时不会调用】


【Audio Mixer,通过slider调节游戏声音】
(1)先在project视图中创建audiomixer,之后双击创建好的mixer,在groups面板下可以为游戏创建多个混音器,之后单机某一个混音器,在inspector窗口中右键volume项,为这个混音器expose一下,设置为脚本可编辑模式—》之后可以在exposed parameter项更改参数名,这个参数名就作为之后代码中SetFloat的“string name“。
(2)在代码中添加一个公共变量:public AudioMixerGroup XXX;,这个可以为audiosource的outputmixer赋值,记得在unity中对其进行赋值。
(3)之后再创建一个:public AudioMixer VolumeControl;用来通过外部组件控制mxier中各混音器的音量大小。
(4)最后创建一个函数:
public void BGMControl(float Mix)
{
VolumeControl.SetFloat(“BGM”, Mix);
}
【其中Mix用来接收从slider中的数值,记得在slider中选择dynamic float中的Mix来通过滑动条动态的调节音量,如果不使用dynamic float,就只能通过手动赋值才能调节音量】


【矢量数学】
(1)Vector3.Dot(VectorA,VectorB)【点积用于判断两向量是否垂直,若两向量的x1x2+y1y2+z1z2之和等于0,则说明两向量垂直。以飞机飞行姿态为例:若两向量点积为正,则两向量角为锐角,飞行阻力增大;若为负,则为钝角,机头朝下,速度加快】*
(2)Vector3.Cross(VectorA,VectorB)【叉积可以计算出另一个向量,例如对A和B向量进行叉积运算,可以得出一个与这两个向量都垂直的向量C。以坦克为例:若已知目标朝向A,炮台朝向B,则可以求出垂直的轴C,转动C轴就可以转动炮台指向目标】


【Translate和Rotate】
(1)通常在平移操作时速度乘上Time.deltaTime意味着它会按照每秒多少米的速度移动而不是每帧多少米,可以使移动更流畅,因为每一帧的时间不是固定的,而deltatime可以让其在固定的时间内移动,这样可以让我们更改每秒的速度而不是每帧的速度
(2)前后移动可以用transform.translate(±vector3.forwardSpeedTime.deltaTime);
(3)左右旋转可以用transform.Rotate(±Vector3.up,turnSpeed*Time.deltaTime);


【LookAt】
(1)transform.LookAt(target);可用于让游戏的正向指向世界中的另一个transform【若将改脚本应用于摄像机,则可以实现摄像机跟踪物体的效果】


【Destroy】
(1)Destroy(GetComponent());可用于移除组件
(2)创建延时:Destroy(XXX,3f);【3f作为另一个参数,则将会延时3秒后移除对象】


【GetButton和GetKey】【返回布尔值】
(1)当持续按下按钮或松开按钮时,GetButtonDown和GetButtonUp都只在第一帧时返回结果true,到第二帧时就会返回默认的false
(2)GetButton可以检测持续按下的按钮,一直返回true,直到松开才返回false


【GetAxis返回浮点值,值介于-1到1之间】,【GetAxisRaw返回-1,0,1整数】
(1)Unity的input设置中的gravity决定归零速度的快慢,越高则归零速度越快
(2)Unity的input设置中的Sensitivity控制着输入的返回值到达1或-1的速度有多块,值越大,反应速度就越快,越小,则移动越流畅
(3)若使用操纵杆控制时,Unity的input设置中的Dead盲区可以避免操纵杆轻微移动造成的影响,Dead值越大,盲区越大,操纵杆的移动幅度也就越大
(4)Unity的input设置中的Snap的作用是同时按下正负按钮时归零


【GetComponent】
(1)对其他脚本的引用就是以脚本名称为类型的变量:private AnotherScript script;,而在下面还需要在Awake函数中进行变量初始化:AnotherScript=GetComponent();【尖括号的作用是让类型成为参数,GetComponent会返回调用它的游戏对象中任意指定类型组件的引用】【注意:相互引用脚本只能在同个gameobject(物体对象)中引用,想要跨对象引用只能通过设置公共类型后拖拽另一个物体进去后才能引用】


【instantiate】
(1)用于克隆游戏对象,也就是对象实例化


【Invoke】
(1)将函数调用安排在指定延迟后发生:Invoke(“generateobject”,2);【由两部分组成,generateobject是一个字符串,用于输入我们想要调用的方法名称,另一个数字2是以秒为单位的延时时长,则它会在两秒后才会调用generateobject方法】
(2)注意:只有不包含参数且返回值为void的方法才能被Invoke调用:void generateobject(){}


【InvokeRepeating】
(1)InvokeRepeating(“geneobject”,2,1);【由三部分组成,geneobject是我们想调用的方法名称,2是调用方法的延时,1是后续方法调用的延时,也就是刚开始先延时两秒调用后,每过一秒重新调用一次】
(2)停止的方法:CancelInvoke(“geneobject”);【输入一个字符串,其中包含我们想要暂停的方法名称】


【枚举】
(1)enum,这是一种特殊的数据类型,有特定的子集;枚举也可以在一个class类内或类外创建,也可以单独创建只包含枚举的c#脚本,然后就可以在其他的脚本中使用它
(2)例:enum Direction{North, East ,South ,West};【用于表示方位,注意!枚举类型的花括号结尾需要加上分号;而这个枚举中声明的每个常量都有一个默认的值,从0开始往上数的整数,因此North的值为0,West的值为3】
(3)同时也可以声明枚举的规定:enum Direction {North=12, East=14 ,South=22 ,West=28};以此类推
(4)也可以更改枚举中的常量类型,常量可以更改为任意整数类型,如需要更改,则在枚举名称后添加一个冒号,然后在后面输入类型即可,例如更改为短整型:enum Direction : short{North, East ,South ,West};
(5)声明好枚举后,接着设定枚举类型的变量:Direction dir; ,之后为变量赋值:dir=Direction.North等等枚举中的常量

 

你可能感兴趣的:(C#知识树,Unity知识树,unity,c#,游戏程序)