Unity之闪电侠大战蓝毒兽(简陋的战斗系统)

目录

🎨一、创建地形

🎮二、创建角色

🏃2.1 动画

🏃2.2 拖尾 

🏃2.3 角色控制 

​🏃2.4 技能释放

🏃2.5 准星

📱三、创建敌人

🐲3.1 选择模型

🐲3.2 敌人动画器 

🐲3.3 敌人脚本

💤四、杂谈


新年好啊大家,开工大吉,一起摸鱼!经过小编一个月摸鱼的努力,本篇给自己学到的知识做一个汇总和应用。效果如下动图所示:

小编加入了丑陋的蓝毒兽,并让它看起来不那么傻。它会追击、会进攻、还会死(doge.jpg)。

小编给了它十滴血,当我们控制闪电侠攻击它的时候会实时判断血量HP,HP小于等于0就会触发死亡动画。


当然也有很多不足之处,所以才叫“简陋的战斗系统。。。”我们控制的角色没有加HP,蓝毒兽攻击角色是没有反应的,死了后还在地上滑动起来了。。。估计是爆炸后呲的它来回撞。有空的话小编还会慢慢完善,废话不多说,下面带大家实现这个实例。


一、创建地形

首先地形是小编自己绘制的,教程可以看下面这篇文章。 

Unity之地形的构建-CSDN博客文章浏览阅读1.1k次,点赞16次,收藏19次。PS:公司没活干,好无聊偷偷摸鱼学Unity,害怕自己学完之后忘记,写下这一篇博客https://blog.csdn.net/qq_48512649/article/details/135267070资源商店也有很多好的地形场景,大家可以用自己喜欢的来做。

二、创建角色

角色模型的创建和动作可以参考下面这篇文章。大家选一个自己喜欢的人物模型来做。。。小编当初做练习选的这个就拿来用了也没换,后悔死了,后面都懒得换了。

Unity之动画和角色控制_unity 角色控制-CSDN博客文章浏览阅读1k次,点赞24次,收藏19次。《绿洲大镖客之重生我是闪电侠》😋_unity 角色控制https://blog.csdn.net/qq_48512649/article/details/135775295

作为一个初学者偶然知道的这个模型素材网站,但是我还没用过(简单瞅了瞅里面有闪电侠的模型doge.jpg)爱给网_音效配乐_3D模型_视频素材_免费下载 


Player的标签设置为Player我们后面要用到:

2.1 动画

这里角色的动画器小编分了两个图层:

  1. Base Layer图层是 静止<——>跑步——>起跳——>空中静止——>落地动作,动作的转换参数小编用的BoolTrigger居多。

  2. 第二个图层用来释放技能的,这里小编设计了两个技能

这里讲一下,权重表示图层的权重,跑跳等动作权重(1)比技能权重(0.9)高,播放动画就会优先播放跑跳的动作。

因为释放技能我们只用手来播放动画,这里的遮罩wave, 释放技能时保证手部动作流畅(新建一个遮罩并保留手部为绿色即可,然后加到图层中)。


2.2 拖尾 

 同样在之前的博客闪电侠的拖尾我们是由拖尾组件TrailRenderer实现的,但是实现效果拖尾只出现在了角色脚下那部分。这和我们所熟悉的闪电侠不一样啊。

 为了把拖尾效果覆盖到全身小编就想到了一个很笨很笨的方法。

新建好多个空对象把它们放到角色身上,再把拖尾组件都挂到这些空对象上,这样拖尾效果就覆盖到全身了。(大佬有好的方案教教我o(╥﹏╥)o) 

来看下效果: 

2.3 角色控制 

