惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
Vercel News
Vercel News
Recent Announcements
Recent Announcements
B
Blog RSS Feed
Y
Y Combinator Blog
M
MIT News - Artificial intelligence
MongoDB | Blog
MongoDB | Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
D
Docker
Jina AI
Jina AI
IT之家
IT之家
人人都是产品经理
人人都是产品经理
L
LangChain Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
博客园 - 叶小钗
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog

博客园 - 华安

C#中Microsoft.Extensions.Caching.Memory 与 System.Runtime.Caching.MemoryCache区别 自适应网格系统:CSS Grid中repeat()、auto-fill与auto-fit的深度解析 CSS3中响应式布局两大神器display:flex和display:grid springBoot中的 pom.xml文件 bulid学习 CSS中元素的display显示方式有多种,隐藏、块级、内联、内联-块级 SQl Server 中的 go 是什么作用 CSS中 display:flex的align-items: stretch; 移动端浏览器(尤其是 iOS Safari)的橡皮筋回弹效果(Overscroll / Bounce Effect) 手机端浏览器上ES6中的Fetch回调执行 window.open没效果 用Flex实现兼容性好的全屏布局 在 VS Code 中使用 C# Dev Kit 和 Unity Tools 调试 Unity 2022 Unity 可编程物件(ScriptableObject) 微信小程序中的 联系客服 最基本的使用方法 wx.requestSubscribeMessage(Object object) 和 wx.requestSubscribeDeviceMessage(Object object) 这两个有什么区别 微信小程序中 wx.hideLoading() 后调用 wx.showToast()的问题 Windows 中启动 Nginx的常用命令 CSS进阶技巧:字体渐变、描边、倒影与渐变色描边全解析 netCore 中各DLL引用了 SkiaSharp.dll的问题 unity中预制体解包 在 Unity 中,Time.timeScale实现游戏暂停加速等 微信小程序中关联微信支付 unity中的 Navigation AI使用 C#中TaskCompletionSource(简称 TCS)学习 Unity 编辑器 中,快捷键 Ctrl + Shift + F 的功能 unity中按下 F键,让物体聚焦 微信中进入定页面的,判断时通过扫二维码进入的,还是点小程序名称进入的 MYSQL中从JSON字符串中提取指定的值 Unity2022中创建动画 Animation(旧方法) Unity中 onCollisionEnter2D与OnTriggerEnter2D 区别 asp.netCore中给动态请求路径加客户端缓存
Unity 中区别,public 和 [SerializeField]
华安 · 2026-07-25 · via 博客园 - 华安

在 Unity 中,public[SerializeField] 都用于在 Inspector 中显示字段,但它们的核心区别在于访问权限和封装性。

核心区别

特性public[SerializeField]
Inspector 可见性 ✅ 可见 ✅ 可见
外部访问权限 ✅ 任何类都可访问 ❌ 只有本类可访问
封装性 ❌ 破坏封装 ✅ 保持封装
使用场景 需要外部访问 仅需 Inspector 编辑

详细说明

public 字段

public class Player : MonoBehaviour
{
    public float speed = 5f;  // 其他类可以直接修改
}
  • 任何其他类都可以通过 player.speed 访问和修改
  • 破坏了面向对象的封装原则
  • 可能导致不可预期的修改

[SerializeField] 私有字段

public class Player : MonoBehaviour
{
    [SerializeField] private float speed = 5f;  // 只有本类可修改
}
  • 保持私有性,其他类无法直接访问
  • 仍然在 Inspector 中可见可编辑
  • 遵循封装原则

推荐实践

推荐使用 [SerializeField] 的场景

public class Player : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 5f;
    [SerializeField] private GameObject bulletPrefab;
    [SerializeField] private int maxHealth = 100;
    
    // 如果需要外部访问,提供公共属性
    public float MoveSpeed => moveSpeed;
    public int MaxHealth => maxHealth;
}

应该使用 public 的场景

public class GameManager : MonoBehaviour
{
    // 其他类需要频繁修改
    public static GameManager Instance;
    
    // 需要被其他系统直接调用
    public void StartGame() { }
}

进阶技巧

使用属性封装

public class Player : MonoBehaviour
{
    [SerializeField] private int health = 100;
    
    public int Health 
    { 
        get => health;
        set 
        {
            health = Mathf.Clamp(value, 0, maxHealth);
            OnHealthChanged?.Invoke(health);
        }
    }
    
    public event System.Action<int> OnHealthChanged;
}

使用 [SerializeField] 的扩展

public class Weapon : MonoBehaviour
{
    [SerializeField] private int damage = 10;
    [SerializeField] [Range(0, 100)] private int accuracy = 80;
    [SerializeField] [Tooltip("子弹速度,单位:米/秒")] private float bulletSpeed = 100f;
    [SerializeField] [HideInInspector] private int serialNumber; // 序列号不在Inspector显示
}

总结

  • 优先使用 [SerializeField] private:保持封装性,只暴露必要的 Inspector 接口
  • 仅在需要外部访问时使用 public:如静态单例、公共方法等
  • 考虑使用属性:在需要额外逻辑(验证、触发事件)时替代直接暴露字段
  • 团队协作:建议制定统一的编码规范,明确何时使用哪种方式

这样做既能保持代码的健壮性,又能充分利用 Unity Inspector 的可视化编辑优势。