找回密码
 立即注册
查看: 853|回复: 10

[笔记] 在unity中用C#写脚本,注释要写到什么程度最合适?(请举例)

[复制链接]
发表于 2021-9-27 08:44 | 显示全部楼层 |阅读模式
在另一个问题的的答案下引发的关于写注释到底该写什么?写多少?怎么写?的讨论Unity做游戏有哪些比较好的代码管理方式? - 路人甲的回答

我是认为:除了参数函数说明,也该把不懂的和记不住的部分写上去。
写多点没关系。
虽然用///可以自动补全注释,但是会导致占用的行数过多,所以除了变量和函数的说明是在头上///一下(方便其他函数调用的时候有提示),函数内部的注释我就全部用//补在同一行。

我的想法明显不是写注释的最优方案。所以请问你们觉得注释要写什么?写多少?怎么写?才能让人(包括自己)看的懂,看的容易,看的爽。
发表于 2021-9-27 08:50 | 显示全部楼层
逻辑层的代码我一般会拆分的足够细,然后不写注释……靠函数名来表达意思(其实原因是懒,而且变化太快……

框架层的代码会写到函数级别的注释,譬如这种
    /// <summary>
    /// load an prefab obj from a given url and don't cache it!
    /// we'll try assetbundle first than resource
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path"></param>
    /// <returns></returns>
    public T LoadWithoutCache<T>(string path) where T : Object

另外#region是个好东西
发表于 2021-9-27 08:56 | 显示全部楼层
谢邀。以下情况请自行对号入座,有则改之,无则加勉,~\(≧▽≦)/~。

1、如果你过一段时间,就完全不知道自己写的代码,具体功能是做什么的,我建议你勤快点添加注释,连续三下///非常困难吗?

2、如果你没有良好的代码风格,经常花时间从混乱不堪的代码中,寻找代码片段复制粘贴,我建议你从现在开始写注释,方便找Bug。

3、不要说什么好的代码都是不需要注释的,在你没有做到独具匠心的时候,最好的策略是多写注释,多思考,少写代码。

4、很多人常常向别人提问,可是没有办法描述清楚问题本身,我建议你多写注释,因为注释是为了增强代码的可读性,帮助别人理解代码。

5、一件事情做出来非常伟大,可是能让别人理解这件事情的意义更加伟大,如果你热爱开源,从现在开始学着写注释、Commit Log,这样将来才会写出漂亮的README。
发表于 2021-9-27 09:03 | 显示全部楼层
一般我是这样的

// Filename:    XXXPanel.cs
// Summary:     XXX界面
// Version:     1.0.0
// Author:    xxx
// Date:    2016/05/04 11:37

#region

using System.Collections.Generic;
using MyExtensionMethod;
using Network;
using UnityEngine;

#endregion

public class XXXPanel : MonoBehaviour
{
    #region 变量定义
    private GameObject m_rankItem;
    private UIGrid m_grid;
    private UIScrollView m_scrollView;
    private GameObject m_leftArrow;
    private GameObject m_rightArrow;
    private ComponentList<ArenaRankItem, stPlayerInfoSub> m_rankIList;
    /// <summary>
    /// 翻页
    /// </summary>
    private PageTurn m_pageTurn;
    private const int m_perPageCount = 6;
    private const int m_perCellWidth = 160;
    #endregion

    #region 获取控件
    private void FindObject(Transform tr)
    {
        tr.Find(ref m_rankItem, "RankList/RankItem");
        tr.Find(ref m_grid, "RankList/ScrollView/Fill/Grid");
        tr.Find(ref m_scrollView, "RankList/ScrollView");
        tr.Find(ref m_leftArrow, "RankList/LeftArrow");
        tr.Find(ref m_rightArrow, "RankList/RightArrow");
    }
    #endregion

    private void Awake()
    {
        FindObject(transform);
        m_rankIList = new ComponentList<ArenaRankItem, stPlayerInfoSub>(m_grid.gameObject, m_rankItem);
    }

    public void UpdateWin(bool isShow = true)
    {
        if (!isShow)
        {
            Hidden(null);
            return;
        }

        gameObject.SetVisiable(true);
        m_rankIList.UpdateData(CData.arena.rankData.playerList);
        LoadLookFaceImage();
        int count = CData.arena.rankData.playerList.Count;
        m_pageTurn = new PageTurn(m_scrollView, m_leftArrow, m_rightArrow, count, m_perPageCount, m_perCellWidth);
        m_grid.onReposition = m_pageTurn.UpdateButtonState;
        m_scrollView.ResetPosition();
        m_grid.Reposition();
        MoveListCurrPosToTarget(count);
        m_scrollView.GetComponent<UIPanel>().onClipMove = OnListPanelClipMove;
        m_canOpt = true;
    }

    private void MoveListCurrPosToTarget(int count)
    {
        // 主界面启动,对所有抽取的选手排名进行排序确定玩家所处的顺位。
        // 当玩家顺位为最后三位时,则主界面初始显示最后6位;
        // 当玩家顺位非最后三位时,主界面初始显示,玩家前4位、玩家、玩家后1位;
        // 当玩家排名为前6位,主界面初始显示前6位。

        int index = CData.arena.myIndexInList + 1;
        if (count - index < 3)
        {
            Vector3 offset = new Vector3(-(count - m_perPageCount) * m_perCellWidth, 0);
            m_scrollView.MoveRelative(offset);
            m_pageTurn.UpdateButtonState();
        }
        else if (index > 6)
        {
            Vector3 offset = new Vector3(-(index + 1 - m_perPageCount) * m_perCellWidth, 0);
            m_scrollView.MoveRelative(offset);
            m_pageTurn.UpdateButtonState();
        }
    }

    private void OnListPanelClipMove(UIPanel panel)
    {
        float offsetx = panel.clipOffset.x;
        EventDispatcher.GameWorld.DispatchEvent(EventDefine.STR_ARENA_SCROLLVIEW_MOVE, offsetx);
    }
}
发表于 2021-9-27 09:03 | 显示全部楼层
说说我的做法吧
1.命名空间前有类/结构文件的注明(名字,作者,创建时间,版本,简介等)


这是我改VS的初始化文件样式自动生成的,网上很多教程。

2.方法属性有"///"的注释,第一,快捷方便,按三下就出来了,第二,输入方法属性名时可以显示注释,不用点进去看方法的参数是什么意思啊,属性是什么意思啊,第三,方便以后导出API文档

3.方法内使用//注释,一般在复杂逻辑和难懂的地方(例如写死数值)中会有,太简单的逻辑一般不注释。简单的注释了反而会让人难已阅读。

4.使用//TODO  (手机码字,“TODO”打错了,已修正,谢谢乌泊指出)
由于开发有时候可能比较跳跃,这样方便很久很久很久很久之后记得自己做到哪,还有啥逻辑没做。

5.使用#region,那样复杂的逻辑块可以隐藏显示,不会影响到阅读,而且对接手你代码的人提供一个方便的入手界面。

尽量写注释吧,可能会使类文件变大,可是却方便以后的维护。
当然,如果你发觉你的单个类文件过大,那么,也是开始要重构了…(ω)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-9-27 09:05 | 显示全部楼层
泻药(这个问题能说两句)

工作上的代码,方法及其参数的注释是必须要有的。如果某个方法内的逻辑比较复杂,在关键代码上也会写注释。

注释其实就是源代码和文档的折衷方案,简洁地描述代码如何工作。相比在代码里加入成段的注释,我更喜欢让代码描述自己如何工作,即所谓“流畅接口(fluent interfaces)”。

PS:我只是一个读了两本C#相关书籍的低级码农,题主你邀请我回答的Unity问题,我真心不会啊(哭)!
发表于 2021-9-27 09:09 | 显示全部楼层
注释是代码本身不足以用自然语言说明功能时的产物,理想的情况是“消灭注释”,但正常情况是不可能达到的。
所以我经常说的一句话就是:“你可以这样写,但你这些写就必须写注释”

让那些坚持“翻译式注释”的人去写英文注释是个好办法,这样他们就会发现之前的自己到底有多蠢。
发表于 2021-9-27 09:11 | 显示全部楼层
首先写注释是产生文档和代码提示的需要。
另外写注释并非因为代码混乱,代码简洁清晰也应该给写注释,毕竟看一行文字比看十行代码来了解一段代码的功能要快的多。
如果注释很难写,或许还是代码有问题,需要改进代码。
需要继续研究改进的可以以//TODO  开头写注释。
[怎样做]可以让代码本身去说明。[为什么做]、背景、目的、用途、思路等等可以写到注释里。
发表于 2021-9-27 09:11 | 显示全部楼层
除非特别绕的,否则不写。
发表于 2021-9-27 09:20 | 显示全部楼层
推荐一本“代码整洁之道”
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 12:16 , Processed in 0.102028 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表