笔者刚刚接触unity,跟着B站上的教程学着做了一个小项目,若有不足,请各位大佬多多指教。

1. 创建项目

视频教程网址:
https://www.bilibili.com/video/BV1V4411W787?p=6&spm_id_from=pageDriver


项目预览

素材搜集:Window-general-Assert store
导入后可在assert文件夹中查看

2. 角色移动

  1. 新建文件夹 scripts脚本
  2. 创建脚本文件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;}
}
  1. 将脚本拖给人物

3. tilemap绘制地图

  1. 左侧窗口右键创建 Grid-tilemap
  2. 创建tile文件夹,里面可以放瓦片
  3. 裁剪瓦片 右侧spliteditor
    调整行与列,自动裁剪成n*m
  4. window-2D-tilepalette
    调色板中放入图片来作为地板

4. prefab丰富场景

  1. 将要加入的物体加入到prefab文件夹中,作为模板,方便复制粘贴
  2. 给物体添加刚体与碰撞
    给人物添加刚体(rigid body) 与碰撞(Box colider)
    给物体添加碰撞(Box Colider)
  3. 设置人物重力为零,刚体中gravity设置 (bug 1: 人物不停下降,根本停不下来)
  4. 更改 edit-project Setting-graphics
    调整mode为自定义(custom axis)
    x,y,z 0 1 0
    目的为图层的穿插更真实

4. 解决碰撞与抖动问题

  1. 解决碰撞旋转 (bug 2:爱的魔力转圈圈)
    人物-刚体-freeze rotation z
  2. 解决抖动问题: (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: 两者不兼容)**

采集道具:

  1. 图片调整合适大小拖入map,添加碰撞,打开触发器。
  2. 编辑脚本
    在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);//拾取草莓后摧毁草莓}}}

受到伤害

  1. 创建脚本,类似于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,可实现持续收到伤害
  1. 在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函数
  1. 实现人物站在陷阱里也能收到伤害
    人物刚体选择neverawake

  2. 伤害区域的扩充
    选中伤害图片-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);}}
}

添加动画(难点!!!)

物品动画

  1. 选中需要添加动画的物体, 点击windows-animation 新建一个动画 新建在item文件夹下创建
  2. add Property – scale 控制缩放 在每一帧设置不同的大小
  3. 另外所有要加动画的物体点击修改过的物体 prefebs-apply all

敌人动画

  1. 选中预支动作图片,将其批量选中walkdown拖动到robot下,会打开资源管理器,选择新建enemy文件夹存放,保存为walkdown.anim 。
  2. 分别如此创建向上下左右的动画,特例右和左是对称的,所以在向右animation中 add property – sprite renderer.FlipX,在x轴上旋转。
    之后再添加fixed动画
  3. 动画的应用,创建混合树,在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
  4. 修改动画代码:
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);}}
}

人物动画

  1. 人物组件添加animator,添加控制 Ruby(官方自带,也可以用Blend tree自行完成)
  2. 修改代码:
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);}
}

添加子弹

  1. 将子弹拖入场景,加上刚体与碰撞,重力设为零,不加z旋转,不勾选 isTrigger

  2. 添加脚本 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);}
}
  1. 修改图层与碰撞
    右上角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);}}

添加特效:可以自学粒子相关

烟雾特效

  1. 右键左侧物品栏,新建特效particle System

https://www.bilibili.com/video/BV1V4411W787?p=15

人物血条

  1. 添加ui

右侧列表-右键新建ui-image
将要添加的图片加进去
调整缩放模式convas-scale with screen size

调整血条:filed, horizontal

  1. 编辑ui事件,在血量变化同时ui界面血量条随即变化

npc对话框,相应事件

子弹数量ui

链接如下,需要补充。
B站教程

本项目github网址

感谢大家阅读!!!

