unity笔记


unity笔记

一些重要概念

project工程:一个游戏即一个工程
scene场景:一个游戏包括很多场景/关卡
gameobject游戏对象: 构成游戏的各种对象。如场景模型,角色以及其他抽象(控制模块)单的确存在于场景中的对象
component组件:是unity的核心架构。每个游戏对象有一个或者多个组件构成,每种组件赋予游戏对象某种功能
script脚本:是实现component的脚本程序。现在unity支持c#语言
prefabs预置:在unity3d中为游戏对象添加各种组件,并设置好他的属性和行为,然后反复利用。

C#入门

GetKeyDown:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExampleBehaviouirScript : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            GetComponent<Renderer>().material.color = Color.red;
        }
    }
}

Debug.log:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class VariablesAndFunctions : MonoBehaviour
{
    int myInt = 5;

    void Start()
    {
        myInt = 55;
        Debug.Log(Mul(myInt) * 2);
        Debug.Log(transform.position.x);
        if(transform.position.y <= 5f)
        {
            Debug.Log("hit the ground!");
        }
    }
    public int Mul(int m)
    {
        return m * m;
    }
}

ifStatements:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class IfStatements : MonoBehaviour
{
    float coffeeTemperature = 85.0f;
    float hotLimitTemperature = 70.0f;
    float coldLimitTemperature = 40.0f;
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            TempratureTest();
        coffeeTemperature -= Time.deltaTime * 5f;
    }
    void TempratureTest()
    {
        if (coffeeTemperature > hotLimitTemperature)
        {
            print("Coffee is too hot");
        }
        else if (coffeeTemperature < coldLimitTemperature)
        {
            print("Coffee is too cold");
        }
        else
        {
            print("Coffee is just right");
        }
    }
}
// if ...else
if(a==xx)
{}
else if(b=xx)
{}
else
{}

// switch
switch(op)
{
case "+":
	xxxx
	break;
default:
	xxx
	break;
}

Loop

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoopTest : MonoBehaviour
{
    int cupsInTheSink = 4;
    int numEnemies = 3;
    void Start()
    {
        //while
        while (cupsInTheSink > 0)
        {
            Debug.Log("i've washed a cup");
            cupsInTheSink--;
        }
        //do
        bool shouldC = false;
        do {
            print("Hello World"); 
        } while (shouldC == true);
        //for
        for (int i = 0; i < numEnemies; i++)
        {
            Debug.Log("Creating enemy number: " + i);
        }
    } 
}
// loop
for(xxx;xxx;xxx)
{
	xxx
}
  // 先判断
while(xxx)
{
	xxx
}
  // 先执行一次,再判断
do{
	xxx
}while(xxx)

// foreach
int a[6]={1,2,3,4,5,6}
foreach(var b in a)
{
  //这里面不能对b不赋值外,基本和python的for in相同
}

作用域和访问修饰符

// ScopeAndAccessModifiers:

// 在当前脚本访问其他脚本中的公开函数

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScopeAndAccess : MonoBehaviour
{
    private VariablesAndFunctions myOtherClass;
    void Start()
    {
        myOtherClass = new VariablesAndFunctions();
        Debug.Log(myOtherClass.Mul(2));
    }
}

访问修饰符

访问修饰符实在声明变量时放在数据前面的关键词,其作用是定义能够看到变量或函数的位置。

一般而言,如果其他脚本需要访问某个变量或函数时,就应将其公开,否则就设为私有。

  • public: 类外(其他脚本)可以访问
    • 公开变量:可从外部访问这个变量,且可在Inspector中的组件上显示和编辑。
  • private: 只允许类内访问,默认私有
  • protect: 允许子类访问

Awake and start

Awake和Start都在游戏运行之前会被调用,类似构造函数,Awake不论脚本是否挂载都会运行而Start则需要脚本被挂载.

  • Awake: 初始化之前,脚本不启用也会初始化,只能调用一次。
  • Start: Awake 之后,首次 Updata 之前,脚本启用才会初始化,只能调用一次。

Update and FixedUpdate

  • Update: 使用的脚本每帧调用一次,调用间隔不同,非物理相关。基本上需要变化和需要调整整的都需要使用Update来实现。非物理对象的移动,简单的计时器,输入检测等。

    Update并不是ian固定过的时间调用的,如果某一帧比下一帧的处理时间长,那么Update调用的时间间隔就会不同。

  • FixedUpdate: 固定时间,间隔相同调用,每秒调用50次,用于物理(Rigibody)相关函数,力相关。

