编辑器操作
- 放大恢复窗口 shift + space 
- 窗口布局:window - layout 进行选择,恢复默认选择: default 
- w q e r t y u w - 调整方向 transform - reset 还原 
- - sorting layer调整画面图层的显示序列。可以认为是把图层分类。 
- sorting layer越在下面,越在前面order layer 数字越大越在前2dobject - sprite 
- c#代码编辑器设置:unity edit - preferences - external tools 把script editor 默认的 open by file extention 改成 visual stdio2019 
- 会在unity编辑器的左下角看到输出在玩游戏时修改参数时,要在齿轮里点 copyComponent 
- 设置Layer层- 菜单: - Edit / Settings / Tags and Layers / Layers - 设置Tags- 菜单: - Edit / Settings / Tags and Layers / Tags 
素材
素材资源下载
去在线素材商店选素材,学习的话可以先选择一些免费的素材,然后点「添加至我的资源」。
在unity editor里,找到菜单:Window - Package Manager - 下拉列表切换到My Assets,刷新就能出来选择的资源了,下载到本地即可使用。
资源处理
图片的Pixel Per Unit默认是100像素,如果图片的像素不高的话,可以设置一个较小的值,例如16。
切图
如果是多图资源拼合而成,需要切图,切图有自动切图和手动切图。
sprite editor sprite mode -multiple //Slice- autoslice - slice Slice - grid by cell size 16,16 apply
预制体prefab
创建一个Perfabs防止重复利用 object
动画
使用序列帧创建动画
动画状态切换
- 添加站立动画Idle,跑动动画Run。
- 了解 Animator 和 Animation 的使用。
- 在 C# 脚本里调用动画效果。
- 跳跃和下落的动画转换
- LayerMask的使用方法
添加文件夹 Assets - Animation - Player create AnimationController window - Animation - Animation 打开动画面板 Smaples 设置动画速率
window - Animation - Animator parameters 设置变化参数
修改变化箭头 去掉 Has Exit Time Transition Duration 设置成 0
将Player Animation 加到 Player 编辑变化代码 public Animator anim; anim.SetFloat(running, Mathf.Abs(facedirection));
UGUI
canvas
切换成camera,然后把主camera拖进来。
控件响应鼠标
鼠标滑过放大效果
TileMap
创建TileMap
create - 2dobject - tilemap
Unity之Tilemap - boynextdoor♂ - 博客园
还需要创建一个调色板,可以理解为用来「贴瓷砖」的画笔。
window - 2d - tile palette
tilemap画的地图有缝隙要怎么解决?
选择grid 在右边的inspector窗口里 把Grid的Grid Size X和Y都改成0.99
Tilemap Collider 2D
*正确的解决移动卡顿问题应该在Tilemap上添加 Composite Collider2D 组件,勾选 Tilemap Collider2D 组件中的 Use Composite,将自动添加上的 Rigidbody2D 组件的 Body Mode 改为 Static
Tilemap加碰撞体
- 添加Tilemap Collider 2D组件
- 如果想要将所有的碰撞体组合成一个,再添加Composite Collider 2D组件,但是这样会自动给物体添加刚体,把Body Type变为static物体就不会因重力影响而下落。并在Tilemap Collider 2D中选中Used by composite.
动态创建Tile
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class MapEditor : MonoBehaviour
{
    public Tilemap tilemap;//引用的Tilemap,加入脚本后需要将对应tilemap拖进来
    private Dictionary<string, Tile> arrTiles; //地块种类
    private List<string> TilesName;
    string[] TileType;
    //大地图宽高
    public int levelW = 10;
    public int levelH = 10;
    // Start is called before the first frame update
    void Start()
    {
        arrTiles = new Dictionary<string, Tile>();
        TilesName = new List<string>();
        InitTile();
        InitMapTilesInfo();
        InitData();
    }
    // Update is called once per frame
    void Update()
    {
    }
    void InitData()
    {
        for (int i = 0; i < levelH; i++)
        {//根据地面类型TileType初始化tilemap
            for (int j = 0; j < levelW; j++)
            {
                tilemap.SetTile(new Vector3Int(j, i, 0), arrTiles[TileType[i * levelW + j]]);
            }
        }
    }
    void InitMapTilesInfo()
    {
    	//初始化地图信息,即每个单位对应的地面类型
        TileType = new string[levelH * levelW];
        for (int i = 0; i < levelH; i++)
        {
            for (int j = 0; j < levelW; j++)
            {
                TileType[i*levelW+j] = TilesName[Random.Range(0, TilesName.Count)];
            }
        }
    }
    void InitTile()
    {
        //创建3钟类型的地面瓦片
        AddTile("soil", "Image/soil");
        AddTile("brick", "Image/brick");
        AddTile("grass", "Image/grass");
        
    }
    void AddTile(string labelName,string spritePath)
    {
        Tile tile = ScriptableObject.CreateInstance<Tile>();//创建Tile,注意,要使用这种方式
        Sprite tmp = Resources.Load<Sprite>(spritePath);
        tile.sprite = tmp;
        arrTiles.Add(labelName, tile);
        TilesName.Add(labelName);
        
    }
}
Tile[] arrTiles;//生成的Tile数组
arrTiles = new Tile[colorCount];
for(int i=0;i<colorCount;i++){
    arrTiles[i] = ScriptableObject.CreateInstance<Tile>();//创建Tile,注意,要使用这种方式
    arrTiles[i].sprite = baseTile.sprite;
    arrTiles[i].color = new Color(Random.Range(0f, 1f), Random.Range(0f,1f), Random.Range(0f, 1f), 1);
}
for(int i=0;i<levelH;i++){//这里就是设置每个Tile的信息了
    for(int j=0;j<levelW;j++){
        tilemap.SetTile(new Vector3Int(j, i, 0), arrTiles[Random.Range(0, arrTiles.Length)]);
    }
    yield return null;
}
将鼠标坐标转成世界坐标,注意要z轴
 Vector3 wordPosition  =  Camera.main.ScreenToWorldPoint(mousePosition);