接下来轮到脚本了,编写FPSMove脚本控制玩家移动和动画之间的转换:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;//给玩家挂载 Character Controller 组件
public class FPSMove : MonoBehaviour
{private CharacterController cc;//移动速度public float moveSpeed;//跳跃速度public float jumpSpeed;//定义获得按键值的两个变量private float horizontalMove, verticalMove;private Vector3 dir;//手动实现重力public float gravity;private Vector3 velocity;//创建空对象放到玩家最底部用来检测碰没碰到地面,把空对象挂上来//检测点的中心位置public Transform groundCheck;  //检测点的半径public float checkRadius;//需要检测的图层public LayerMask groundLayer;//布尔值存储Physics.CheckSphere的返回值public bool isGround;//定义动画变量private Animator animator;private void Start(){ //获取角色控制组件cc = GetComponent<CharacterController>();//获取动画组件animator = GetComponent<Animator>();}private void Update(){//检测玩家是否在地面上,如果定义的球体和物体发生碰撞返回trueisGround = Physics.CheckSphere(groundCheck.position, checkRadius, groundLayer);if (isGround && velocity.y < 0){velocity.y = -2f;}//获得移动按键的值horizontalMove = Input.GetAxis("Horizontal") * moveSpeed;verticalMove   = Input.GetAxis("Vertical") * moveSpeed;dir = transform.forward * verticalMove + transform.right * horizontalMove;//实现移动cc.Move(dir * Time.deltaTime);//每秒减去重力的值不断下降,手动实现重力velocity.y -= gravity * Time.deltaTime;cc.Move(velocity * Time.deltaTime);//判断是否按下跳跃键if (Input.GetButtonDown("Jump") && isGround) {//给玩家一个向上的速度velocity.y = jumpSpeed;//播放跳跃动画animator.SetTrigger("Jump");}isGroundTest();//如果向量不等于空就证明我们按了方向键了if (dir != Vector3.zero){//播放跑步动画animator.SetBool("IsRun",true);}//没有按方向键else{//播放站立动画animator.SetBool("IsRun",false);}}private void isGroundTest(){if (isGround == false){//播放落地动画animator.SetBool("down",true);}else if (isGround == true){//播放落地动画animator.SetBool("down",false);}}
}

 老样子空对象GroundCheck放在角色脚底用来检测角色碰没碰到地面,把地形的图层设置为Ground

2.4 技能释放

技能的模型和发生碰撞后爆炸的原理大家可以根据下面文章回顾一下,小编技能用的模型也是在这里面挑选的:

Unity之物理系统_unity 物理系统-CSDN博客文章浏览阅读1.2k次,点赞21次,收藏20次。专栏的上一篇角色控制器控制角色移动跳崖,这一篇来说说Unity的物理系统。本篇小编还要带大家做一个碰撞检测效果实例,先放效果图:流星撞击地面产生爆炸效果。_unity 物理系统https://blog.csdn.net/qq_48512649/article/details/135600857

编写Gun脚本来控制技能的生成并挂到角色身上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Gun : MonoBehaviour
{//子弹预设体序列化[SerializeField]private GameObject bulletPrefab;//游戏对象子弹发射点[SerializeField]private GameObject bulletPoint;//子弹速度[SerializeField] private float bulletSpeed = 1200;//定义动画变量private Animator animator;[SerializeField] //获取技能对象private GameObject RotatorPS2;[SerializeField] private GameObject PS2Point;// Start is called before the first frame updatevoid Start(){//获取动画组件animator = GetComponent<Animator>();}// Update is called once per framevoid Update(){//判断是否按下技能键if (Input.GetButtonDown("Fire1")){//播放跳跃动画animator.SetTrigger("wave");PlayerFireEffectTest();}//判断是否按下技能键if (Input.GetButtonDown("Fire2")){//播放技能动画PlayerFireEffect();//播放技能动画animator.SetTrigger("pickUp");}}//播放技能特效public void PlayerFireEffect(){Debug.Log("shoot!!!!");//生成一个子弹实例,每点击射击一次则生成一枚子弹GameObject bullet = Instantiate(RotatorPS2, bulletPoint.transform.position, transform.rotation);//启动特效bullet.SetActive(true);//给子弹一个向前的力bullet.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed);//8秒关闭//Invoke("UnEffect", 8f);Destroy(bullet,8);}public void PlayerFireEffectTest(){//生成一个子弹实例,每点击射击一次则生成一枚子弹GameObject bullet = Instantiate(bulletPrefab, PS2Point.transform.position, transform.rotation);//启动特效bullet.SetActive(true);//给子弹一个向前的力bullet.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed);}// 取消播放技能特效private void UnEffect(){RotatorPS2.SetActive(false);}
}

