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.mzph.cn/news/690980.shtml

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

相关文章

Netty Review - NIO空轮询及Netty的解决方案源码分析

文章目录 Pre问题说明NIO CodeNetty是如何解决的&#xff1f;源码分析入口源码分析selectCntselectRebuildSelector Pre Netty Review - ServerBootstrap源码解析 Netty Review - NioServerSocketChannel源码分析 Netty Review - 服务端channel注册流程源码解析 问题说明 N…

专题十一、指针和数组

指针和数组 1. 指针的算术运算1.1 指针加上整数1.2 指针减去整数1.3 两个指针相减1.4 指针比较1.5 指向复合常量的指针 2. 指针用于数组处理3. 用数组名作为指针3.1 数组型实际参数&#xff08;改进版&#xff09;3.2 用指针作为数组名 4. 指针和多维数组4.1 处理多维数组的元素…

log4j2的使用

基础用法 1. pom文件导入依赖 junit用来做测试 <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.5</version></dependency><dependency><groupId>org.…

国际网络专线多少钱一年

国际网络专线作为企业扩展业务的重要通信渠道&#xff0c;已经成为许多企业不可或缺的选择。然而&#xff0c;对 于许多企业来说&#xff0c;选择一条稳定、高质量的国际网络专线&#xff0c;并不是一件容易的事情。那么&#xff0c;国际 网络专线到底多少钱一年呢&#xff1f;…

BGP 邻居建立

拓扑图 配置 BGP进程号及为AS号 使用环回口建立BGP邻居关系时&#xff0c;需要指定更新源地址 EBGP在使用环回口建立邻居关系时&#xff0c;需配置EBGP多跳&#xff0c;环回口路由可达 EBGP的路由器存在IBGP邻居时&#xff0c;需要配置next-hop-local&#xff0c;保证下一跳…

适合tiktok运营的云手机需要满足什么条件?

TikTok作为一款全球热门的社交媒体平台&#xff0c;具有无限的市场潜力。然而&#xff0c;卖家在运营过程中常常会面临到视频0播、账号被降权、限流等问题&#xff0c;甚至可能因为多人同时使用一个IP而导致封号的风险。为了规避这些问题&#xff0c;越来越多的卖家将目光投向了…

C语言—指针(2)

回原点(......?)当我没讲&#xff0c;好难 1. 编写函数,要求用指针做形参&#xff0c;实现将二维数组(行列相同)的进行转置&#xff08;行列数据互换&#xff09;&#xff1a; ...不会写 /*1. 编写函数,要求用指针做形参&#xff0c;实现将二维数组(行列相同)的进行转置&a…

看小姐姐的效果棒极了,写了一个工具,逐帧解析视频转成图片,有没有带上商业思维的小伙伴一起研究下

一个突然的想法&#xff0c;促成了这个项目雏形。 原理是&#xff1a; 上传一个视频&#xff0c;自动将视频每一帧保存成图片 然后前端访问 就能实现如图效果 后端是python/flask 数据库mysql 前端uniapp 项目演示&#xff1a; xt.iiar.cn 后端代码如下&#xff1a; #学习…

【C深剖】数组名的细节

本系列博客为个人刷题思路分享&#xff0c;有需要借鉴即可。 引言&#xff1a;我想我说的这个数组名细节可能很多人并没有留意&#xff0c;现在先来C设计者这样设计也很合理。 就是数组名本质上是一个指针&#xff0c;但是这个指针的内容也就是说指向的空间是固定的&#xff0c…

unplugin-vue-components解决命名冲突

我们在vue项目中通常会利用unplugin-vue-components插件进行自定义组件的自动引入 注&#xff1a;如果不知道怎么配置unplugin-vue-components插件&#xff0c;欢迎看我整理的这篇&#xff1a; vue3项目配置按需自动引入自定义组件unplugin-vue-components 当出现同名文件时&a…

先进电机技术——感应电机与同步电机

一、感应电机 感应电机&#xff08;Induction Motor&#xff09;是一种广泛应用的交流电动机&#xff0c;其工作原理基于电磁感应定律。在感应电机中&#xff0c;定子绕组连接到电源后会因通入的交流电而产生一个旋转磁场。这个磁场在空间中是连续变化并以恒定的速度&#xff…

【医学大模型】Text2MDT :从医学指南中,构建医学决策树

Text2MDT &#xff1a;从医学指南中&#xff0c;构建医学决策树 提出背景Text2MDT 逻辑Text2MDT 实现框架管道化框架端到端框架 效果 提出背景 论文&#xff1a;https://arxiv.org/pdf/2401.02034.pdf 代码&#xff1a;https://github.com/michael-wzhu/text2dt 假设我们有一…

算法-矩阵置零

1、题目来源 73. 矩阵置零 - 力扣&#xff08;LeetCode&#xff09; 2、题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1…

机器学习---规则学习(一阶规则学习、归纳逻辑程序设计)

1. 一阶规则学习 “一阶”的目的&#xff1a;描述一类物体的性质、相互关系&#xff0c;比如利用一阶关系来挑“ 更好的”瓜&#xff0c;但实际应用 中很难量化颜色、 …、敲声的属性值。一般情况下可以省略全称量词。 命题逻辑&#xff1a;属性-值数据 色泽程度&#xff1a…

CSS:BFC

BFC&#xff0c;Block Formatting Context&#xff0c;块级格式化上下文&#xff0c;是一个独立的渲染区域或隔离的独立容器&#xff0c;它决定了其子元素如何布局&#xff0c;并且与这个区域外部的元素无关。 形成 BFC 的条件 float 的值不为 none&#xff08;left、right&a…

爬虫入门一

文章目录 一、什么是爬虫&#xff1f;二、爬虫基本流程三、requests模块介绍四、requests模块发送Get请求五、Get请求携带参数六、携带请求头七、发送post请求八、携带cookie方式一&#xff1a;放在请求头中方式二&#xff1a;放在cookie参数中 九、post请求携带参数十、模拟登…

HTTPS网络通信协议基础

目录 前言&#xff1a; 1.HTTPS协议理论 1.1协议概念 1.2加密 2.两类加密 2.1对称加密 2.2非对称加密 3.引入“证书” 3.1证书概念 3.2数据证书内容 3.3数据签名 4.总结 前言&#xff1a; 了解完HTTP协议后&#xff0c;HTTPS协议是HTTP协议的升级加强版&#xff0c…

设计模式二:代理模式

1、什么是动态代理 可能很多小伙伴首次接触动态代理这个名词的时候&#xff0c;或者是在面试过程中被问到动态代理的时候&#xff0c;不能很好的描述出来&#xff0c;动态代理到底是个什么高大上的技术。不方&#xff0c;其实动态代理的使用非常广泛&#xff0c;例如我们平常使…

unity 使用VS Code 开发,VS Code配置注意事项

vscode 对应的插件&#xff08;unity开发&#xff09; 插件&#xff1a;.Net Install Tool,c#,c# Dev Kit,IntelliCode For C# Dev Kit,Unity,Unity Code Snippets 本人现在是用了这些插件 unity需要安装Visual Studio Editor 1、.Net Install Tool 设置 需要在设置里面配置…

jvm gc日志拿取与分析思路

前言 参考文章:Java中9种常见的CMS GC问题分析与解决 - 美团技术团队 排查过程 进入容器里 生产应用是跑在docker上的&#xff0c;所以需要先进入到应用里面去&#xff0c;步骤如下 1. docker ps 找到对应的应用id&#xff0c;比如 zxc 2. 进入容器内部 docker exec -it 7690…