编辑器操作
放大恢复窗口 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许可证)