要给你选择的技能特效加上标签,用来识别是否打到蓝毒兽身上。

 这里FirePointPS2Point是一二技能的发射点,把你喜欢的技能特效挂在Gun脚本上,小编这里放了Magic fire2RotatorPS2,别忘了给技能特效加刚体和碰撞组件。

 有了技能还不够,技能发射后碰到物体产生爆炸效果,编写fire脚本挂载到你所选的技能特效预设体上。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Fire : MonoBehaviour
{[SerializeField]//创建一个爆炸的预设体private GameObject Explosion;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}//监听发生碰撞: 只监听发生碰撞的一瞬间private void OnCollisionEnter(Collision collision)  //参数 collision 就是你碰撞到的物体的碰撞信息{//创建一个爆炸物体GameObject explosion =Instantiate(Explosion, transform.position, Quaternion.identity);   //参数: 预设体,爆炸位置是自身火焰位置,不旋转//销毁自身(流星): 流星撞击地面爆炸物产生流星销毁Destroy(gameObject);explosion.SetActive(true);//获取碰撞到物体看一下参数collision —— 打印一下物体名称,这里打印的是地面的名称Debug.Log("撞到了"+collision.gameObject.name);//实用小技巧//给地面一个图层"Ground"   collision.collider.tag == "Ground"   可以判断物体是否踩在地面上}//结束碰撞检测方法private void OnCollisionExit(Collision other){//collision.collider.tag == "Ground"  判断物体是否离开地面}//监听触发检测private void OnTriggerEnter(Collider other){}
}

比如我这里选的RotatorPS2特效 ,我把fire脚本挂到它身上,ExplosionVariant是爆炸特效。

技能撞倒物体消失产生爆炸效果,爆炸后也会消失,编写 ExplosionTest 脚本挂到爆炸特效上来实现这一功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ExplosionTest : MonoBehaviour
{float timer = 0;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){Debug.Log("============这里是explosion");//如果时间大于一秒就销毁爆炸物timer += Time.deltaTime;if (timer > 1){Destroy(gameObject);}}
}

2.5 准星

小编盗用自己的图片来加准星(doge.jpg)

新建一个图像,然后根据下图的数据设置好,还可以选择自己喜欢的颜色,这样准星就设置好了。

 到这里玩家的功能差不多都实现了,下面我们来实现丑陋的蓝毒兽。

三、创建敌人

3.1 选择模型

首先我们去资源商店淘一下敌人的免费模型,毕竟小编很穷o(╥﹏╥)o。搜索monster点击免费资源就会找到下面这个,这个居然是1月26号发布的,当然也有很多其他的优秀资源看个人喜好选择。


在选模型的过程中还闹过笑话,之前选了一个类似大猩猩的模型下半身陷进去了眼睛却还是在原来的位置(这是加了寻路组件之后才这样的),然后在寻路组件的作用下保持这个姿势向我靠近。。。后来也没改过来

 3.2 敌人动画器 

 动画器这里小编编辑的有静止、跑步、攻击、死亡。attack1和attack2小编直接连一块了就,形成一个连击。


至于这里的run和run0,我不知道是模型还是哪出问题了跑步的动画循环播放不了只播放一遍,所以我又又想出了一个很笨很笨的方法让俩跑步动画来回切换达到循环的效果。。。大家不要笑话我。

关于导航网格Nav Mesh Agent组件的使用大家可以回顾这篇文章,使用Nav Mesh Agent组件记得烘焙地形,这里我们用作敌人的寻路功能。

