Unity 采坑知识点整理

 

一:C#知识点

1、数组,矩形数组,锯齿数组

   数组类型是从抽象基类型Array派生的引用类型。继承实现了Ienumerable,可以使用foreach进行只读访问

   矩形数组,多维数组是使用多个索引访问其元素的数组,以二维数组为例

    int[,] arr = { {1,2},{4,5},{7,8} }

    int[,] arr1 = new int[3,2];

    arr1[0,0] = 1;

        arr1[0,1] = 2;

   锯齿数组:该数组中的每个元素都是另外一个数组,每行都有不同的元素个数

        int [][] a = new int[2][];

        a[0] = new int[3];

        a[1] = new int[4];


2、get() 和 set() 方法

      [SerializeField]

       private List _Items = new List();

       public List Items { get { return _Items; } }

好处:便于修改,边界检查之类。协作更方便。对外访问的类必须这样写。对内的可以适当填写。


3、List 降序升序,查找

升序:       

 List<int> test = new List<int>();

        test.Add(1);

        test.Add(3);

        test.Add(2);

        test.Sort((a, b) => a.CompareTo(b));

降序:

        List<int> test = new List<int>();

        test.Add(1);

        test.Add(3);

        test.Add(2);

        test.Sort((a, b) => -a.CompareTo(b));

查找:

    _PreLoadList.Find(p => p.Type == scenePanels[i].Type);


4、Action 和 func用法

 

CoreRoot.eventMgr.TriggerEvent, System.Func>(EventID.SelecteGrid, "", (selectedPos) =>

{

  CoreRoot.eventMgr.TriggerEvent("lightPos", selectedPos);

},

(selectedPos) =>

{

  if( GlobalFunctions.MinSquareDistance(worldPos, selectedPos) == 1 )

     return true;

  else

    return false;

});

1:Action用于没有返回值的方法(参数可以根据自己情况进行传递)

2:Func恰恰相反用于有返回值的方法(同样参数根据自己情况情况)

3:记住无返回就用action,有返回就用Func


5、for遍历并删除,可以采用倒叙

for(int i=itemlist.count-1;i>=0;i--)
{
    itemlist.RemoveAt(i);
}

6、整型和浮点型在 大地图游戏中区别

浮点数在不同CPU上有不确定性,因此一般采用定点数,*100倍之类的方法,例如帧同步上尽量避免浮点数

7、枚举类用法

public enum Type

{

        Idle,

        Walk,

        Run,

}

private Type type;

//获取枚举类的所有枚举类型

var values = Enum.GetValues(typeof(Type));

//获取单个枚举类,打印Walk

var temp = (Enum)values.GetValue(1);    

// Parse:将一个或多个枚举常数的名称或数字值的字符串表示转换成等效的枚举对象。 (MSDN)

Enum key;

 try

{

    key = (Enum) Enum.Parse(typeof(T), names[0]);

 }

 

二、Unity 知识点

1、PNG无损压缩 JPG有损压缩

2、判断组件是否存在

T hitComponent = hit.transform.GetComponent ();

if(hitComponent == null)

3、用基类继承游戏结构的优缺点

优点:增加代码的复用性

缺点:游戏中的世界不是按照真实世界分类,因此继承之间的关系难以一成不变

4、消息体

消息体尽量使用结构体,频繁调用,不产生GC

5、如何管理耗电问题

在五年前这还不是问题。 游戏运行在插到插座上的机器上或者专用的手持设备上。 但是随着智能手机,笔记本以及移动游戏的发展,现在需要关注这个问题了。 画面绚丽,但会耗干三十分钟前充的电,并将手机变成空间加热器的游戏,可不能让人开心。

现在,你需要考虑的不仅仅是让游戏看上去很棒,同时也要尽可能少地使用CPU。 你需要设置一个性能的上限:完成一帧之内所需的工作后,让CPU休眠。

  • 尽可能快地运行:

    这是PC游戏的常态(即使越来越多的人在笔记本上运行游戏)。 游戏循环永远不会显式告诉系统休眠。相反,空闲的循环被划在提升FPS或者图像显示效果上了。

    这会给你最好的游戏体验。 但是,也会尽可能多地使用电量。如果玩家在笔记本电脑上游玩,他们就得到了一个很好的加热器。

  • 固定帧率

    移动游戏更加注意游戏的体验质量,而不是最大化图像画质。 很多这种游戏都会设置最大帧率(通常是30或60FPS)。 如果游戏循环在分配的时间片消耗完之前完成,剩余的时间它会休眠。

    这给了玩家“足够好的”游戏体验,也让电池轻松了一点。

6、获取脚本的反射方法,公有方法,声明方法

//Reflect methods

 var methods = component.GetType().GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic);

7、如何查看一段代码的性能消耗

UnityEngine.Profiling.Profiler.BeginSample("UpdateMesh01");

        //构建网格

        centerPos = m_followTarget.transform.position;

        _mesh.Clear();

        verticeList.Clear();

        trianglesList.Clear();

        Pos = TileManager.instance.GetGridPosition(centerPos);

        UnityEngine.Profiling.Profiler.EndSample();

8、针对Awake start关闭会重新执行问题,通过添加变量解决

static bool bInited = false;

    // 加载所有配置数据

    public static void Init()

    {

        if (bInited)

            return;

        bInited = true;

        ReInit();

    }

9、sprite加载添加cache

GameObject prefabGo = Resources.Load(tileShadowPath);
if (prefabGo != null)
{
    SpriteRenderer spriteRenderer = prefabGo.GetComponent();
    if (spriteRenderer != null)
    {
         Tile shadowTile = ScriptableObject.CreateInstance();
         shadowTile.sprite = spriteRenderer.sprite;
         regionRenderInfo.shadowLayer.SetTile(tilePos, shadowTile);
     }
}

10、Tilemap  里的setTile方法 z坐标不对 也不能正确设置

11、unity 移动

public Transform target;//目标位置
public float distance;//两个物体的距离
void Start () {
    distance = Vector2.Distance (transform.position,target.position);
        }
void Update () {
transform.position = Vector2.MoveTowards (transform.position,target.position,(distance/1f)*Time.deltaTime);
    }//我设置了1秒达到。

所以如果用协程的话,做出两个方式,一下是摘自网络
//在time时间内移动物体
private IEnumerator MoveObject(Vector3 startPos, Vector3 endPos, float time)
{        
        var dur = 0.0f;
        while (dur <= time)
        {
            dur += Time.deltaTime;
            transform.position = Vector3.Lerp(startPos, endPos, dur / time);
            yield return null;
        }
}

//以指定速度speed移动物体
private IEnumerator MoveObject_Speed(Vector3 startPos, Vector3 endPos, float speed)
{
        float startTime = Time.time;
        float length = Vector3.Distance(startPos, endPos);
        float frac = 0;

        while (frac < 1.0f)
        {
            float dist = (Time.time - startTime) * speed;
            frac = dist / length;
            transform.position = Vector3.Lerp(startPos, endPos, frac);
            yield return null;
        }
}

12、打开GIZMOS画线

public void OnDrawGizmos()
{
    if( drawLineTimer > 0 )
    {
         drawLineTimer -= Time.deltaTime;
         Gizmos.DrawLine(drawLineStart, drawLineEnd);
     }
}

13、UGUI判断是否点击在了UI上

if (EventSystem.current.IsPointerOverGameObject())
    return;

 

你可能感兴趣的:(Unity,C#)