IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity2D入门(九):敌人的移动、消灭敌人(包括动画的触发) -> 正文阅读

[游戏开发]Unity2D入门(九):敌人的移动、消灭敌人(包括动画的触发)

游戏中的敌人有三种,我们先拿青蛙和老鹰来做例子,我们要实现的效果是:青蛙要能共在一定的范围内往返跳动,老鹰则是在一定的范围内上下运动。

要实现敌人在一定范围内移动,拿青蛙为例,我们需要确定他活动的左右边界点,我们在frog下创建两个空物体,让他们分别代表左端点和右端点,在右侧Inspector窗口中,可以设置这个物体的颜色。

?

这样我就就可以依靠拖动两点的位置来界定敌人移动的边界了。

下一步我们在代码中实现敌人的移动,在这里我用文字阐述一下我的设计思想,首先为青蛙创建一个脚本,由于青蛙做往返运动,当青蛙面向左边时向左走,面向右边是向右走,当向左走碰到左端点是改变面部朝向,更改为向右走,通过上面描述,我们知道需要创建一个float类型的speed来控制青蛙的移动速度,在创建一个bool型的变量控制青蛙的面部朝向,假设用facing_left=true/false来控制面部朝向(初始值我们设为true)。接下来,代码运行时,我们首先要获取到做右端点的x的值,因此我们能需要两个变量来获取,获取了之后,这两个物体对于我们就是去了意义,留着只会浪费性能,所以我们要销毁这两个物体。接下来再考虑,青蛙是一跳一跳的,所以他还需要一个向上跳跃的力jumpforce,我们还需要为跳跃添加限制条件,每接触一次地面才能条一次,那不然就一直跳了。因此青蛙在运动中就会出现四种情况:1.面向左(在空中/不在空中)2.面向右(在空中/不在空中),下面直接上代码:

public class Enemy_frog : Enemy
{

? ? private Rigidbody2D rb;
? ? public Collider2D coll;
? ? public float speed,jumpforce;
? ? public LayerMask ground;
? ? public Transform leftpoint, rightpoint;
? ? private float leftx, rightx;
? ? private bool facing_left=true;
? ? //private Animator anim;

? ? protected override void Start()
? ? {
? ? ? ? base.Start();
? ? ? ? rb=GetComponent<Rigidbody2D>();
? ? ? ? //anim = GetComponent<Animator>();
? ? ? ? coll = GetComponent<Collider2D>();


? ? ? ? transform.DetachChildren();
? ? ? ? leftx = leftpoint.position.x;
? ? ? ? rightx = rightpoint.position.x;
? ? ? ?
? ? ? ? Destroy(leftpoint.gameObject);
? ? ? ? Destroy(rightpoint.gameObject);
? ? }

? ? // Update is called once per frame
? ? void Update()
? ? {
? ? ? ? SwitchAnim();
? ? }
? ? void Movement()
? ? {
? ? ? ? if (facing_left)
? ? ? ? {
? ? ? ? ? ? if (coll.IsTouchingLayers(ground))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? anim.SetBool("jumping", true);
? ? ? ? ? ? ? ? rb.velocity = new Vector2(-speed, jumpforce);
? ? ? ? ? ? }
? ? ? ? ? ? if (transform.position.x<leftx)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rb.velocity = new Vector2(0, 0);
? ? ? ? ? ? ? ? transform.localScale = new Vector3(-1, 1, 1);
? ? ? ? ? ? ? ? facing_left = false;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? if (coll.IsTouchingLayers(ground))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? anim.SetBool("jumping", true);
? ? ? ? ? ? ? ? rb.velocity = new Vector2(speed, jumpforce);
? ? ? ? ? ? }
? ? ? ? ? ? if (transform.position.x > rightx)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rb.velocity = new Vector2(0, 0);
? ? ? ? ? ? ? ? transform.localScale = new Vector3(1, 1, 1);
? ? ? ? ? ? ? ? facing_left = true;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? void SwitchAnim()
? ? {
? ? ? ? if (anim.GetBool("jumping"))
? ? ? ? {
? ? ? ? ? ? if (rb.velocity.y < 0.1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? anim.SetBool("jumping",false);
? ? ? ? ? ? ? ? anim.SetBool("falling",true);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (coll.IsTouchingLayers(ground)&&anim.GetBool("falling"))
? ? ? ? {
? ? ? ? ? ? anim.SetBool("falling", false);
? ? ? ? }
? ? }

}

以上代码中有一些要注意的是这里用Collider变量去检测青蛙是不是和属于Grid瓦片地图发生了碰撞,这里瓦片地图要新建一个Layer取名为ground,另外动画的切换还存在一些问题,那就是这个青蛙根本不存在静止的状态,跳完一次之后紧接着开始第二次跳跃,我们希望他跳完一次后静止一段时间,才开始第二次跳跃,那么我们就需要用到在上节笔记中用到的动画event了,我们为青蛙创建了静止动画后,在静止动画结束的时候,为其添加两个事件,一个是Movement函数另一个是SwitchAnim函数,这样就是先了跳跃-静止-跳跃的过程。

老鹰的运动实现和青蛙的十分相似,而且更为简单,在此不做赘述。

下面来说一下消灭敌人的效果实现,因为敌人不只有一种,如果在每个敌人的脚本单独写消灭的效果也可以,但是会显得比较繁琐,所以我们可以为老鹰和青蛙添加一个共同的父类,在父类中写消灭敌人的效果,这样子类调用父类,就可以了。而且由于消灭敌人的效果我们是写在了Player Controller中,我们还要在其他的类中实现敌人类的实例化,代码:

public class Enemy : MonoBehaviour
{
? ? protected Animator anim;
? ? protected AudioSource deathAudio;
? ? // Start is called before the first frame update
? ? protected virtual void Start()
? ? {
? ? ? ? anim = GetComponent<Animator>();
? ? ? ? deathAudio = GetComponent<AudioSource>();
? ? }
? ? public void Death()
? ? {
? ? ? ? GetComponent<Collider2D>().enabled = false;
? ? ? ? Destroy(gameObject);
? ? }
? ? public void JumpOn()
? ? {
? ? ? ? deathAudio.Play();
? ? ? ? anim.SetTrigger("death");
? ? }

}

下面是在PlayerController中写道的消灭敌人的代码,两者需要结合着看,后面我来解释一下。

?private void OnCollisionEnter2D(Collision2D collision)
? ? {

? ? ? ? if (collision.gameObject.tag == "Enemy")
? ? ? ? {
? ? ? ? ? ? //eagle_test eagle = collision.gameObject.GetComponent<eagle_test>();
? ? ? ? ? ? //Enemy_eagle eagle = collision.gameObject.GetComponent<Enemy_eagle>();
? ? ? ? ? ? Enemy enemy = collision.gameObject.GetComponent<Enemy>();
? ? ? ? ? ? if (anim.GetBool("falling"))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? enemy.JumpOn();
? ? ? ? ? ? ? ? //eagle.JumpOn();
? ? ? ? ? ? ? ? rb.velocity = new Vector2(rb.velocity.x, jumpforce * Time.fixedDeltaTime*50);
? ? ? ? ? ? ? ? anim.SetBool("jumping", true);
? ? ? ? ? ? ? ? anim.SetBool("falling", false);
? ? ? ? ? ? }else if (transform.position.x < collision.gameObject.transform.position.x)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rb.velocity = new Vector2(-10, rb.velocity.y);
? ? ? ? ? ? ? ? isHurt = true;
? ? ? ? ? ? ? ? hurtAudio.Play();
? ? ? ? ? ? }else if(transform.position.x > collision.gameObject.transform.position.x)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rb.velocity = new Vector2(10, rb.velocity.y);
? ? ? ? ? ? ? ? isHurt = true;
? ? ? ? ? ? ? ? hurtAudio.Play();
? ? ? ? ? ? }
? ? ? ? }
? ? }

?首先在Player代码中,如果碰撞体检测碰撞到tag标记为Enemy的物体,在继续判断,只有当角色处在下落的状态,也就是首先要碰到敌人,而且是在敌人的头顶,才能把敌人踩死,那么就去调用JumpOn函数,他的作用是出发名为death的动画,我们在来到Animator窗口中,我们可以看到一个看色的方块anystate,也就是说,在任何情况下都有可能出发的动画。那么这个动画触发了之后,我们在这个动画后添加event,首先先让他的active状态变为false,不然他只是切换了动画,他的碰撞体还在,会持续与游戏场景中的其他物体碰撞,然后再销毁它。重点是,在Player的代码中,通过 Enemy enemy = collision.gameObject.GetComponent<Enemy>();这一行代码实现了类的调用和实例化。

没有提及到的代码的功能是,如果消灭了敌人,玩家可以获得一次额外的跳跃,否则,如果不是踩在敌人头上,那么就是受伤,会被敌人击退,所以另外两个else是向两个方向击退的效果。

以上是以青蛙作为例子,老鹰的实现过程也是类似的,在此不做赘述。

?

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:59:42  更:2021-07-29 11:59:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 19:56:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码