Unity 2D -- Ruby Adventure 学习笔记
笔者刚刚接触unity,跟着B站上的教程学着做了一个小项目,若有不足,请各位大佬多多指教。
1. 创建项目
视频教程网址:
https://www.bilibili.com/video/BV1V4411W787?p=6&spm_id_from=pageDriver
项目预览
素材搜集:Window-general-Assert store
导入后可在assert文件夹中查看
2. 角色移动
- 新建文件夹 scripts脚本
- 创建脚本文件PlayerControl.cs
可能出现的问题:unity没有补全功能
在unity中设置,edit-preference 默认vs再打开
public class PlayerController : MonoBehaviour
{public float speed = 5f;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;Vector2 position = transform.position;position.x += moveX*speed*Time.deltaTime;position.y += moveY * speed * Time.deltaTime;transform.position = position;}
}
- 将脚本拖给人物
3. tilemap绘制地图
- 左侧窗口右键创建 Grid-tilemap
- 创建tile文件夹,里面可以放瓦片
- 裁剪瓦片 右侧spliteditor
调整行与列,自动裁剪成n*m - window-2D-tilepalette
调色板中放入图片来作为地板
4. prefab丰富场景
- 将要加入的物体加入到prefab文件夹中,作为模板,方便复制粘贴
- 给物体添加刚体与碰撞
给人物添加刚体(rigid body) 与碰撞(Box colider)
给物体添加碰撞(Box Colider) - 设置人物重力为零,刚体中gravity设置 (bug 1: 人物不停下降,根本停不下来)
- 更改 edit-project Setting-graphics
调整mode为自定义(custom axis)
x,y,z 0 1 0
目的为图层的穿插更真实
4. 解决碰撞与抖动问题
- 解决碰撞旋转 (bug 2:爱的魔力转圈圈)
人物-刚体-freeze rotation z - 解决抖动问题: (bug 3: 不断抽搐)
public class PlayerController : MonoBehaviour
{public float speed = 5f;Rigidbody2D rBody;//刚体组件// Start is called before the first frame updatevoid Start(){rBody=GetComponent<Rigidbody2D>();}// Update is called once per framevoid Update(){float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;Vector2 position = rBody.position;position.x += moveX*speed*Time.fixedDeltaTime;position.y += moveY * speed * Time.fixedDeltaTime;rBody.MovePosition(position);}
}
修改为刚体的位置,并且使用fixedDeltaTime替换DeltaTime
4.相机跟随
添加相机
import package cinemaMachine
GameObject-cinemaMachine-2dCamera
将人物添加到相机的follow中
地板碰撞
添加tilemapcollider
将除了水面以外 的瓦片 collidertype 都设为none
镜头边界
左侧创建新建空物体,取名为cameraConfirmer
为这个物体添加组件:Polygon Collider
编辑边界
在原相机中extension tools添加camera collider,把自己写的放进去。
confiner中点击istrigger,避免将人物弹出**(bug 4: 两者不兼容)**
采集道具:
- 图片调整合适大小拖入map,添加碰撞,打开触发器。
- 编辑脚本
在playcontroller中添加
public class PlayerController : MonoBehaviour
{public float speed = 5f;private float MaxHealth = 5;private float MinHealth = 0;private float currHealth ;public float getMaxHealth(){return MaxHealth;}public float getMinHealth(){return MinHealth;}public float getCurrHealth(){return currHealth;}Rigidbody2D rBody;//刚体组件// Start is called before the first frame updatevoid Start(){this.currHealth = 2;rBody=GetComponent<Rigidbody2D>();}// Update is called once per framevoid Update(){float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;Vector2 position = rBody.position;position.x += moveX * speed * Time.fixedDeltaTime;position.y += moveY * speed * Time.fixedDeltaTime;rBody.MovePosition(position);}public void changeHealth(float add){currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间}}
新建脚本 collectable.cs
private void OnTriggerEnter2D(Collider2D other){PlayerController player = other.GetComponent<PlayerController>(); if (player != null){Debug.Log("玩家碰到草莓");Debug.Log(player.getCurrHealth() + "/" + 5);if (player.getCurrHealth() < player.getMaxHealth()){player.changeHealth(2);Debug.Log(player.getCurrHealth() + "/" + 5);Destroy(this.gameObject);//拾取草莓后摧毁草莓}}}
受到伤害
- 创建脚本,类似于collectable
private void OnTriggerStay2D(Collider2D other){PlayerController player = other.GetComponent<PlayerController>();if (player != null){Debug.Log("玩家碰到陷阱");Debug.Log(player.getCurrHealth() + "/" + 5);if (player.getCurrHealth() > 0){player.changeHealth(-1);Debug.Log(player.getCurrHealth() + "/" + 5);}}}//注意方法为OnTriggerStay2D,可实现持续收到伤害
- 在Playercontroller中改动实现间隔受到伤害
private float invincibleTimer;private float invincibleTime=2f ;private bool isinvincible=false;//if (isinvincible){invincibleTimer -= Time.deltaTime;if(invincibleTimer < 0)isinvincible=false;//两秒以后取消无敌状态}//在update函数中public void changeHealth(float add){if(add<0){if (isinvincible){return;}isinvincible = true;invincibleTimer = invincibleTime;}currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间}//修改changeHealth函数
实现人物站在陷阱里也能收到伤害
人物刚体选择neverawake伤害区域的扩充
选中伤害图片-drawmode-tiled平铺
添加敌人
1,给敌人加上刚体与碰撞,重力设为0;
2,编辑脚本EnemyController
public class EnemyController : MonoBehaviour
{public float changeDirectionTime = 2f;//改变方向的时间public float changeTimer;//改变方向的计时器public float speed = 3f;public bool isVertical;//是否垂直方向移动Rigidbody2D rbody;private Vector2 moveDirection;//移动方向 // Start is called before the first frame updatevoid Start(){rbody= GetComponent<Rigidbody2D>();moveDirection=isVertical ? Vector2.up : Vector2.right;//如果垂直移动,向上,否则向右changeTimer = changeDirectionTime;}// Update is called once per framevoid Update(){changeTimer -= Time.deltaTime;if (changeTimer < 0){moveDirection *= -1;changeTimer = changeDirectionTime;}//计时器使来回运动Vector2 position=rbody.position;position.x+= moveDirection.x*Time.deltaTime;position.y += moveDirection.y * Time.deltaTime;rbody.MovePosition(position);}/// <summary>/// 与玩家的碰撞检测/// </summary>/// <param name="collision"></param>private void OnCollisionEnter2D(Collision2D collision)//碰撞体检测,不会穿过,要求两刚体之间{PlayerController pc = collision.gameObject.GetComponent<PlayerController>();if (pc != null){pc.changeHealth(-1);}}
}
添加动画(难点!!!)
物品动画
- 选中需要添加动画的物体, 点击windows-animation 新建一个动画 新建在item文件夹下创建
- add Property – scale 控制缩放 在每一帧设置不同的大小
- 另外所有要加动画的物体点击修改过的物体 prefebs-apply all
敌人动画
- 选中预支动作图片,将其批量选中walkdown拖动到robot下,会打开资源管理器,选择新建enemy文件夹存放,保存为walkdown.anim 。
- 分别如此创建向上下左右的动画,特例右和左是对称的,所以在向右animation中 add property – sprite renderer.FlipX,在x轴上旋转。
之后再添加fixed动画 - 动画的应用,创建混合树,在animator界面-右键-create state-new blend tree
blendType:2D Simple
下方加号:add motion field,把上下左右的动作拖入,分别设置positionX,Y的变化(初始化为moveX,moveY)
返回base layer 使entry指向blend tree
左侧参数添加 moveX,moveY 以及trigger型的fixed,利用右键blend tree实现transition的连接,点击这根转换线,将transition的参数设置为trigger型的变量fixed - 修改动画代码:
public class EnemyController : MonoBehaviour
{public float changeDirectionTime = 2f;//改变方向的时间public float changeTimer;//改变方向的计时器public float speed = 3f;public bool isVertical;//是否垂直方向移动Rigidbody2D rbody;private Vector2 moveDirection;//移动方向 // Start is called before the first frame updateprivate Animator animator;void Start(){rbody= GetComponent<Rigidbody2D>();animator= GetComponent<Animator>();moveDirection=isVertical ? Vector2.up : Vector2.right;//如果垂直移动,向上,否则向右changeTimer = changeDirectionTime;}// Update is called once per framevoid Update(){changeTimer -= Time.deltaTime;if (changeTimer < 0){moveDirection *= -1;changeTimer = changeDirectionTime;}//计时器使来回运动Vector2 position=rbody.position;position.x+= moveDirection.x*Time.deltaTime;position.y += moveDirection.y * Time.deltaTime;rbody.MovePosition(position);animator.SetFloat("moveX",moveDirection.x);animator.SetFloat("moveY", moveDirection.y);}/// <summary>/// 与玩家的碰撞检测/// </summary>/// <param name="collision"></param>private void OnCollisionEnter2D(Collision2D collision)//碰撞体检测,不会穿过,要求两刚体之间{PlayerController pc = collision.gameObject.GetComponent<PlayerController>();if (pc != null){pc.changeHealth(-1);}}
}
人物动画
- 人物组件添加animator,添加控制 Ruby(官方自带,也可以用Blend tree自行完成)
- 修改代码:
public class PlayerController : MonoBehaviour
{public float speed = 5f;private float MaxHealth = 5;private float MinHealth = 0;private float currHealth ;private float invincibleTimer;private float invincibleTime=2f ;private bool isinvincible=false;private Animator animator;//动画机private Vector2 lookDirection = new Vector2(1, 0);//初始朝向默认为向右public float getMaxHealth(){return MaxHealth;}public float getMinHealth(){return MinHealth;}public float getCurrHealth(){return currHealth;}Rigidbody2D rBody;//刚体组件// Start is called before the first frame updatevoid Start(){this.currHealth = 2;invincibleTimer = 0;rBody=GetComponent<Rigidbody2D>();animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){float moveX = Input.GetAxisRaw("Horizontal");//control horizon move A:-1 D:1 else: 0float moveY = Input.GetAxisRaw("Vertical");//control vertical move W:1 S:-1 else 0;//获取朝向:Vector2 moveVector= new Vector2(moveX, moveY);if(moveX!=0 || moveY != 0)//至少一个不为零(按下了键盘){lookDirection = moveVector;}animator.SetFloat("Look X",moveVector.x);animator.SetFloat("Look Y", moveVector.y);animator.SetFloat("Speed", moveVector.magnitude);//向量的模//控制移动Vector2 position = rBody.position;//position.x += moveX*speed*Time.fixedDeltaTime;//position.y += moveY * speed * Time.fixedDeltaTime;position += moveVector*speed*Time.deltaTime;rBody.MovePosition(position);//控制无敌时间if (isinvincible){invincibleTimer -= Time.deltaTime;if(invincibleTimer < 0)isinvincible=false;//两秒以后取消无敌状态}}public void changeHealth(float add){if(add<0){if (isinvincible){return;}isinvincible = true;invincibleTimer = invincibleTime;}currHealth=Mathf.Clamp(add+currHealth, 0, MaxHealth);//玩家生命值约束在0与Maxhealth之间Debug.Log("当前生命值" + currHealth);}
}
添加子弹
将子弹拖入场景,加上刚体与碰撞,重力设为零,不加z旋转,不勾选 isTrigger
添加脚本 bulletController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class BulletController : MonoBehaviour
{private Rigidbody2D rb;private void Awake(){rb = GetComponent<Rigidbody2D>();//优先于start}// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}public void Move(Vector2 moveDirection, float moveForce)//发射方法{rb.AddForce(moveDirection*moveForce);}
}
修改图层与碰撞
右上角layer图层添加 player与bullet层
edit-preference-2D physical 修改碰撞:player与bullet之间,bullet与bullet之间禁止碰撞
添加enemy逻辑
public void Fixed(){rbody.simulated = false;//禁用物理模拟animator.SetTrigger("fixed");//播放被修复的动画isfixed = true;}
plyercontroller 添加发射逻辑与动画
if (Input.GetKeyDown(KeyCode.J)){animator.SetTrigger("Launch");GameObject bullet = Instantiate(bulletPrefab, rBody.position+Vector2.up *0.4f ,Quaternion.identity);//默认方向,四元数,参数分别为预制体类别,产生出来的位置,旋转的初始角度BulletController bc=bullet.GetComponent<BulletController>();if (bc != null){bc.Move(lookDirection, 300);}}
添加特效:可以自学粒子相关
烟雾特效
- 右键左侧物品栏,新建特效particle System
https://www.bilibili.com/video/BV1V4411W787?p=15
人物血条
- 添加ui
右侧列表-右键新建ui-image
将要添加的图片加进去
调整缩放模式convas-scale with screen size
调整血条:filed, horizontal
- 编辑ui事件,在血量变化同时ui界面血量条随即变化
npc对话框,相应事件
子弹数量ui
链接如下,需要补充。
B站教程
本项目github网址
感谢大家阅读!!!
Unity 2D -- Ruby Adventure 学习笔记相关推荐
- Unity材质球个人学习笔记
Unity材质球个人学习笔记 Shader FX: Lighting and glass effects.( 灯光.玻璃) GUI and UI: For user interface graphic ...
- Unity 项目 - Ruby‘s Adventure 学习笔记
Ruby's Adventure 初识 Unity 主角 Ruby 的创建 Ruby 的移动控制 使用 TileMap 创建世界地形 调色板的工具与快捷键 丰富游戏世界 Unity 中的物理系统 道具 ...
- SiKi学院 Unity中常用api学习笔记(001-014)
Api 应用程序编程接口 前言 笔记是看siki学院中<Unity中常用api>的学习笔记 课程地址: http://www.sikiedu.com/my/course/59 强烈推荐大 ...
- SiKi学院 Unity中常用api学习笔记(015-019)
Api 应用程序编程接口 前言 笔记是看siki学院中<Unity中常用api>的学习笔记 课程地址: http://www.sikiedu.com/my/course/59 强烈推荐大 ...
- Ruby‘s Adventure 学习笔记—— 场景搭建
1.2D场景地板布置中Tilemap应用 图片转自:https://www.cnblogs.com/sweetXiaoma/p/9342121.html Tilemap(瓦片地图)是tile(一种特殊 ...
- 基于傅老师unity游戏教学的学习笔记(EX)将PMX格式的MMD模型导入unity并使用
为了学习unity,开始游戏制作大业,我选择在bilibili上寻找unity游戏教学视频并边做边学,以此系列博客作为笔记. (EX)将PMX格式的MMD模型导入unity并使用 想做3D游戏,优秀的 ...
- Unity官方图形教程 学习笔记(二) -- Precomputed Realtime GI(实时全局光照)
原文链接:https://unity3d.com/cn/learn/tutorials/s/graphics 1 介绍 当使用Baked GI的时候,会在预计算阶段,离线创建一张lightmap纹理贴 ...
- 《Ruby》学习笔记
前言 笨办法学Rubyearnrubythehardway.org 进入下面这些网站bitbucket.org.github.com.gitorious.org.launchpad.net.sourc ...
- Ruby编程语言学习笔记4
对应Ruby编程语言第五章 #Ruby使用换行符.分号.then关键字 对条件表达式(expression)和后续内容(code)进行分割 #if条件式 =begin if expression ...
最新文章
- Python用selenium获取Cookie并用于登录。
- 如何调用华为云api_postman调用华为云接口添加资源
- android studio 连不上设备,Android Studio-设备已连接但“脱机”
- 决胜大数据时代:HadoopYarnSpark企业级最佳实践(3天)
- 大津阈值分割matlab实验,OTSU(大津法)分割源程序(MATLAB版)
- 单线多拨插件安装_Rhino 中的 SU 插件 | Jamparc for Rhino 6
- AI开发者顶会,这一次,人人都可以参加!
- python与html5_python前端HTML和CSS入门
- 巅峰之证!首位阿里云ACE认证专家产生
- hbase+phoenix开发预演小例子
- html基础学习笔记
- 使用pydicom实现Dicom文件读取与CT图像窗宽窗位调整
- 这几个excel神操作,让你从入门到大神 ,涨完工资再来谢我……
- BIM模型文件下载——某加油站服务区Revit模型
- Python命名空间和作用域窥探
- 汽车整体解剖VR教学软件QY-JP001
- uniApp消息推送(极光/阿里云)
- OpenStack最新版本:Ussuri发布亮点
- 甘蔗歉收糖价大涨,游资热捧白糖期货
- 生化实验技术——酵母双杂交
热门文章
- RabbitMQ GUI客户端工具(RabbitMQ Assistant)
- 基于51单片机实现秒表_☆往事随風☆的博客
- 信息共享交换体系在政务服务中的应用研究
- 快速排序 (挖坑法)+partion函数的应用
- 辞职后三个月才能走是不是违法的
- 什么样的场景看不到反而更精彩?_数字体验_新浪博客
- java流程引擎实现_手写实现一套流程编排
- matlab使用LAN网口TCP/IP通信对大华可编程电源控制
- java 数据立方_写一个Java应用程序,从键盘输入一个整数,然后输出它的平方值立方值...
- 我是如何一步步编码完成万仓网ERP系统的(三)登录