(Ctrl+Shift+M可以启用向导)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class UpdateAndFixedUpdate : MonoBehaviour
{
    private float fixedUpdateTimer;
    private float UpdateTimer;
    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate time :" + Time.deltaTime);  // Time.deltaTime 每帧增加的间隔时间
    }
    /*private void Update()
    {
        //Called every frame
        //Used for regular updates such as:
        //moving non-physics objects 移动非物理对象
        //simple timers 简单的计时器
        //receiving input 输入检测


        //update interval times vary
        Debug.Log("update time :" + Time.deltaTime);
    }*/
}
// 结果
Updata Time: 0.0023467	0.0023239 ……
FixedUpdata Time: 0.02	0.02  0.02 ……

点积和差积

Dot 点积 Cross 叉积
计算得到数值,==0为垂直,可用于飞机飞行方向判断 计算得到矩阵,可用于炮塔朝向
Vector3. Dot (VectorA, VectorB) Vector3. Cross (VectorA, VectorB)
  • 点积: 得到两矢量点是否垂直

  • 叉积: 得到垂直于两矢量的第三矢量

启用和禁用组件(EnableComponent)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnableComponents : MonoBehaviour
{
    private Light myLight;
    private void Start()
    {
        myLight = GetComponent<Light>();      
    }
    private void Update()
    {
        if (Input.GetKeyUp(KeyCode.Space))
        {
            myLight.enabled = !myLight.enabled; //将myLight变为非当前状态
        }
    }
}
// 模板
Component.enabled = false or true;
// unity官方案例
public class LightEnable : MonoBehaviour
{
    private Light pointLight;

    // Start is called before the first frame update
    void Start()
    {
        pointLight = GetComponent<Light>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyUp(KeyCode.Space))  // GetKeyUp 按下弹起算一次
            pointLight.enabled = false;
    }
}

激活游戏对象

用active来检查对象激活状态,如果对象的父级未被激活,则即使使用了setactive方法也无法激活对象.

Hierarchy 窗口 -> GameObject 是否开启

>gameObject.SetActive(false);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CheckState : MonoBehaviour
{
    public GameObject myObject;
    void Start()
    {
        myObject.SetActive(true);
        Debug.Log("active self: " + myObject.activeSelf);
        Debug.Log("active in hierarchy: " + myObject.activeInHierarchy);
        // 要确认某个对象在场景或在层次结构中是否处于活跃状态,可以使用Active Salf和Active in hierarchy 状态查询 
        // 父级不关闭的状态下,运行时,子对象被激活,他所处的层次结构也被激活;如果停用父对象,子对象被激活,而他所在的层次结构却未被激活。这是因为父对象已被停用,因此他在场景中也不是活跃状态。
        //当子对象由于其父对象被禁用而随之被禁用时,使用set up to true,也不会激活子对象。要再次激活子对象,就必须激活父对象。
    }
}

Tranlate and Rotate

平移和旋转:针对局部坐标(Local axis),而非世界坐标

Vector3. forward and Vector3. Up 都是局部坐标

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TransformFunctions : MonoBehaviour
{
    public float moveSpeed = 10f;
    public float turnSpeed = 50f;
    
    // Update is called once per frame
    void Update()
    {
        if(Input.GetKey(KeyCode.UpArrow))  // GetKey 长按
            transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);  // 作用于 Local axis 局部坐标
        if (Input.GetKey(KeyCode.DownArrow))
            transform.Translate(-Vector3.forward * moveSpeed * Time.deltaTime);
        if (Input.GetKey(KeyCode.LeftArrow))
            transform.Rotate(Vector3.up * -turnSpeed * Time.deltaTime);  // up表示哪个轴
        if (Input.GetKey(KeyCode.RightArrow))
            transform.Rotate(Vector3.up * turnSpeed * Time.deltaTime);
    }
}
  • 如果想用碰撞体移动某个对象,也就是将会产生物理作用的物体,则不应使用Translate 和Rotate函数,而是考虑使用Physics函数

LookAt

GameObject 的 forward 指向世界坐标(World axis)的另一个transform

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraLookAt : MonoBehaviour
{
	// 摄像机看向目标
    public Transform target;
    void Update()
    {
        transform.LookAt(target);
    }
}

