目录

一、敌人的实现

二、受伤效果的实现

三、代码优化及二段跳实现


一、敌人的实现

今天试图将敌人添加进来让游戏变得更有趣

首先按照之前的步骤,使用素材制作三种敌人的动画

这里面需要添加的组件(敌人首先需要是个刚体,然后要加入动画,碰撞体)

这里的一些操作和之前的博客没有什么不同,就不过多赘述了,这里我们要尝试加入人物消灭怪物的效果,这里的思路和收集品的思路是一样的,但是注意,我们这里不能把碰撞体设为触发器,这样会导致怪物直接掉出地图,所以我们这里使用另外一个函数

和之前收集品的思路一样为了让我们的脚本可以识别当前正在碰撞的物品是什么,我们需要添加一个Tag

这样我们就可以在脚本中通过这个Tag实现对物体种类的分辨,但是我们这里发现我们写完代码后会出现一个bug就是我们只要碰到了就会消灭怪物,这不符合我们的想法,我们的思路是踩一下才会消灭,所以我们使用是否处于掉落状态来作为消灭的条件

然后为了实现踩怪跳的效果,可以在销毁的时候加上跳跃的函数

private void OnCollisionEnter2D(Collision2D collision) //消灭怪物
{if(anim.GetBool("falling") && collision.gameObject.tag == "enemy"){Destroy(collision.gameObject); //消灭怪物rb.velocity = new Vector2(rb.velocity.x, jumpforce); //跳跃anim.SetBool("jumping", true);}
}

二、受伤效果的实现

那么我们有了敌人自然要做出受伤的效果,首先我们的想法是当玩家碰到敌人后,会受伤并反弹,我们首先在代码中实现这样一个功能。

 if(collision.gameObject.tag == "enemy"){if(anim.GetBool("falling")){Destroy(collision.gameObject); //消灭怪物rb.velocity = new Vector2(rb.velocity.x, jumpforce); //跳跃anim.SetBool("jumping", true);}else if (transform.position.x < collision.gameObject.transform.position.x) //如果玩家在敌人的左侧{rb.velocity = new Vector2(-10, rb.velocity.y);}else if (transform.position.x > collision.gameObject.transform.position.x) //如果玩家在敌人的左侧{rb.velocity = new Vector2(10, rb.velocity.y);}
}

但是执行后我们发现并没有出现反弹的效果,经过分析,是因为我们的Move函数会不断的执行,覆盖了我们的改变,所以我们定义一个bool值来判断是否受伤,在受伤的时候不执行Move

private bool isHurt;
if(!isHurt)
{Move();
}

我们会在玩家受伤的地方来将这个变量改成true,但是又出现了新的bug就是玩家会一直后退不能停下,我们需要在动画切换函数里面把玩家的状态切换回来,所以这里我们先把动画加进来,然后把这个动画加入动画器同时加入一个hurting的变量作为判断条件

然后我们重写动画转换函数的部分

if(Mathf.Abs(rb.velocity.x) < 0.1f) //人物可以返回站立状态
{anim.SetBool("hurting", false);isHurt = false;anim.SetBool("idleing", true);
}

这样下来就实现了我们的效果,还是比较简单的。

三、代码优化及二段跳实现

几天下来我的代码已经十分凌乱,还有不少可以优化的地方我决定对代码进行优化,然后实现一个二段跳功能

public Transform groundCheck; //地面检测点

首先为了实现二段跳,我定义了一个地面检测点用于判断玩家是否回到地面,然后写了一个对应的判断的变量

public bool isGround;

注意,这里不初始化的时候,默认是false。

bool jumpPressed;
int jumpCount;

然后定义了跳跃按键按下和计数的变量

if(Input.GetButtonDown("Jump") && jumpCount > 0)
{jumpPressed = true;
}

然后在Update中把原本的跳跃函数改成是否允许跳跃的代码,我们会另外实现一个跳跃函数来实现跳跃

我们首先给角色创建一个用于地面检测的空对象

我们把这个变量放在脚底

和之前的下蹲思路一样我们利用这个对象来检测是否站在地面上

isGround = Physics2D.OverlapCircle(groundCheck.position, 0.1f, ground);

跳跃的实现部分

void Jump() //控制玩家跳跃函数
{if(isGround) //落到地面恢复跳跃次数{jumpCount = 2;}if(jumpPressed && jumpCount > 0) //跳跃{rb.velocity = new Vector2(rb.velocity.x, jumpforce);jumpCount--;jumpPressed = false; //确保跳跃执行完毕}
}

此代码在fixedupdate中执行,至此我们就实现了流畅的二段跳,然后我们来修改角色动画

但是这样导致了一个问题就是在角色爬坡的时候会显示跳跃动画,我们通过对检测圆半径的调整来修复这个bug

然后我们删除没有使用的脚步碰撞体,然后我发现了一个新的bug就是在空中二连跳的时候,如果是下落状态二连跳不会切换回跳跃状态,所以修改动画器,添加一条边,成功解决此问题

总的代码如下(优化后)

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;public class PlayerController : MonoBehaviour
{public Rigidbody2D rb; //刚体public Collider2D bodyColl; //身体碰撞体public Animator anim; //动画控制器public float speed = 10; //速度public float jumpforce; //跳跃力public LayerMask ground; //碰撞体过滤public int CherryCount = 0; //收集品樱桃计数器public int GemCount = 0; //收集品宝石计数器public Text Cherrynumber; //控制樱桃数目显示的UIpublic Text Gemnumber; //控制樱桃数目显示的UIpublic Transform groundCheck; //地面检测点bool isGround, isHurt; //监测玩家状态bool jumpPressed;int jumpCount;void Start(){}void Update(){if(Input.GetButtonDown("Jump") && jumpCount > 0){jumpPressed = true;}if (!Physics2D.OverlapCircle(rb.position, 0.1f, ground)) //判断人物在下蹲的时候不可以起身,{if (Input.GetButton("Crouch")) //实现角色下蹲{anim.SetBool("crouching", true);bodyColl.enabled = false;speed = 5; //下蹲速度减慢的效果}else //恢复姿态{anim.SetBool("crouching", false);bodyColl.enabled = true;speed = 10;}}}private void FixedUpdate(){isGround = Physics2D.OverlapCircle(groundCheck.position, 0.2f, ground); //检测玩家是否在地面SwitchAnim();Jump();if(!isHurt){Move();}}void Move() //控制玩家移动函数{float Horizontaldirection = Input.GetAxisRaw("Horizontal"); //玩家移动方向rb.velocity = new Vector2(Horizontaldirection * speed, rb.velocity.y); if (Horizontaldirection != 0){transform.localScale = new Vector3(Horizontaldirection, 1, 1); //控制角色翻转}}void Jump() //控制玩家跳跃函数{if(isGround) //落到地面恢复跳跃次数{jumpCount = 2;}if(jumpPressed && jumpCount > 0) //跳跃{rb.velocity = new Vector2(rb.velocity.x, jumpforce);jumpCount--;jumpPressed = false; //确保跳跃执行完毕}}void SwitchAnim() //玩家动画切换函数{anim.SetFloat("running", Mathf.Abs(rb.velocity.x)); //切换玩家奔跑的动画if(isGround){anim.SetBool("falling", false); //从下落回到站立}else if(rb.velocity.y > 0) //向上移动{anim.SetBool("jumping", true);anim.SetBool("falling", false);}else if(rb.velocity.y < 0) //掉落{anim.SetBool("jumping", false);anim.SetBool("falling", true);}if(isHurt) //从受伤状态恢复{anim.SetBool("hurting", true);if(Mathf.Abs(rb.velocity.x) < 0.1f) //人物可以返回站立状态{anim.SetBool("hurting", false);isHurt = false;anim.SetBool("idleing", true);}}}private void OnTriggerEnter2D(Collider2D collision) //物品收集函数{if(bodyColl.IsTouching(collision) && collision.tag == "cherry") //如果身体碰到了樱桃{Destroy(collision.gameObject); //销毁游戏体CherryCount++; //收集品数量加一Cherrynumber.text = CherryCount.ToString();}if (bodyColl.IsTouching(collision) && collision.tag == "gem") //如果身体碰到了宝石{Destroy(collision.gameObject); //销毁游戏体GemCount++; //收集品数量加一Gemnumber.text = GemCount.ToString();}}private void OnCollisionEnter2D(Collision2D collision) //消灭怪物{if(collision.gameObject.tag == "enemy"){if(anim.GetBool("falling")){Destroy(collision.gameObject); //消灭怪物rb.velocity = new Vector2(rb.velocity.x, jumpforce); //跳跃jumpCount = 1; //踩到怪物后恢复跳跃次数,但是反弹用掉一次anim.SetBool("jumping", true);}else if (transform.position.x < collision.gameObject.transform.position.x) //如果玩家在敌人的左侧{rb.velocity = new Vector2(-10, rb.velocity.y);isHurt = true;}else if (transform.position.x > collision.gameObject.transform.position.x) //如果玩家在敌人的左侧{rb.velocity = new Vector2(10, rb.velocity.y);isHurt = true;}}}
}

Unity开发日记【第六天】——敌人、受伤和运动手感提升相关推荐

  1. unity开发日记之火箭发射

    2020-06-25 夜晚,思考人生的意义,乔布斯在斯坦福的演讲说到,你的热爱就是你的事业,你的事业就是你的热爱,我想了想,什么是自己的热爱呢,这么多年,陪伴在自己身边的也就是充满乐趣的游戏吧.自己不 ...

  2. Unity开发日记【第一天】——素材的导入及地图的建立

    前言:本人由于兴趣和未来的工作原因开始尝试接触和学习Unity开发,为了避免忘记一些东西所以写下这些博客算是一个记录. 目录 一.软件的安装与配置 二.如何编辑素材以及Tilemap的使用 三.图层和 ...

  3. Unity开发日记【第七天】——怪物的移动和动画及类的实现

    目录 一.怪物的移动 二.怪物的动画 三.实现消灭动画.类的初探. 一.怪物的移动 之前我们向游戏中添加了敌人,现在要努力让敌人动起来,首先我们之前使用的是方形的碰撞器,为了防止怪物卡住我们改用圆形的 ...

  4. C# + Unity开发日记(二) 利用宏命令实现简单的代码开关

    unity提供的宏命令在开发中可以非常方便的对不同的代码进行区分,例如UNITY_EDITOR 就可以定义代码只在编辑器里运行,这样就可以在下面写一些编辑器专用的代码,而不用担心打包Android或者 ...

  5. UNITY 开发日记/教程 俄罗斯方块 (五) 方块平移和旋转

    接上文. 已经实现了方块下落之后,可以意识到,平移变得非常简单.因为我们已经实现了边界检查的函数,只要把移动目标坐标放进去判断就可以了. 在UPDATE中增加如下代码 if (Input.GetKey ...

  6. Unity开发日记【第八天】——音效与对话框

    目录 一.音效的实现 二.对话框的实现 一.音效的实现 声音是一个游戏必不可少的元素,现在开始尝试给游戏加入一些音效,这里面设计三个组件,分别是Audio Listener(接收).Audio Sou ...

  7. [Unity]《太空射击》开发日记Ep.2(初级篇)

    文章目录 前言 敌人1脚本 预制件 敌人1的完善工作 触发器式碰撞 屏幕边缘检测 计算敌人1的飞行角度 优化敌人生成器 前言 [Unity]<太空射击>开发日记Ep.1(入门篇) 在上一篇 ...

  8. 用Unity开发一款2D横版游戏demo

    # LanW Game Project 目录 (一) 介绍 (二) 安装教程 (三) 开发流程 1.  新建工程 2.  设置人物 3.  控制主角的移动 4.   添加切换动作的动画 5.   镜头 ...

  9. 浅谈Unity与VR产业,用Unity开发VR应用

    VR(Virtual Reality的缩写,中文翻译-虚拟现实)概念早在80年代初就被提出来的,其具体是指借助计算机及最新传感器技术创造的一种崭新的人机交互手段. 中国VR产业仍在摸索阶段,亟缺复合型 ...

最新文章

  1. Ubuntu中Atom安装与使用
  2. 图论 ---- 构造DFS树的思想 K - Boomerangs Gym - 102001K
  3. 数组模拟栈和队列板子
  4. Android SoundPool.play方法的音量与系统音量的关系
  5. linux信号量超过系统限制
  6. PL\SQL 打开时出现动态执行表不可访问,本会话的自动统计被禁止
  7. 手机轮廓光怎么拍_想拍美秋天叶子,别犯这5个初级错误!告诉错在哪里及咋拍正确...
  8. 单例(Singleton)设计模式应用场景
  9. 鲜为人知的6个黑科技网站_6种鲜为人知的熊猫绘图工具
  10. mysql varchar java_关于MySQL varchar类型最大值,原来一直都理解错了
  11. C语言程序设计 笔试考试,试题样卷
  12. 2014 UESTC Training for Data Structures D - 长使英雄泪满襟
  13. IBM 、M$ 、Google Apple
  14. unix linux windows mac,從 Mac (Unix) 移至 Windows | Microsoft Docs
  15. 部署 shell Linux
  16. 什么是 Apache Shiro
  17. NFC怎么复制房卡_为了省门禁卡的钱,买了NFC读卡器,到底值不值
  18. 怎样在虚拟机装文件服务器,虚拟机下怎么解压文件
  19. SQL Server Arithmetic overflow error converting nvarchar to data type numeric
  20. 【入门】Pytorch实现简单的图片分类器

热门文章

  1. java逻辑运算符 ||,|,,,!,^
  2. python语言有哪些关系运算符_python常用运算符有哪些?
  3. 让智能交互更加个性化:基于用户的交互设计技术的研究
  4. 【H - Highways】
  5. 罗辑思维CEO李天田:我们是这样玩儿公司的
  6. Reactor Reactor模式是什么 - 晏无心的博客补充说明
  7. 集成的故事 - 智慧管道
  8. 伦敦城市大学卡斯商学院MBA招生要求
  9. Unity设置VS2017为编译器
  10. 缓存更新的Design Pattern -- 缓存专题(2)