Unity之射线检测和导航系统-CSDN博客文章浏览阅读558次,点赞5次,收藏7次。不知道大家有没有玩过红色警戒 —— 一款即时战略游戏,和罪恶都市一样小编小学的时候就开始玩了,这款游戏控制单位角色移动是通过鼠标的点击来实现。同样的操作方法还有英雄联盟等很多游戏,那本篇文章小编就通过简单小实例来讲解这种操作在Unity中是如何实现的。小编先展示一下实例的演示动图:红色球体表示我们控制的角色,鼠标左键点击小球就会到相应的坐标位置并打印坐标。https://blog.csdn.net/qq_48512649/article/details/135674470这是蓝毒兽挂载的组件大家参考一下:

3.3 敌人脚本

好了接下来我们让丑陋的蓝毒兽变得聪明一点,创建脚本AI挂载到蓝毒兽上:


这里用枚举的方式来描述蓝毒兽的状态。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//状态
public enum EnemyState
{idle,   //静止状态run,    //逃跑状态attack, //攻击状态die     //死亡状态
}public class AI : MonoBehaviour
{//状态public EnemyState CurrentState = EnemyState.idle;//动画控制器private Animator animator;//玩家private Transform player;//导航private NavMeshAgent agent;//怪兽血量private int hp = 10;// Start is called before the first frame updatevoid Start(){//获取动画组件animator = GetComponent<Animator>();agent = GetComponent<NavMeshAgent>();player = GameObject.FindWithTag("Player").transform;}// Update is called once per framevoid Update(){float distance = Vector3.Distance(player.position, transform.position);//判断状态switch (CurrentState){case EnemyState.idle:idle(distance);break;case EnemyState.run:run(distance);break;case EnemyState.attack:attack(distance);break;case EnemyState.die:die();break;}}void idle(float distance){//站立状态,如果和玩家距离为5到200米变为跑步if (distance >= 5 && distance <= 200){CurrentState = EnemyState.run;}//播放站立动画animator.SetBool("IsRun", false);        //导航停止agent.isStopped = true;}void run(float distance){//如果离玩家大于200米,则变为站立if (distance >= 200){CurrentState = EnemyState.idle;}else if (distance < 9){CurrentState = EnemyState.attack;}//播放跑步动画animator.SetBool("IsRun", true); animator.SetTrigger("Run1");animator.SetTrigger("Run2");//导航开始agent.isStopped = false;agent.SetDestination(player.position);}void attack(float distance){//如果离玩家大于10米,则变为站立if (distance >= 10){CurrentState = EnemyState.run;}//播放攻击动画animator.SetTrigger("Attack");}void die(){//播放死亡动画animator.SetTrigger("die");}//监听碰撞检测private void OnCollisionEnter(Collision collision){//判断是否碰到技能if (collision.collider.tag == "Skill"){//血量减少hp--;//如果血量少于等于0,敌人死亡if (hp <= 0){Debug.Log("==========HP:" + hp);CurrentState = EnemyState.die;//Destroy(gameObject);}}}
}

四、杂谈

实例教程到这里就先结束了,八千多字比我毕业论文字数都多(doge.jpg)。继续扩展的话可以像很多游戏一样设置一个出生点,不断有丑陋的蓝毒兽实例被创建;还可以给我们玩家也加上血条,被攻击也会有击退反应;有想法之后可以进行针对性学习。

自己写的游戏想怎么来就怎么来,拜拜┏(^0^)┛

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/480196.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware Workstation 17安装教程:安装系统

点击开启虚拟机 安装向导的初始化界面 Keyboard和Language Support分别指的是键盘类型和语言支持&#xff0c;我们首先单击Time & Date按钮&#xff0c;设置系统的时区和时间。在地图上单击中国境内即可显示出上海的当前时间&#xff0c;确认后单击左上角的Done按钮。系统…

从starrocks安装说起和Oracle的OLAP殊途同归

StarRocks是一款分析型数据库&#xff08;他的定语也很多&#xff0c;分布式存算分离等等&#xff09;。作为数据库他的运行和维护迟早也是落在我这里的。对于做数据库的人都知道什么是交易型数据库&#xff0c;什么是分析型数据库。以及什么是事务分析混合型数据库。但是对于非…