Destory

可以销毁对象,也可以销毁对象挂载的组件,第二个形参可以设置delay时间

删除一个游戏物体或组件等。如果Object实际上为组件,则会将其从gameobject中删除并销毁;如果实际上为gameobject则将销毁它的全部组件及其所有子物体。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DestroyBasic : MonoBehaviour
{
    public GameObject other;
    public GameObject another;
    void Update()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            Destroy(gameObject);
            Destroy(other);
            Destroy(another.GetComponent<MeshRenderer>(),3f);
        }
    }
}
// unity官方
// 销毁对象or组件,第二个参数为延时(delay)
Destory(GameObject, 3f);
Destory(GetComponent<MeshRenderer>());

GetButten and GetKey

GetButton:输入管理器 Project Setting -> Input 设置按键,string 类型传入按键名

>bool Up = Input.GetButtonUp("Jump");

GetKey:GetKey(KeyCode. X) 具体指定按键

bool crouch = Input.GetKey(KeyCode.S)			//长按
Input.GetKeyUp(KeyCode.S)						//按下弹起一次后触发
Input.GetKeydown(KeyCode.S)						//按下就触发

GetKey会使用KeyCode明确指定按键名称

没按 按下去 继续按(持续一帧) 松开 持续一帧
GetButtenDown False True False False False
GetButten False True True False False
GetButtenUp False False False True False
  • GetKey与GetButten的行为完全相同,且都返回bool。
  • 要查看按钮的状态,使用输入管理器内输入的标题字符串jump
void Update()
{
	bool down = Input.GetButtenDown("Jump");
	bool held = Input.GetButten("Jump");
	bool up = Input.GetButtenUp("Jump");
}
  • 如果要查看特定键的状态可以使用KeyCode。因为KeyCode只与特定键相关,所以建议使用GetButten,并用输入管理器指定输入。

GetAxis(轴)

与上两者相似,但返回浮点值(-1<float<1)

GetAxis: 输入管理器 Project Setting -> Input 设置按键,string 类型传入按键名

  • 对于butten(按钮),我们只需要关注“Positive Butten”的值,但是对于Axis(轴),除了“Positive Butten”,“Negative Butten”,还要关注“Gravity”,“Sensitivity”,“Dead”和“Snap”
Gravity 影响滑尺在按钮松开后归零的速度;值越高,归零速度越快
Sensitivity 与Gravity相反,控制着输入的返回值,即达到1/-1的速度有多快;值越大,反应速度越快
Dead 如果我们用操纵杆表示轴,那麽我们就不想感受到操纵杆轻微移动的作用,所以需要盲区;值越大,盲区越大,操纵杆的幅度也必须越大,才能让GetAxis返回非0值
Snap 同时按下正负按钮时归零

为了获得横轴或竖轴的值,只需在代码中添加一个Input.GetAxis(“Horizontal”)或Input.GetAxis(“Vertical”)。也可以使用Input.GetAxisRaw(”Horizontal”),仅返回整数,不返回非整数,适合需要精准控制的二维游戏,而不适用于需要平滑值的游戏,注意他不需要Gravity或Sensitivity。

float h = Input.GetAxis("Horizontal");
float V = Input.GetAxis("Vertical");

OnMouseDown

OnMouseDown及其相关函数可检测对碰撞体或GUI文本元素的点击

># 判断鼠标点击
>void OnMouseDown()
>{
rb.AddForce(-transform.forward * 500f);	//鼠标点击推出物体
>}  

GetComponent

GetComponent 是访问游戏对象的组件的方法

GameObject.GetComponent<type>()

说明:

  • GameObject 是定义 GameObject 游戏对象的变量名。

  • type 是组件名称,类型是 string。

UsingOtherComponent

using UnityEngine;
using System.Collections;

public class UsingOtherComponents : MonoBehaviour
{
    public GameObject otherGameObject;
    
    private AnotherScript anotherScript;
    private YetAnotherScript yetAnotherScript;
    private BoxCollider boxCol;
    
    //使用Awake减少开销
    void Awake ()
    {
        anotherScript = GetComponent<AnotherScript>();   
        yetAnotherScript = otherGameObject.GetComponent<YetAnotherScript>();   //可调用其他物体上的脚本
        boxCol = otherGameObject.GetComponent<BoxCollider>();    //可调用其他物体上的碰撞体
    }
    
    
    void Start ()
    {
        boxCol.size = new Vector3(3,3,3);
        Debug.Log("The player's score is " + anotherScript.playerScore);  //可修改其他物体上脚本里的参数
        Debug.Log("The player has died " + yetAnotherScript.numberOfPlayerDeaths + " times");  
    }
}

