|
内容来自这个视频:(很早以前看了一些,基本上忘完了,当时做了一些笔记。可能有空完善一下)
这个感觉挺有用的:
ep03 地图绘制
图片切割为瓦片:
Sprite Mode: Muitiple(这一步可用 Shift 批量设置)
– Sprite Editor – Apply
– Slice
– Type: Grid By Cell Count, Column & Row: 3*3 – Slice – Apply
使用瓦片:
Window – 2D – Tile Palette(调色板) – Create New Palette (放到Asset/Tiles文件夹下)– 原图片拖到Palette(放到Asset/Tiles文件夹下)(创建好了调色板)
调色板中的瓦片拖入场景 – 一个瓦片不能占满一个格子 – 原图片属性 – Pixeis Per Unit(每单元像素数) - 默认是100,即每个格子是100个像素,原图片为192*192,,切割为3*3后变为64*64的瓦片,所以将Pixeis Per Unit设为64,这样一个瓦片就占满一个格子。(其他图片也要设为64)
预制体 prefab:将物体拖到 Project 栏目即可创建 prefab,成为一个可以多次使用的模板。(这里在 Project 中创建了 Frefabs文件夹,拖到了该文件夹中)。
2.5D实现
Edit – Project Settings – Graphics – Camera Settings, Transparency Sort Mode : Custom Axis(自定义), Transparency Sort Axis(同一层级排序): X=0, Y=1, Z=0; - Crtl+S。– 将人物和物体设为同一层级,即 Order in Layer 相同。
【每个物体的厚度不一样怎么办?】【为什么草和电线杆可以遮住人物,房子和树只有y更高时才能遮住?】
【能不能设为人物的碰撞体y值超过碰撞体的y值时人物被遮住?】
【更好的方法!没看懂。。。】
ep05 人物碰撞物体
人物碰撞物体时抖动:在人物和物体上添加 Components – Rigid Body 2D,物理运动会抖动,改为刚体运动不会抖动。移动脚本中的transform改为Rigidbody 2D组件rbody:
//==========移动Rigidbody 2D组件rbody=====================================
Vector2 position = rbody.position;
position.x += moveX * speed * Time.fixedDeltaTime;
position.y += moveY * speed * Time.fixedDeltaTime;
rbody.MovePosition(position);
人物碰撞物体时旋转:因为不同角度受力不同,所以会旋转。禁用Z轴旋转即可:Rigid Body 2D – Constraints: Freeze Rotation Z 打勾 – Crtl+S
ep06 相机跟随
Window – Package Manager – Cinemachine – Create 2D Camera – 把Hierarchy层级中的人物拖到Follow中【如何自己写脚本实现?】 - Lens – 正交尺寸:5(大小合适)
相机不超出地图:
对2D Camera:Add Extension – CinemachineConfiner;
Create Empty(命名CameraConfiner):Add Component Polygon Collider 2D(多边形碰撞体),可以拖动点编辑碰撞器,也可以设置点的个数和位置:Points点 – Element0 – Size(点个数)、每个点X-Y坐标。
2D Camera的CinemachineConfiner:将CameraConfiner拖入Bounding Shape 2D(Must be a PolygonCollider2D or CompositeCollider2D)(此时角色被碰撞体挤出地图);CameraConfiner - Polygon Collider 2D – is Trigger(是触发器,只触发,不会挤出)【触发器是什么?大概明白了】
ep07 采集草莓(生命道具)
文件夹中的草莓
- 设置大小:Pixels Per Unit
- 添加碰撞体:Box Collider 2D - is Trigger(“是触发器”,表示可穿过的碰撞)
- 脚本(放在Script文件夹):
- - - - - - - - - - Collectible.cs - - - - - - - - - -
/// <summary>
/// 碰撞检测
/// </summary>
/// <param name=&#34;other&#34;></param>
void OnTriggerEnter2D(Collider2D other)//OnTriggerEnter:另一个物体刚碰撞该物体时发生的事
{
PlayerController pc = other.GetComponent<PlayerController>();//检测other上有没有PlayerController脚本
if (pc != null)//有的话
{
if (pc.MyCurrentHealth < pc.MyMaxHealth)
{
pc.ChangeHealth(10); //生命值+10
Debug.Log(&#34;拾取草莓&#34;); //打印
Destroy(this.gameObject); //草莓消失
}
}
}
- - - - - - - - - - PlayerController.cs - - - - - - - - - -
private int maxHleath = 100; //最大生命值
private int currentHealth; //当前生命值
public int MyMaxHealth //属性,读取maxHealth
{
get
{
return maxHleath;
}
}
public int MyCurrentHealth
{
get
{
return currentHealth;
}
}
public void ChangeHealth(int amount)
{
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHleath);
//生命值约束在0和currentHealth之间
}
草莓动画:
点击草莓 – Window – Animation(或Ctrl+6) - Create创建 - (我放在Assets/Art/ Animations/AnimationClips/Items,命名Idle) - 添加属性 – Transform – Scale,展开可以设置xyz
点时间轴添加帧:(在关键帧处设置xyz比例,即可让草莓随时间改变大小)
受到陷阱伤害:
陷阱扩大:Draw Model绘制模式:Tiled平铺,按T缩放(Rect Tool矩形工具) – 报错:Sprite Tiling可能无法正确显示 – Environment文件夹中原图片 – Mesh Type网格类型:Full Rect全矩形
敌人:Rigidbody2D,BoxCollider2D
private void OnCollisionEnter2D(Collision2D other)//刚体检测(两个都有刚体)
{
PlayerController pc = other.gameObject.GetComponent<PlayerController>();
if (pc != null)
{
pc.ChangeHealth(-3);
}
}
【Collision2D和Collider2D有什么区别?】
【敌人会被推走怎么办?】
敌人动画:点击敌人,Ctrl+6,把一组图片拖进动画,翻转:添加属性,Sprite Renderer,Flip X
显示帧数:Show Sample Rate
动画切换:点击敌人,拖入anim文件,进入动画器【按住滚轮移动】,右键 - Create State – From New Blend Tree,双击,改名为Walk,Blende Type:2D Simple Directional,+号 – Add Motion Field,拖入四个方向走路的anim文件,
Base Layer,Walk – 右键 – 设置为默认图层状态
动画器 – 参数 – 创建Trigger,Walk混合树 – 创建过渡
过渡:Conditions – Fixed参数,Has Exit Time、Fixed Duration不勾。
Fixed触发器参数触发时,会切换到Fixed状态
EnemyController脚本【记得脚本应用到预制件,和isVertical的设置】:
用private Vector2 moveDirection进行动画设置
private Animator anim; //获取动画组件
anim = GetComponent<Animator>(); //获取动画组件
anim.SetFloat(&#34;Move X&#34;, moveDirection.x); //给动画器中的参数赋值
anim.SetFloat(&#34;Move Y&#34;, moveDirection.y);
ep12 Ruby的动画
给Ruby添加Animator组件,Controller选择已经制作好的“Ruby”,点开如下:
Idle是一个Blender Tree:将Look X和Look Y参数赋值给Pos X和Pos Y,Pos X和Pos Y为一定数值时调用面对不同方向休息的图片
Hit也有不同状态:
过渡的设置:
Conditions – If Speed is greater than 0.1, 则从Idle变为Moving
Moving的Blender Tree:
在代码里使用Animator中创建的参数:
Update函数:
private Vector2 lookDirection = new Vector2(1, 0); //玩家朝向,默认向右
Vector2 moveVector = new Vector2(moveX, moveY); //移动方向
if(moveVector.x!=0 || moveVector.y != 0) //移动方向不为0时,即在移动时
{
lookDirection = moveVector; //Ruby朝向与移动方向相同
}
Animator anim; //获取Animator组件
Start函数:
anim = GetComponent<Animator>(); //获取Animator组件
Update函数:
anim.SetFloat(&#34;Look X&#34;, lookDirection.x); //给Animator中的参数赋值
//Look X = lookDirection.x = moveVector.x = moveX = Input.GetAxisRaw(&#34;Horizontal&#34;) = 0、1、-1
//Look X和Look Y为0、1、-1,在Blender Tree中,会根据Look X和Look Y的不同值,播放不同的动画
anim.SetFloat(&#34;Look Y&#34;, lookDirection.y);
此时的效果:Ruby移动时有不同朝向。lookDirection随moveDirection而改变
anim.SetFloat(&#34;Speed&#34;, moveVector.magnitude); //Returns the length of this vector (Read Only).
//public float magnitude { get; }
此时的效果:Ruby可以朝四个方向跑动
移动修改:
//position.x += moveX * speed * Time.fixedDeltaTime;
//position.y += moveY * speed * Time.fixedDeltaTime;
//改为:
position += moveVector * speed * Time.deltaTime;
ep13 Ruby的攻击:发射齿轮修复机器人
Ruby部分:
//============ 按下Space键发射齿轮 ===================
if (Input.GetKeyDown(KeyCode.Space)) {
anim.SetTrigger(&#34;Launch&#34;); //播放动画
GameObject bullet = Instantiate( bulletPrefab, rbody.position + Vector2.up * 0.5f, Quaternion.identity); //创建GameObject,默认方向;初始位置是Ruby脚下+ Vector2.up * 0.5f,从手的位置发出
BulletController bc = bullet.GetComponent<BulletController>(); //(BulletController脚本在后面)
if (bc != null)
{
bc.Move(lookDirection, 300); //子弹方向:玩家方向;速度:300
}
}
子弹部分:
文件Art – Sprites – VFX(Visual Effects) – CogBullet
大小设置(每单元像素数 与图片匹配),添加Rigidbody 2D组件,Box Collider 2D碰撞组件:
---给齿轮Prefab拖入脚本BulletController.cs:
Rigidbody2D rbody; //获取刚体组件
Start函数中:rbody = GetComponent<Rigidbody2D>();
public void Move (Vector2 moveDirection, float moveForce){
rbody.AddForce(moveDirection * moveForce); //对刚体施加力的方向和大小,在PlayerController中调用
}
点击Ruby,把CogBullet预制体拖到脚本里:
此时的效果:按左ShiftRuby脚下会出现齿轮,与Ruby发生碰撞后才会移动
使齿轮与Ruby不碰撞:Ruby – Layer – Add Layer,添加Player和Bullet两个Layer,然后给Ruby和CogBullet选择这两个Layer,
然后设置这两个Layer之间不碰撞,以及Bullet层(子弹之间)不碰撞:
【问题:敌人在Default层,Ruby在Player层,本来发生碰撞;Bullet层与Player层不碰撞,与Default层发生碰撞;但是Default层的敌人与子弹碰撞后,不再与Ruby和子弹发生碰撞。为什么敌人变到Bullet层了?】
此时子弹不会动。将Start()改为Awake(),子弹发射后就会动了。
void Awake() //游戏刚生成时执行
{
rbody = GetComponent<Rigidbody2D>();
}
///碰撞检测,碰到另一个物体后销毁齿轮
void OnCollisionEnter2D(Collision2D other)
{
Destroy(this.gameObject);
}
Awake函数中:Destroy(this.gameObject, 1f); //无论是否碰撞,1s后消失【为什么1秒钟那么长?】
【问题:刚开始Ruby没有动的时候,发射子弹不会动,Ruby动了之后发射子弹才会动】
【关于Awake和Start】下面再来看看Unity圣典中的解释。
Awake():
当一个脚本实例被载入时Awake被调用。
Awake用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如 GameObject.FindWithTag 这样的函数搜索它们。每个游戏物体上的Awke以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息。Awake总是在Start之前被调用。它不能用来执行协同程序。
Start():
Start仅在Update函数第一次被调用前调用。Start在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。
你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。 敌人被齿轮修复:
private bool isFixed; //是否被修复
Start函数中:isFixed = false;
public void Fixed()
{
isFixed = true;
rbody.simulated = false; //禁用物理模拟(对吗?)
anim.SetTrigger(&#34;fix&#34;); //播放被修复时的动画
}
Update函数中:if (isFixed) return;
对 BulletController.cs 的改动:
///碰撞检测,碰到另一个物体后销毁齿轮
void OnCollisionEnter2D(Collision2D other)
{
EnemyController ec = other.gameObject.GetComponent<EnemyController>(); //对方是不是敌人,如果是,身上有没有挂EnemyController脚本
if (ec != null) //是敌人
{
Debug.Log(&#34;子弹碰到敌人&#34;);
ec.Fixed();
}
Destroy(this.gameObject);
}
ep14 简单特效制作1:机器人冒烟特效,吃草莓发光特效
1.切割图片:VFX文件-图片;Sprite Mode精灵模式:Multiple多个;
切割:Sprite Editor精灵编辑:Type类型:Grid By Cell Count;Column & Row:C4 R4 四行四列;Slice切割;
Apply应用。
2.创建特效:Hierarchy面板–右键 – Effects特效 - Particle System粒子系统 - 名字“Broken Effect”。
“Broken Effect”的属性设置:
属性1.Texture Sheet Animation (贴图):Mode:选择Sprites,拖入两张烟雾图片【默认显示第一张】
属性2.Start Frame:选择Random Between Two Constants,0-2 【开始帧:两张图片随机】
材质球(贴图):Assets文件夹下新建“Material材质球”文件夹,文件夹内右键Create,选择Material,命名为“Effect Material”。
Effect Material 的属性:
- Shader:选择Legacy Shaders/Particles/Alpha Blended。
2. Particle Texture:点击Select,随便选一个图片
刚刚的特效 Particle System“Broken Effect”:
- 属性:
- - Renderer渲染器:
- - - Material材质球:选刚刚的材质球“Effect Material”【这样就没有边框了,虽然本来就没有边框2333】
“Broken Effect”基本属性:
1. Duration持续时间
2. Looping是否循环
3. Start LifeTime生成周期
4. Start Speed初始速度:选择Random Between Two Constants,设置初始速度范围
5. Start Size初始大小:选择Random Between Two Constants,设置初始大小范围
6. Start Rotation初始角度:选择Random Between Two Constants,设置初始角度范围
7. Simulation Space所处空间:World(全局,烟在全局飘散,拖动跟随)Local(自身,烟只在固定区域飘散)
8. Stop Action停止动作:Destroy(特效跟随的游戏体消失时,特效也消失)
冒烟的形状:
“Broken Effect”其他属性:
- Shape形状:
- - Shape形状:Cone梯形
- - - Angle角度:10
- - - Radius半径:0
烟上升时逐渐变淡,直至消失:
- “Broken Effect”其他属性:勾选 Color over Lifetime
- 点击白色长条(色块)。上面的两个白色方块剪头:Alpha值(透明度),在中间点击可新建位置,并调整透明度。最后一帧:Alpha调为0【烟冒到最上面会消失】。
将特效做成预制体:从“Hierarchy图层”拖入Prefab文件夹。
烟雾加到敌人(Mr.Clock)身上:
点击机器人,在图层栏中把特效预制体拖到敌人上。
点击敌人身上的烟雾特效,先把 Transform/Position 归零,再按剪头拖动【选择左上角的Move Tool才能拖动】特效,到合适的位置。
保存机器人预制体:点击敌人,Prefab:Overrides推翻/Apply All【记住在哪里Apply All】【这样所有敌人都一样了,包含了特效、特效相对敌人的位置也一样】
被齿轮击中后烟雾消失:
EnemyController.cs:
public ParticleSystem brokenEffect; //冒烟特效
Fixed函数加上:
if (brokenEffect.isPlaying)
{
brokenEffect.Stop(); //fix后,如果烟在冒,则停止
}
并且将“Broken Effect”拖到 Enemy Controller 脚本组件的对应位置:(注意拖入的烟和机器人对应hhhh)
吃草莓发光:【未完成】
新建Particle System:加入材质,更改渲染材料(随便选一张图片)
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|