Unity的C#编程教程

    科技2025-04-20  4

    文章目录

    C# Properties1.Properties2.Auto Properties3.When to Use Properties Challenge: Declaring Properties

    C# Properties

    1.Properties

    什么是属性 其实就是一种变量可以从中获取数据可以运行函数控制访问修饰符 control access modifiers

    来看案例:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { // Start is called before the first frame update void Start() { transform.position = new Vector3(0, 0, 0); // 为什么通过这个语句可以进行赋值操作呢? // 鼠标移动到 position 上面可以看到 {get;set;} // 说明我们可以从中获取数据,也可以设置数据 // 另外一个例子是:Time.deltaTime 增量时间(代表时间修正到真实时间) // 如果鼠标移动到说明可以看到 {get;} // 这表示只能获取,不能设置 // 所以我们不能赋值,即不能写成 Time.deltaTime = 5; 这样 } // Update is called once per frame void Update() { } } 如何定义我们自己的 property

    假设我们设置一个 bool 变量监控游戏是否结束:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { public bool isGameOver; // 指示游戏是否结束 // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } public void GameOver() // 当玩家死亡的时候触发调用该方法 { isGameOver = true; // 游戏结束变为 true 的时候,游戏 UI 显示 GAME OVER } }

    其实我们可以直接在 property 的内部进行相应的操作:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { private bool isGameOver; // 指示游戏是否结束 // 设置为 private 后仅有该脚本本身可以访问该变量 // 我们希望该变量变为只读 public bool IsGameOver // property 的声明,使用 pascal casing 命名方式 { get { return isGameOver; // 读取对应数值 } set { isGameOver = value; // 赋值操作,这里 value 的数据类型需要和目标一致,这里为 bool } } // Start is called before the first frame update void Start() { isGameOver = false; // 游戏开始,初始化为 false } // Update is called once per frame void Update() { } }

    当我们设置了 property 的声明后,在下面的语句中输入 isGameOver 后,鼠标移动到上面就可以看到 {get; set; },如果仅仅设置了 get,那会显示 {get; }。

    然后我们把修改 UI 的链接内置到 property 中:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { private bool isGameOver; // 指示游戏是否结束 // 设置为 private 后仅有该脚本本身可以访问该变量 // 我们希望该变量变为只读 public bool IsGameOver // property 的修饰符,使用 pascal casing 命名方式 { get { return isGameOver; // 读取对应数值 } set { if (value == true) { Debug.Log("GAME OVER"); // 假设链接到 UI 上显示 GAME OVER } isGameOver = value; // 赋值操作,这里 value 的数据类型需要和目标一致,这里为 bool } } // Start is called before the first frame update void Start() { IsGameOver = false; // 游戏开始,初始化为 false } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) // 假设按下空格键表示玩家死亡 { IsGameOver = true; // 触发游戏结束的指示 } } }

    特别注意:这里在脚本里输入 isGameOver 后有两个选择,一个是 F (isGameOver),另外一个是 P (IsGameOver),我们想要调用 get 和 set,就必须使用 P 的这个 IsGameOver。

    2.Auto Properties

    什么是 auto property 控制谁可以访问里面的信息设置只读,不能修改:删除 set 部分即可原来我们设置的时候,首先需要一个 private 变量,然后通过 property 来访问,但是现在 auto property,只需要一个语句

    举例:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { public bool IsGameOver { get; set; } // 设为 auto property // Start is called before the first frame update void Start() { IsGameOver = false; // 这里 auto property 可以当作普通的变量使用 // 但是和一般的 property 的区别在于,不能在里面添加额外的代码 } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) // 假设按下空格键表示玩家死亡 { IsGameOver = true; // 触发游戏结束的指示 } } }

    如果我们想要 IsGameOver 仅限至于本脚本可以更改,外部脚本只能访问而不能修改其值,在 set 前面添加 private 即可:

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { public bool IsGameOver { get; private set; } // 设为 auto property // Start is called before the first frame update void Start() { IsGameOver = false; // 这里 auto property 可以当作普通的变量使用 // 但是和一般的 property 的区别在于,不能在里面添加额外的代码 } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) // 假设按下空格键表示玩家死亡 { IsGameOver = true; // 触发游戏结束的指示 } } }

    根据需要,如果需要子类可以访问修改,那设置成 protected set 即可。

    总结一下,property 是让我们拥有了一个可变性更强的,更智能的“变量”。

    但是 property 有个缺点,就是无法在 inspector 中查看(除非进入 debug 模式)。

    3.When to Use Properties

    什么时候使用 properties 呢? 通常用在 manager classes 中比如整个游戏的控制脚本,监控游戏角色是否死亡,控制主体游戏进程,目前游戏关卡等比如游戏角色死亡状态,只有主进程 game manager 可以设定,其他脚本只能进行只读访问,那就适合设置为 property还比如说游戏得分,也是类似的这样的设置方法是为了更为合理,减少游戏 bug,减少游戏漏洞,减少程序的安全问题。如果随便一个脚本就可以把角色改为死亡状态,或者直接改掉总得分,那绝对会出问题!另外,在最佳的编程实践中,所有变量都应该默认是 private 的,除非该变量有不得不设置为 public 的理由unity 中 properties 不会在 inspector 中显示property 不能像普通的变量那样,在命名的时候进行初始化赋值,所以需要在 start 方法中进行初始化另外一种情况使用 property,在 spawn manager 中,希望监控生成了多少 enemy 总数,因为这个数据不需要我在 inspector 中进行修改

    Challenge: Declaring Properties

    任务说明 设计 2 个 properties一个是:速度,要求对于别的脚本只读一个是:名字尝试使用 auto properties 和 declaring properties在 declaring properties 中使用 Debug.Log 显示该方法被调用在 start 方法中测试 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PropertyTest : MonoBehaviour { public int Speed { get; private set; } // 速度,对于别的脚本只读 private string _playerName; // 名字 public string PlayerName { get { Debug.Log("get method called"); return _playerName; } set { Debug.Log("set method called"); _playerName = value; } } // Start is called before the first frame update void Start() { Speed = 16; Speed += 10; Debug.Log("Speed: " + Speed); PlayerName = "Mike"; PlayerName += "s"; Debug.Log("Player name: " + PlayerName); } // Update is called once per frame void Update() { } }

    Processed: 0.009, SQL: 8