AnotherScript

using UnityEngine;
using System.Collections;

public class AnotherScript : MonoBehaviour
{
    public int playerScore = 9001;
}

YetAnotherScript

using UnityEngine;
using System.Collections;

public class YetAnotherScript : MonoBehaviour
{
    public int numberOfPlayerDeaths = 3;
}
       MyComponment myCom=gameObject.GetComponent<MyComponment>();
 
MyComponment childCom=gameObject.GetComponentInChildren<MyComponment>();
 
MyComponment[] comS=gameObject.GetComponents<MyComponment>();
 
MyComponment[] comS1=gameObject.GetComponentsInChildren<MyComponment>();
 
MyComponment[] comSTrue=gameObject.GetComponentsInChildren<MyComponment>(true);
 
MyComponment[] comSFalse=gameObject.GetComponentsInChildren<MyComponment>(false);
  • GetCompoment ()从当前游戏对象获取组件T,只在当前游戏对象中获取,没得到的就返回null,不会去子物体中去寻找。

  • GetCompomentInChildren()先从本对象中找,有就返回,没就子物体中找,知道找完为止。

  • GetComponents()获取本游戏对象的所有T组件,不会去子物体中找。

  • GetComponentsInChildren()=GetComponentsInChildren(true)取本游戏对象及子物体的所有组件

  • GetComponentsInChildren(false)取本游戏对象及子物体的所有组件 除开非活跃的游戏对象,不是该组件是否活跃。

DeltaTime

Time 类的 DeltaTime 用于计算两次更新或固定函数调用的间隔时长,用于移动或其他增量变化变得平滑

因为完成一帧的时长是不一致的,按完成每帧做速率会不平滑

Speed * Time.deltaTime 用于速率恒定

using UnityEngine;
using System.Collections;

public class UsingDeltaTime : MonoBehaviour
{
    public float speed = 8f; 
    public float countdown = 3.0f;

    
    void Update ()
    {
        countdown -= Time.deltaTime;
        if(countdown <= 0.0f) //亮灯
            light.enabled = true;
        
         if(Input.GetKey(KeyCode.RightArrow)) //平滑移动
            transform.position += new Vector3(speed * Time.deltaTime, 0.0f, 0.0f);
    }   
}

数据类型

  • 值类型变量包含某个值,而所有引用类型变量都包含值存储位置的存储地址。因此如果值类型该改变,则只会影响特定变量 ;但如果引用类型改变,所有包含特定存储地址的变量都会受到影响。
using UnityEngine;
using System.Collections;

public class DatatypeScript : MonoBehaviour 
{
    void Start () 
    {
        //值类型变量
        Vector3 pos = transform.position;
        pos = new Vector3(0, 2, 0); // 值类型,只有pos会受这行代码的影响,而transform.position不受影响
        
        //引用类型变量
        Transform tran = transform; //赋值语句,使tran和transform指向同一个存储地址
        tran.position = new Vector3(0, 2, 0); 	//tran引用类型,更改其中一个,另一个也会在随之改变。
    } 
}

面向对象编程:将脚本拆分成多个脚本,每一个脚本承担一个角色或职责

重要的类

譬喻:变量 –> 盒子,函数–>机器,类 –> 他们所在的工厂

类是一个容器,用来储存变量和函数,具备多种功能,包括将配合工作的要素组合起来。他们是有组织结构的工具,属于面向对象编程(OOP)。

原则是将一个脚本拆分成多个脚本,其中每一个脚本成本单一个角色或职责。因此类非常适合战门完成一项职责。

创建类或者struct时,都要调用构造函数,类或struct都可以有多个构造函数,这些函数使用不同的参数。