Golang for 循环

从基础知识到高级技术、并发和通道 Go&#xff08;Golang&#xff09;编程语言中的“for”循环是一个基本而多功能的结构&#xff0c;用于迭代集合、重复执行代码块以及管理循环控制流。Golang的“for”循环语法简洁却强大&#xff0c;为处理多样的循环场景提供了一系列能力。无…

大厂的数据质量中心系统设计

日常工作中&#xff0c;数据开发上线完一个任务后并不是就可以高枕无忧&#xff0c;时常因上游链路数据异常或者自身处理逻辑的 BUG 导致产出的数据结果不可信。而问题发现可经历较长周期&#xff08;尤其离线场景&#xff09;&#xff0c;往往是业务方通过上层数据报表发现数据…

【Unity】【VR开发】如何创建让物体透明的Material

【背景】 在VR开发中&#xff0c;如果遇到需要锚点传送移动的场景&#xff0c;作为锚点的目标往往需要设置为透明。本篇介绍简单设置Material使3D GameObject便透明的方法。 【操作方法】 新建一个Material对象选中Material对象后&#xff0c;在Inspector面板中重选Shader属…

Excel练习:双层图表

Excel练习&#xff1a;双层图表 学习视频Excel制作双层图表&#xff0c;很多人都不会&#xff0c;其实只需1步操作就够了&#xff01;_哔哩哔哩_bilibili ​​ 通过调整两个图形的显示范围实现 增加折现图的负数显示范围&#xff0c;使折现图仅出现在整体图形的上方增加柱形…

Kotlin 基本语法5 继承,接口,枚举,密封

1.继承与重写的Open关键字 open class Product(val name:String ) {fun description() "Product: $name"open fun load() "Nothing .."}class LuxuryProduct:Product("Luxury"){//继承需要调用 父类的主构造函数override fun load(): String {…

Mybatis | 初识Mybatis

初识Mybatis 目录: 初识Mybatis什么是Mybatis&#xff1f;Hibernate 和 MyBatis的区别&#xff1f;Mybatis的下载和使用Mybatis的工作原理 作者简介 &#xff1a;一只大皮卡丘&#xff0c;计算机专业学生&#xff0c;正在努力学习、努力敲代码中! 让我们一起继续努力学习&#…

从宏观到微观——泽攸科技ZEM系列台式扫描电子显微镜在岩石分析中的应用

岩石作为地球地壳的主要构成物质之一&#xff0c;其微观结构对于了解地质过程、资源勘探以及工程建设具有重要意义。按照岩石的成因&#xff0c;可以把它们分为三类&#xff1a;岩浆岩、沉积岩和变质岩。在地球表面&#xff0c;沉积岩占据75%的份额&#xff0c;而在地壳深度&am…

卡车拆解不再难:可视化示意图的魔力

随着科技的飞速发展和工业的不断进步&#xff0c;卡车作为物流运输的核心力量&#xff0c;承担着越来越多的运输任务。然而&#xff0c;当卡车出现故障或需要维护时&#xff0c;复杂的拆解流程往往让人头疼不已。这时&#xff0c;一份清晰易懂的卡车拆解示意图就显得尤为重要。…

解决本地googleapis 谷歌统计 nodejs 遇到 ECONNRESET和 ETIMEDOUT

在本地通过谷歌分析接口, 获取网站的访问量统计, 用于在管理端面板世界地图显示 获取分析数据的部分代码,这部分很简单示例有 // 获得前10个页面浏览量与页面标题在过去30天 const {BetaAnalyticsDataClient} require(google-analytics/data); const analyticsDataClient ne…

Linux 内存top命令详解

通过top命令可以监控当前机器的内存实时使用情况&#xff0c;该命令的参数解释如下&#xff1a; 第一行 15:30:14 —— 当前系统时间 up 1167 days, 5:02 —— 系统已经运行的时长&#xff0c;格式为时:分 1 users ——当前有1个用户登录系统 load average: 0.00, 0.01, 0.05…