当前位置: 首页 > news >正文

【Unity2D:C#Script】制作敌人

一、制作敌人预制体

1. 在场景面板中添加敌人,并创建预制体

2. 设置敌人的锚点在底部

二、为敌人添加碰撞体积

1. 添加Box Collider 2D、Rigidbody 2D组件

2. 调整轴心点位置、层级、碰撞体积大小、刚体类型、锁定z轴

        Body Type(刚体类型):Dynamic:自身运动,也会被其他刚体推动;Kinematic:自身运动,但不会被其他刚体推动;Static:自身不动,也不会被其他刚体推动

        注意:敌人是碰撞器而不是触发器,所以不要勾选Is Trigger

三、编辑敌人脚本

1. 创建变量

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;
}

2. 初始化

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}}

3. 编辑计时器、控制敌人移动

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}void Update(){// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}}

4. Ruby和敌人碰撞的方法

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}void Update(){// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}}

5. 添加敌人修复(即死亡效果)逻辑

        添加布尔变量broken,表示是否修理好;在Update方法中进行判断,若已经修理好则return(停止移动);新建fix方法,在敌人生命值为0时调用

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 敌人基础属性private int maxHealthPoint = 100;public int healthPoint;private float speed = 3.0f;private bool broken;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;// 为当前生命值赋值healthPoint = maxHealthPoint;// 敌人初始时是故障的broken = true;}void Update(){if (broken == false) {return;}// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}// 敌人改变生命值public void changeHealthPoint(int value){healthPoint = Mathf.Clamp(healthPoint+value, 0, maxHealthPoint);if(healthPoint <= 0) {enemyFixed();}}// 敌人修复完成public void enemyFixed(){broken = false;}}

6. 添加敌人动画控制器逻辑

public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 创建动画控制器对象Animator animator;// 敌人基础属性private int maxHealthPoint = 100;public int healthPoint;private float speed = 3.0f;private bool broken;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 获取动画控制器组件animator = GetComponent<Animator>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;// 为当前生命值赋值healthPoint = maxHealthPoint;// 敌人初始时是故障的broken = true;// 设置初始动画if(moveHorizontally == true) {animator.SetFloat("MoveX", direction);} else {animator.SetFloat("MoveY", direction);}}void Update(){if (broken == false) {return;}// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值,更改动画播放的方向if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;if(moveHorizontally == true) {animator.SetFloat("MoveX", direction);} else {animator.SetFloat("MoveY", direction);}}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}// 敌人改变生命值public void changeHealthPoint(int value){healthPoint = Mathf.Clamp(healthPoint+value, 0, maxHealthPoint);if(healthPoint <= 0) {enemyFixed();}}// 敌人修复完成public void enemyFixed(){broken = false;animator.SetTrigger("Fixed");}}

四、为敌人添加动画

                 动画混合树详细教程:【Unity】动画混合树

1. 在Assets/Art/Animations/Animator文件夹中,新建Enemy的Animator Controller文件

2. 创建Move状态混合树

        创建参数MoveX、MoveY(红色)

        设置混合类型为2D简单方向(蓝色)

        将两个参数设置为MoveX、MoveY(紫色)

        创建四个Motion(黄色)

        创建四个AnimationClip文件(敌人向四个方向移动的动画)并添加到Motion中(绿色)

        修改四个Motion的两个参数的值(粉色)

3. 新建Fixed State,将Move通向Fixed,新建Trigger类型的Fixed参数,点击Move通向Fixed的箭头,将条件设置为Fixed

 

4. 给敌人添加Animator组件,并挂载Enemy的Animator Controller文件

本章完。感谢阅读! 

相关文章:

  • 数据库(6)——数据类型
  • springboot社区助老志愿服务系统-计算机毕业设计源码96682
  • Golang设计模式(四):观察者模式
  • SpringBoot使用rsa-encrypt-body-spring-boot实现接口加解密
  • Spring Boot+Debezium:解决 MySQL Binlog监听
  • 出书,是「盖你自己的房子」你知道吗?
  • 清华新突破||新研究揭示多智能体协作的秘密武器
  • springboot + Vue前后端项目(第十一记)
  • ArcGIS中离线发布路径分析服务,并实现小车根据路径进行运动
  • 【Spring Boot】在项目中使用Spring AI
  • Vue.js功能实现博客
  • Golang使用HTTP框架zdpgo_resty实现文件下载
  • [Linux打怪升级之路]-进程和线程
  • Web基础考点
  • vue中axios的使用
  • 【React系列】如何构建React应用程序
  • 2017届校招提前批面试回顾
  • Computed property XXX was assigned to but it has no setter
  • CSS魔法堂:Absolute Positioning就这个样
  • Electron入门介绍
  • HTTP 简介
  • Intervention/image 图片处理扩展包的安装和使用
  • js如何打印object对象
  • leetcode讲解--894. All Possible Full Binary Trees
  • Objective-C 中关联引用的概念
  • Python学习之路16-使用API
  • Redis 中的布隆过滤器
  • REST架构的思考
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • SQLServer之创建显式事务
  • webgl (原生)基础入门指南【一】
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 动态魔术使用DBMS_SQL
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 聊聊directory traversal attack
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端技术周刊 2019-01-14:客户端存储
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 深度学习中的信息论知识详解
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 事件委托的小应用
  • 王永庆:技术创新改变教育未来
  • 再谈express与koa的对比
  • zabbix3.2监控linux磁盘IO
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #NOIP 2014# day.1 T2 联合权值
  • #pragma multi_compile #pragma shader_feature
  • #pragma pack(1)
  • $.ajax,axios,fetch三种ajax请求的区别
  • (03)光刻——半导体电路的绘制
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)