然后调用Tilemap的 WorldToCell 函数,就可以拿到一个地图中的坐标
 Vector3Int cellPosition 
 = 
 backMap.
 WorldToCell(
 wordPosition);
最后就直接设置Tile了
 backMap.
 SetTile(
 cellPosition, 
 gameUI.
 GetSelectColor().
 colorData.
 mTile);
实现当tilemap里面的格子与其他的对象发生碰撞后,消除碰撞的那个格子
//tilemap就是发生碰撞的tilemap对象
void OnCollisionEnter2D(Collision2D collision)
    {
        Vector3 hitPosition = Vector3.zero;
        if (tilemap != null && tilemapGameObject == collision.gameObject)
        {
            foreach (ContactPoint2D hit in collision.contacts)
            {
                hitPosition.x = hit.point.x - 0.01f * hit.normal.x;
                hitPosition.y = hit.point.y - 0.01f * hit.normal.y;
                tilemap.SetTile(tilemap.WorldToCell(hitPosition), null);
            }
        }
    }
要从图块贴图的矩形区域获取包含所有图块的数组,请使用tilemap.GetTilesBlock(BoundsInt bounds)。您将获得一维拼贴块,因此您需要自己知道下一排拼贴块何时开始。任何空单元格都将用一个null值表示。
如果需要所有图块,请使用tilemap.cellBounds。这将为您提供一个BoundsInt覆盖tilemap完整使用区域的对象。这是一个示例脚本,该脚本从同一个游戏对象上的Tilemap中获取所有图块,并列出其图块及其坐标:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class TileTest : MonoBehaviour {
    void Start() {
        Tilemap tilemap = GetComponent<Tilemap>();
        BoundsInt bounds = tilemap.cellBounds;
        TileBase[] allTiles = tilemap.GetTilesBlock(bounds);
        for (int x = 0; x < bounds.size.x; x++) {
            for (int y = 0; y < bounds.size.y; y++) {
                TileBase tile = allTiles[x + y * bounds.size.x];
                if (tile != null) {
                    Debug.Log("x:" + x + " y:" + y + " tile:" + tile.name);
                } else {
                    Debug.Log("x:" + x + " y:" + y + " tile: (null)");
                }
            }
        }
    }
}
这是另一种方法 .cellBounds.allPositionsWithin
public Tilemap tilemap;
public List<Vector3> tileWorldLocations;
// Use this for initialization
void Start () {
    tileWorldLocations = new List<Vector3>();
    foreach (var pos in tilemap.cellBounds.allPositionsWithin)
    {   
        Vector3Int localPlace = new Vector3Int(pos.x, pos.y, pos.z);
        Vector3 place = tilemap.CellToWorld(localPlace);
        if (tilemap.HasTile(localPlace))
        {
            tileWorldLocations.Add(place);
        }
    }
    print(tileWorldLocations);
}
Change Unity Tilemap’s Tile sprite during runtime
高亮
 //This line outside the Update 
  TileBase highlightTile = gravelTile;
  
  
  void Update() { 
        
      Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
      Vector3Int tileCoordinate = highlightMap.WorldToCell(mouseWorldPos);
  
      if(tileCoordinate != previousTileCoordinate ){
          highlightMap.SetTile(previousTileCoordinate, null);
          highlightMap.SetTile(tileCoordinate,highlightTile);
          previousTileCoordinate = tileCoordinate;     
      }
  }