GameObject 表示可以存在于场景中的对象的类型。
MonoBehaviour 基类,默认情况下,所有 Unity 脚本都派生自该类。
Object Unity 可以在编辑器中引用的所有对象的基类。
Transform 提供多种方式来通过脚本处理游戏对象的位置、旋转和缩放,以及与父和子游戏对象的层级关系。
Vectors 用于表达和操作 2D、3D 和 4D 点、线和方向的类。
Quaternion 表示绝对或相对旋转的类,并提供创建和操作它们的方法。
ScriptableObject 可用于保存大量数据的数据容器。
Time(以及帧率管理) Time 类用于测量和控制时间,并管理项目的帧率。
Mathf 一组常见的数学函数,包括三角函数、对数函数以及游戏和应用开发中常用的其他函数。
Random 提供简便的方法来生成各种常用类型的随机值。
Debug 用于可视化编辑器中的信息,这些信息可以帮助您了解或调查项目运行时发生的情况。
Gizmos 和 Handles 用于在 Scene 视图和 Game 视图绘制线条和形状以及交互式手柄和控件。
using UnityEnging;

public Class Inventory: MonoBehavior //Inventory Class
{
    public class Stuff //stuff子类,包含三个int变量:projectileA/B/C
    {
        public int projectileA;
    	public int projectileB;
    	public int projectileC;
    	public float fuel;  //如果加入了新的变量,但是在原类的构造函数中并没有对其进行操作,那么我们可以再设置一个构造函数,来为我们执行这个赋值操作(vsc CTOR+Tab插入代码片段)
    }
	
    //一个类可以有多个构造函数,但是只能调用其中的一个进行初始化。
    // 构造函数,与类同名,可以重载,不需要返回值,构造函数用于初始化
    public stuff(int prA, int prB, int prC)  //可以编写自己的构造函数来为这些变量设置参数
    {
        projectileA = prA; //将变量赋值给参数,我们在创建对象或创建类实例时,可以在下面使用括号来定义默认值。
        projectileB = prB;
        projectileC = prC;
    }
    public stuff(int prA, float fu) //此构造函数用来设置新的对象fule
    {
        projectileA = PRa;
        fuel = fu;
    }
    public Stuff() //构造函数允许设置默认值,限制实例化以及编写灵活易读的代码
    {
        projectileA = 1;
        projectileB = 1;
        projectileC = 1;
    }
    
    // 实例化
    public Stuff myStuff = new Stuff(50, 5, 5); //创建子类Stuff的实例,名为Object。我们能给他指定数据类型,也就是类的名称;接着给他命名,也就是“new”,然后使用类的名称。类名称结尾处的括号表明使用的是构造函数
    public Stuff myOtherStuff = new Stuff(20, 50.5f); //会实例化新的对象,因为参数匹配。,而类的其他变量的实例化将会使用上面的代码,因为参数匹配。
    
    void Start()
    {
        Debug.Log(myStuff.projectileA);
    }
	
}

这里直接搬了大佬文章关于实例构造函数的解释:

实例构造函数

  • 构造函数的名字与类名相同
  • 使用new表达式创建类的对象时,会调用其构造函数。并且通常初始化新对象的数据成员。
  • 除非类是静态的,否则会为没有构造函数的类,自动生成一个默认构造函数,并使用默认值来初始化对象字段。
  • 构造函数可以有参数,可以以参数个数、参数类型、参数顺序不同的形式存在多个构造函数。
class Program
    {
        static void Main(string[] args)
        {
        	Student stu1 = new Student();//无参构造函数调用
			Student stu2 = new Student(10,"20");
			Console.WriteLine($"X={stu1.X}---Y={stu1.Y}");//结果为:X=0---Y=0
            Console.WriteLine($"X={stu2.X}---Y={stu2.Y}");//结果为:X=10---Y=20
            Console.ReadLine();
        }
    }
class Student
    {
        public int X { get; set; }
        public string Y { get; set; }
        //无参构造函数
        public Student()
        {
            this.X = 0;
            this.Y = "0";
        }
        //有两个参数构造函数
        public Student(int x, string y) {
            this.X = x;
            this.Y = y;
        }
    }


————————————————
版权声明:本文为CSDN博主「Just Do Its」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liu991029/article/details/106550226

Instantiate

Instantiate 用于克隆 gameObject,常用于克隆 Prefabs,即预配置对象。返回值为object的,在制作游戏的过程中,为了投射抛射体并给他添加作用力,强制类型转换为Rigidbody,然后将返回值放在Rigidbody中。

例如抛射出的物体

>Instantiate(object);	// 参数为想克隆的对象
>Instantiate(object, position, rotation);	// 指定位置和角度
using UnityEngine;
using System.Collections;