Unity 2D -- Ruby Adventure 学习笔记相关推荐

  1. Unity材质球个人学习笔记

    Unity材质球个人学习笔记 Shader FX: Lighting and glass effects.( 灯光.玻璃) GUI and UI: For user interface graphic ...

  2. Unity 项目 - Ruby‘s Adventure 学习笔记

    Ruby's Adventure 初识 Unity 主角 Ruby 的创建 Ruby 的移动控制 使用 TileMap 创建世界地形 调色板的工具与快捷键 丰富游戏世界 Unity 中的物理系统 道具 ...

  3. SiKi学院 Unity中常用api学习笔记(001-014)

    Api 应用程序编程接口 前言 笔记是看siki学院中<Unity中常用api>的学习笔记 课程地址:  http://www.sikiedu.com/my/course/59 强烈推荐大 ...

  4. SiKi学院 Unity中常用api学习笔记(015-019)

    Api 应用程序编程接口 前言 笔记是看siki学院中<Unity中常用api>的学习笔记 课程地址:  http://www.sikiedu.com/my/course/59 强烈推荐大 ...

  5. Ruby‘s Adventure 学习笔记—— 场景搭建

    1.2D场景地板布置中Tilemap应用 图片转自:https://www.cnblogs.com/sweetXiaoma/p/9342121.html Tilemap(瓦片地图)是tile(一种特殊 ...

  6. 基于傅老师unity游戏教学的学习笔记(EX)将PMX格式的MMD模型导入unity并使用

    为了学习unity,开始游戏制作大业,我选择在bilibili上寻找unity游戏教学视频并边做边学,以此系列博客作为笔记. (EX)将PMX格式的MMD模型导入unity并使用 想做3D游戏,优秀的 ...

  7. Unity官方图形教程 学习笔记(二) -- Precomputed Realtime GI(实时全局光照)

    原文链接:https://unity3d.com/cn/learn/tutorials/s/graphics 1 介绍 当使用Baked GI的时候,会在预计算阶段,离线创建一张lightmap纹理贴 ...

  8. 《Ruby》学习笔记

    前言 笨办法学Rubyearnrubythehardway.org 进入下面这些网站bitbucket.org.github.com.gitorious.org.launchpad.net.sourc ...

  9. Ruby编程语言学习笔记4

    对应Ruby编程语言第五章 #Ruby使用换行符.分号.then关键字 对条件表达式(expression)和后续内容(code)进行分割 #if条件式 =begin if expression    ...

最新文章

  1. Python用selenium获取Cookie并用于登录。
  2. 如何调用华为云api_postman调用华为云接口添加资源
  3. android studio 连不上设备,Android Studio-设备已连接但“脱机”
  4. 决胜大数据时代:HadoopYarnSpark企业级最佳实践(3天)
  5. 大津阈值分割matlab实验,OTSU(大津法)分割源程序(MATLAB版)
  6. 单线多拨插件安装_Rhino 中的 SU 插件 | Jamparc for Rhino 6
  7. AI开发者顶会,这一次,人人都可以参加!
  8. python与html5_python前端HTML和CSS入门
  9. 巅峰之证!首位阿里云ACE认证专家产生
  10. hbase+phoenix开发预演小例子
  11. html基础学习笔记
  12. 使用pydicom实现Dicom文件读取与CT图像窗宽窗位调整
  13. 这几个excel神操作,让你从入门到大神 ,涨完工资再来谢我……
  14. BIM模型文件下载——某加油站服务区Revit模型
  15. Python命名空间和作用域窥探
  16. 汽车整体解剖VR教学软件QY-JP001
  17. uniApp消息推送(极光/阿里云)
  18. OpenStack最新版本:Ussuri发布亮点
  19. 甘蔗歉收糖价大涨,游资热捧白糖期货
  20. 生化实验技术——酵母双杂交

热门文章

  1. RabbitMQ GUI客户端工具(RabbitMQ Assistant)
  2. 基于51单片机实现秒表_☆往事随風☆的博客
  3. 信息共享交换体系在政务服务中的应用研究
  4. 快速排序 (挖坑法)+partion函数的应用
  5. 辞职后三个月才能走是不是违法的
  6. 什么样的场景看不到反而更精彩?_数字体验_新浪博客
  7. java流程引擎实现_手写实现一套流程编排
  8. matlab使用LAN网口TCP/IP通信对大华可编程电源控制
  9. java 数据立方_写一个Java应用程序,从键盘输入一个整数,然后输出它的平方值立方值...
  10. 我是如何一步步编码完成万仓网ERP系统的(三)登录