Physics2D
刚体
禁止物体旋转:Rigidbody 2D–Constraints–Freeze Position Z打钩
Collider
输入
edit - projectsetting - input Horizontial 横向
add Component new script
Assets - Script - 放代码 script文件还要手动拖到对应Sprite里
移动时会触发Update() 函数 public Rigidbody2D rb; //定义刚体,手动在图形编辑器里拖进去 Input.GetAxis(Horizontal);// 获取横轴变更 rb.velocity = new Vector2(horizontalMove * speed, rb.velocity.y); //设置对象位置
将刚体 Constrants 里的 z 勾选,让它不会飞起来
scale 控制方向 float facedirection = Input.GetAxisRaw(Horizontal); //直接获得 -1,0,1 获取整数 transform.localScale = new Vector3(facedirection, 1, 1);// 设置方向
保证不同帧率正常 Update 函数改为 FixedUpdate() 函数 rb.velocity = new Vector2(horizontalMove * speed * Time.deltaTime, rb.velocity.y); //速度乘以一个时间参数
跳跃 Input.GetButtonDown(Jump) // 获取跳跃按键 rb.velocity = new Vector2(rb.velocity.x, jumpforce * Time.deltaTime); //改变y轴方向 Rigidbody2D 中的GravityScale 参数同样可以调整跳跃力度
拾取效果 在 PlayerController void OnTriggerEnter2D(Collider2D collision) 方法里
镜头
- 镜头跟踪。 - 初步了解Cinemachine。
添加CameraController控制镜头
2.填加Cinemachine控制镜头 添加插件 window-PackageManager-Cinemachine 对背景添加 Polygon Colider2d 勾选isTriger Cinemachine Confiner 填入 Polygon
Lens- Orthographic Size 镜头大小
代码片段
通过名字找物体
GameObject.Find("Player")
通过名字寻找物体子集
transform.FindChild("物体子集名字")
显示和隐藏物体
gameObject.SetActive(true);  
使用和关闭物体代码
gameObject.GetComponent<代码名字>().enable=true;
按下动画事件 if (Input.GetMouseButton(0))
按下事件   if (Input.GetMouseButtonDown(0))
抬起事件   if (Input.GetMouseButtonUp(0))
销毁一样标签的物体
GameObject [] objs = GameObject.FindGameObjectsWithTag("标签名");
foreach(GameObject obj in objs){
       Destroy(obj);
}
物体水平匀速移动
transform.Translate(-0.1f*Time.deltaTime,0,0);
位置相关的: 5个和位置相关的Vector3类型变量 up 表示世界坐标的Y轴方向 right 表示世界坐标的X轴方向 forward 表示世界坐标的Z轴方向 position 表示对象在世界坐标系中的位置 localPosition 表示对象相对父节点变换的坐标位置
改变物体颜色
obj.renderer.material.color=Color.red
父子节点相关的: parent 变量表示Transform的父节点 Transform Find(string name) 根据名字查找子节点 bool IsChildOf(Transform node) 判断该Transform是否某Transform的子节点 void DetachChildren() 解除所有子节点的父子关系
鼠标:
Input.mousePosition表示鼠标当前的像素位置(坐标系如何?以左下角为原点)
接下来这三个函数的参数,0左键,1右键,2中键
GetMouseButton 对应的键处于按下状态时返回true
GetMouseButtonDown 对应的键被按下时返回true
GetMouseButtonUp 对应的键弹起时返回true
OnMouseDown 当鼠标点击到对象的时候回调
OnMouseDrag 当鼠标拖拽对象时调用,在Ignore Raycast层上无效
OnMouseEnter 当鼠标进入对象时调用
OnMouseExit 当鼠标离开对象时调用
OnMouseOver 当鼠标停留在对象上面时调用
OnMouseUpAsButton 鼠标在同一个对象上按下,并弹起时调用
OnMouseUp 跟楼上一样
gameObject.transform.rotation = new Quaternion (Player.transform.rotation.x, Player.transform.rotation.y, Player.transform.rotation.z, Player.transform.rotation.w);
gameObject和Player旋转角度一样!
俩个物体之间的距离 float Distance
float Distance = Vector3.Destance(position1,position2);
如果玩家和敌人的距离小于10,执行{}代码
if( Vector3.Destance(敌人.position,玩家.position)<10f){
     //  执行相应代码
}
18.Animation动画
01.倒回播放 Animation.Rewind();
02.停止所有动画 Animation.Stop();
停止动画 Animation.Stop(“动画名字”);
03.使用动画循环模式 Animation.WropMode= WropMode.loop;
04.等待动画播放完成 animation.Play();     yiel WaitForSeconds (animation.Clip.Length);
05.打印动画长度 print(animation["动画名字"].Length);
参考
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/program/unity%E6%B1%87%E6%80%BB.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)