public class UsingInstantiate : MonoBehaviour
{
    public Rigidbody rocketPrefab;
    public Transform barrelEnd;
    
    
    void Update ()
    {
        if(Input.GetButtonDown("Fire1"))
        {
            Rigidbody rocketInstance;
            rocketInstance = Instantiate(rocketPrefab, barrelEnd.position, barrelEnd.rotation) as Rigidbody; //克隆对象并将其类型强追转换未刚体并赋值给刚体
            rocketInstance.AddForce(barrelEnd.forward * 5000);
        }
    }
}

发射刚体后销毁刚体:

using UnityEngine;
using System.Collections;

public class RocketDestruction : MonoBehaviour
{
    void Start()
    {
        Destroy (gameObject, 1.5f);
    }
}

数组

储存同类型数据

int[] myIntArray = new int [3];
myIntArray[0] = 1;
myIntArray[1] = 2;
myIntArray[2] = 3;

int[] myInyArray = {1, 2, 3};

public GameObject[] players; //如果将数组设为公开,并为他分配值,保存脚本并返回控制台,就能看到在脚本分配给对象的位置,players数组公开显示在Inspector中
using UnityEngine;
using System.Collections;

public class Arrays : MonoBehaviour
{
    public GameObject[] players;

    void Start ()
    {
        players = GameObject.FindGameObjectsWithTag("Player"); //寻找游戏中tab未“Player”的GameObject,并将其放入数组
        
        for(int i = 0; i < players.Length; i++)
        {
            Debug.Log("Player Number "+i+" is named "+players[i].name);
        } //按顺序输出tab为“Player”的GameObject的名字
    }
}

Invoke

延时执行

public GameObject target;

void Start()
{
    Invoke("SpawObject", 2);	// 2s后实例化出target
    InvokeRepeating("SpawObject", 2, 1);	// 2s后实例化出target,生成后间隔为1秒	
    
    CancelInvoke("SpawObject");		// 取消循
}

void SpawObject() 
{ 
    float x = Random.Range(-2.0f, 2.0f);	// Random 随机n Range 范围n
    Instantiate(target, new Vector(0, 2, 0), Quaternion.identity); //只会将位置(0,2,0)处的target对象实例化
}
  • 只有不包含参数,且返回类型未void的mathod,才能用Invoke调用。

枚举

列出枚举值,定义变量,选择枚举值给变量赋值

using UnityEngine;
using System.Collections;

public class EnumScript : MonoBehaviour 
{
    enum Direction {North, East, South, West}; //这个枚举中  声明的每个常量,都有一个值,默认为{0,1,2...}。如果需要的话,值的类型和值本身都可以被覆盖,如{North = 1, East, South, West} / {North = 10, East = 23, South = 45, West = 0}  / enum Direction : short {North, East, South, West}

        void Start () 
    {
        Direction myDirection;
        
        myDirection = Direction.North;
    }
    
    Direction ReverseDirection (Direction dir) //enum可以在函数中使用
    {
        if(dir == Direction.North)
            dir = Direction.South;
        else if(dir == Direction.South)
            dir = Direction.North;
        else if(dir == Direction.East)
            dir = Direction.West;
        else if(dir == Direction.West)
            dir = Direction.East;
        
        return dir;     
    }
}
  • 枚举可以在class内或者外创建,我们也可以创建只含此枚举的c#脚本,我们不将其声明为class,而是声明为enum,然后可以在其他scripts的class中,使用这个enum,因为他是public的。

switch语句

更简洁的选择语句,避免选择多时代码变得冗长

using UnityEngine;
using System.Collections;

public class ConversationScript : MonoBehaviour 
{
    public int intelligence = 5;
    
    
    void Greet()
    {
        switch (intelligence)
        {
        case 5:
            print ("Why hello there good sir! Let me teach you about Trigonometry!");
            break;
        case 4:
            print ("Hello and good day!");
            break;
        case 3:
            print ("Whadya want?");
            break;
        case 2:
            print ("Grog SMASH!");
            break;
        case 1:
            print ("Ulg, glib, Pblblblblb");
            break;
        default: //在最后一个实力中,我们需要获取所有无专属实例的内容,为此,此处不用case,而是使用另一个关键词default,它不需要有值。
            print ("Incorrect intelligence level.");
            break;
        }
    }
}
  • vsc快捷键:s-w+Tab

文章作者: 白昀
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 白昀 !
评论
  目录
.js">