找回元素

找回元素开发实践经验

一、问题

1. 在位置需求严格的场景中,角色被Collider的边角卡住

  • 主要解决方案:在Project Settings - Physics 2D - Default Contact Offset中更改为更小的接触偏移量。默认为0.01,如果位置精度要求0.1则会卡住

  • 其他的解决办法(无益于本项目但理论可行)

    • Sprite Editor中设置缩小Collider边界几个像素的位置

    • 如果在位移过程中发生了偏移,使用Rigidbodyconstraints

      1
      2
      3
      4
      5
      6
      void Move(GameObject go, Vector2 dir)
      {
      go.GetComponent<Rigidbody2D>().constraints = dir.x == 0f ? RigidbodyConstraints2D.FreezePositionX : RigidbodyConstraints2D.FreezePositionY;
      go.GetComponent<Rigidbody2D>().freezeRotation = true;
      go.GetComponent<Rigidbody2D>().velocity = dir * 10;
      }

二、组件使用

1. InputSystem

  • Vector2dpadVector2dpad输入按一下响应两下,因此使用Buttondpad输入代替

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private void MoveDpadInputAction(InputAction.CallbackContext context)
    {
    switch (context.control.name)
    {
    case "up": inputVector2 = Vector2.up; break;
    case "down": inputVector2 = Vector2.down; break;
    case "left": inputVector2 = Vector2.left; break;
    case "right": inputVector2 = Vector2.right; break;
    }
    print(inputVector2);
    }

2. Tilemap

  • TilemapGameObject的选择:

    • 前者不提倡代码动态更改,尽量在编辑器中画好就不再更改,一些静态地图、固定画面使用;后者可以随意动态更改。
    • 因此使用前者画外部的墙壁,动态画内部的障碍物,以及障碍物的显隐;使用后者处理所有可操作的、频繁变动位置的内容。
  • 动态画tiles的相关方法(Tilemap tm = GetComponent<Tilemap>();

    • tm.SetTile(Vector3Int position, TileBase tile):设置单个tile

    • tm.SetTiles(Vector3Int[] positionArray, TileBase[] tileArray):设置多个tiles,每一个位置对应一个数组值

    • tm.SetTilesBlock(BoundsInt position, TileBase[] tileArray):批量设置tiles

      • BoundsInt:立方体包围盒。实例化需要参数(int 最小x, int 最小y, int 最小z, int x的长度, int y的长度, int z的长度)(Vector3Int 最小xyz的位置, Vector3Int xyz的长度)

      • TileBase[]需要对应数量长度的数组,需要一一赋值。

      • z的长度1时为一个平面,画瓦片的顺序为从左下到右上逐行进行(第一行为最小y的所有x)

      • 区域批量设置

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        int xmin,ymin,zmin=0,xsize,ysize,zsize=1; //获得所需区域的6个参数
        TileBase[] contentsTiles; //加载区域需要的所有瓦片
        BoundsInt bi = new BoundsInt(xmin, ymin, zmin, xsize, ysize, zsize); //设置区域变量
        TileBase[] tiles = new TileBase[xsize * ysize * zsize]; //设置整个数组, 建议直接写结果避免运算
        //给tiles逐一赋值
        for (byte i = 0; i < tiles.Length; i++)
        {
        tiles[i] = contentsTiles[i]; //为数组赋值,可加入其他条件和逻辑
        }
        //批量画瓦片函数
        tilemap.SetTilesBlock(bi, tiles);
      • i(0~xsize*ysize-1)个TileBase的位置:(i % xsize + xmin, i / xsize + ymin, 平面z)

三、快速实现

1. 保留n位小数

1
2
3
4
5
6
7
8
9
10
11
//保留1位小数
float PointOne(float f)
{
return Mathf.Round(f * 10f) / 10f;
}

//保留2位小数
float PointOne(float f)
{
return Mathf.Round(f * 100f) / 100f;
}