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

个人备案网站做app免费网站建站w

个人备案网站做app,免费网站建站w,茶叶企业网站建设,东莞网络推广服务平台Unity开发2D类银河恶魔城游戏学习笔记 Unity教程(零)Unity和VS的使用相关内容 Unity教程(一)开始学习状态机 Unity教程(二)角色移动的实现 Unity教程(三)角色跳跃的实现 Unity教程&…

Unity开发2D类银河恶魔城游戏学习笔记

Unity教程(零)Unity和VS的使用相关内容
Unity教程(一)开始学习状态机
Unity教程(二)角色移动的实现
Unity教程(三)角色跳跃的实现
Unity教程(四)碰撞检测
Unity教程(五)角色冲刺的实现
Unity教程(六)角色滑墙的实现
Unity教程(七)角色蹬墙跳的实现
Unity教程(八)角色攻击的基本实现
Unity教程(九)角色攻击的改进

Unity教程(十)Tile Palette搭建平台关卡
Unity教程(十一)相机
Unity教程(十二)视差背景

Unity教程(十三)敌人状态机
Unity教程(十四)敌人空闲和移动的实现
Unity教程(十五)敌人战斗状态的实现
Unity教程(十六)敌人攻击状态的实现
Unity教程(十七)敌人战斗状态的完善

Unity教程(十八)战斗系统 攻击逻辑
Unity教程(十九)战斗系统 受击反馈
Unity教程(二十)战斗系统 角色反击


如果你更习惯用知乎
Unity开发2D类银河恶魔城游戏学习笔记目录


文章目录

  • Unity开发2D类银河恶魔城游戏学习笔记
  • 前言
  • 一、概述
  • 二、闪烁特效的实现
    • (1)创建闪烁特效材质
    • (2)实现闪烁特效脚本
  • 三、击退效果的实现
  • 四、攻击方向问题的修复
  • 总结 完整代码
    • EntityFX.cs
    • Entity.cs
    • PlayerPrimaryAttackState.cs


前言

本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记,如有错误,欢迎指正。

本节实现战斗系统的受击反馈部分。

Udemy课程地址

对应视频:
On Hit Fx
On Hit Impact
Attack’s direction hot fix


一、概述

本节我们实现角色的受击反馈,包括闪烁特效,击退效果两部分。
为实现特效,创建了实体特效组件,用于存放作用于实体的特效。闪烁特效用两种材质交替实现。击退效果设置受击角色速度实现。
除此之外,还修复了学习过程中发现的攻击方向bug。
在这里插入图片描述

二、闪烁特效的实现

在开始之前我们先整理一下脚本文件,把相应脚本放入创建的文件夹中,文件整理大致如下:
在这里插入图片描述
在这里插入图片描述

(1)创建闪烁特效材质

首先我们在Materials文件夹中创建闪烁特效FlashFXMaterial。
在Project面板中
右键->Create->Material->重命名为FlashFXMaterial
在这里插入图片描述

在这里插入图片描述
Shader选择GUI->Text Shader,Text Color选择白色
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更换Playerd Animator的材质看一下效果
在这里插入图片描述
在这里插入图片描述
将原始材质与这个纯白的来回交替就可以产生闪烁的特效。

(2)实现闪烁特效脚本

首先我们创建一个特效组件EntityFX,用来实现实体的特效。

特效由更换精灵的材质实现,即要调用接口,修改对应实体下Animator中SpriteRenderer组件的Material属性。
首先要在EntityFX中获取相应SpriteRenderer组件,并设置两个变量分别存储原始材质和受击后的材质。还要创建变量flashDuration,定义受击后闪烁的时长。

//EntityFX:实体特效
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EntityFX : MonoBehaviour
{private SpriteRenderer sr;[Header("Flash FX")][SerializeField] private Material hitMat;private Material originalMat;[SerializeField] private float flashDuration;private void Start(){sr = GetComponentInChildren<SpriteRenderer>();originalMat = sr.material;}
}

接着使用协程实现材质每隔一小段时间更替一次材质。

    //闪烁特性private IEnumerator FlashFX(){sr.material = hitMat;yield return new WaitForSeconds(flashDuration);sr.material = originalMat;}

在Entity中创建特效组件EntityFX并赋值。
    #region 组件public EntityFX fx {  get; private set; }public Rigidbody2D rb { get; private set; }public Animator anim { get; private set; }#endregion//获取组件protected virtual void Start(){fx= GetComponent<EntityFX>();rb= GetComponent<Rigidbody2D>();anim= GetComponentInChildren<Animator>();}

在Entity的Damage函数中调用闪烁特效。

    public virtual void Damage(){fx.StartCoroutine("FlashFX");Debug.Log(gameObject.name + " was damaged");}

将EntityFX拖到Player上作为组件,拖入闪烁特效作为受击材质,并给闪烁持续时间赋一个合适的值。
在这里插入图片描述
骷髅小怪Enemy_Skeleton同理,最终效果如下:
在这里插入图片描述

三、击退效果的实现

击退效果我们依然用协程实现。在实体受到攻击时,设置实体后退速度,等待一小段时间后恢复原来速度设置。

在Entity中创建击退效果相关的变量,分别为击退方向,是否被击退,击退持续的时间。

    [Header("Knockback Info")][SerializeField] protected Vector2 knockbackDirection;[SerializeField] protected float knockbackDuration;protected bool isKnocked;

创建一个协程HitKnockback设置击退速度。一个实体受到攻击后,后退方向与它面向的方向相反。这里存在一个问题,在玩家从背后攻击骷髅时,一般骷髅会在检测后迅速转身,但个别时候会发生它没有转身就受到攻击的情况,这时骷髅会向它朝向的方向跌,这个问题本节暂不解决。

isKnocked用来记录实体是否处于被击退的状态,在击退效果持续期间我们需要让其他涉及设置速度的操作都不生效,在击退结束后再恢复原来状态里的速度设置。

    protected virtual IEnumerator HitKnockback(){isKnocked = true;rb.velocity = new Vector2(knockbackDirection.x * -facingDir, knockbackDirection.y);yield return new WaitForSeconds(knockbackDuration);isKnocked= false;}

在速度设置和速度置零函数中添加一个判定,当处于击退状态时直接return,不执行后面设置速度的部分,直到击退结束。

    #region 速度设置//速度置零public void ZeroVelocity(){if (isKnocked)return;rb.velocity = new Vector2(0, 0);}//设置速度public void SetVelocity(float _xVelocity, float _yVelocity){if (isKnocked)return;rb.velocity = new Vector2(_xVelocity, _yVelocity);FlipController(_xVelocity);}#endregion

在Damage函数中调用击退效果。

    public virtual void Damage(){fx.StartCoroutine("FlashFX");StartCoroutine("HitKnockback");Debug.Log(gameObject.name + " was damaged");}

在这里插入图片描述
骷髅受到攻击后直接飘出去了。加大重力就可以解决这一问题。但需要注意加大重力后,骷髅的移速也会变迟缓,可以根据需要设定。

在这里插入图片描述

在这里插入图片描述

四、攻击方向问题的修复

在学习过程中,发现了一个问题,在个别先向左后向右跑的时候,角色面向右进行攻击时,攻击方向却是向左。
在这里插入图片描述
问题出在下图位置。在基本攻击状态PlayerPrimaryAttackState中,我们原本设置的是攻击时如果有输入,攻击方向为输入方向,但在进入攻击状态时xInput并不是最新的。
在这里插入图片描述
xInput的定义在状态基类PlayerState中,它的赋值在Update函数中进行,PlayerPrimaryAttackState继承自状态基类,所以每次进入攻击状态获取的xInput都是上次攻击Update中获取的。
在这里插入图片描述
教程里的改法是在进入状态时,xInput赋0。我选择了在进入时,重新获取一次xInput。

    //进入public override void Enter(){base.Enter();xInput = Input.GetAxisRaw("Horizontal");//攻击方向问题教程改法//xInput = 0;if (comboCounter > 2 || Time.time > lastTimeAttacked + comboWindow)comboCounter = 0;player.anim.SetInteger("comboCounter",comboCounter);float attackDir = player.facingDir;if (xInput != 0)attackDir = xInput;player.SetVelocity(player.attackMovement[comboCounter].x * attackDir, player.attackMovement[comboCounter].y);stateTimer = 0.1f;}

总结 完整代码

EntityFX.cs

实体特效组件。实现闪烁特效。

//EntityFX:实体特效
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EntityFX : MonoBehaviour
{private SpriteRenderer sr;[Header("Flash FX")][SerializeField] private Material hitMat;private Material originalMat;[SerializeField] private float flashDuration;private void Start(){sr = GetComponentInChildren<SpriteRenderer>();originalMat = sr.material;}//闪烁特效private IEnumerator FlashFX(){sr.material = hitMat;yield return new WaitForSeconds(flashDuration);sr.material = originalMat;}
}

Entity.cs

获取实体特效组件,调用闪烁特效。实现并调用击退效果,修改速度设置。

//Entity:实体类
using System.Collections;
using System.Collections.Generic;
using Unity.IO.LowLevel.Unsafe;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;public class Entity : MonoBehaviour
{[Header("Knockback Info")][SerializeField] protected Vector2 knockbackDirection;[SerializeField] protected float knockbackDuration;protected bool isKnocked;[Header("Flip Info")]protected bool facingRight = true;public int facingDir { get; private set; } = 1;[Header("Collision Info")]public Transform attackCheck;public float attackCheckRadius;[SerializeField] protected Transform groundCheck;[SerializeField] protected float groundCheckDistance;[SerializeField] protected Transform wallCheck;[SerializeField] protected float wallCheckDistance;[SerializeField] protected LayerMask whatIsGround;#region 组件public EntityFX fx {  get; private set; }public Rigidbody2D rb { get; private set; }public Animator anim { get; private set; }#endregionprotected virtual void Awake(){}//获取组件protected virtual void Start(){fx= GetComponent<EntityFX>();rb= GetComponent<Rigidbody2D>();anim= GetComponentInChildren<Animator>();}// 更新protected virtual void Update(){}public virtual void Damage(){fx.StartCoroutine("FlashFX");StartCoroutine("HitKnockback");Debug.Log(gameObject.name + " was damaged");}protected virtual IEnumerator HitKnockback(){isKnocked = true;rb.velocity = new Vector2(knockbackDirection.x * -facingDir, knockbackDirection.y);yield return new WaitForSeconds(knockbackDuration);isKnocked= false;}#region 速度设置//速度置零public void ZeroVelocity(){if (isKnocked)return;rb.velocity = new Vector2(0, 0);}//设置速度public void SetVelocity(float _xVelocity, float _yVelocity){if (isKnocked)return;rb.velocity = new Vector2(_xVelocity, _yVelocity);FlipController(_xVelocity);}#endregion#region 翻转//翻转实现public virtual void Flip(){facingDir = -1 * facingDir;facingRight = !facingRight;transform.Rotate(0, 180, 0);}//翻转控制public virtual void FlipController(float _x){if (_x > 0 && !facingRight)Flip();else if (_x < 0 && facingRight)Flip();}#endregion#region 碰撞//碰撞检测public virtual bool isGroundDetected() => Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);public virtual bool isWallDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);//绘制碰撞检测protected virtual void OnDrawGizmos(){Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y));Gizmos.DrawWireSphere(attackCheck.position, attackCheckRadius);}#endregion
}

PlayerPrimaryAttackState.cs

修复攻击方向问题。

//PlayerPrimaryAttackState:基本攻击状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerPrimaryAttackState : PlayerState
{private int comboCounter;private float lastTimeAttacked;private float comboWindow = 2;public PlayerPrimaryAttackState(PlayerStateMachine _stateMachine, Player _player, string _animBoolName) : base(_stateMachine, _player, _animBoolName){}//进入public override void Enter(){base.Enter();xInput = Input.GetAxisRaw("Horizontal");//攻击方向问题教程改法//xInput = 0;if (comboCounter > 2 || Time.time > lastTimeAttacked + comboWindow)comboCounter = 0;player.anim.SetInteger("comboCounter",comboCounter);float attackDir = player.facingDir;if (xInput != 0)attackDir = xInput;player.SetVelocity(player.attackMovement[comboCounter].x * attackDir, player.attackMovement[comboCounter].y);stateTimer = 0.1f;}//退出public override void Exit(){base.Exit();player.StartCoroutine("BusyFor", 0.15f);comboCounter++;lastTimeAttacked = Time.time;}// 更新public override void Update(){base.Update();if (stateTimer < 0)player.ZeroVelocity();if(triggerCalled)stateMachine.ChangeState(player.idleState);}
}
http://www.yayakq.cn/news/249596/

相关文章:

  • 深圳那个网站建设制作微信小程序要钱吗
  • 网站外网访问怎么做路由器端口映射网站建设微信营销
  • 个人网站站长wordpress图片显示缩略图
  • 网站ftp上传到空间个体户做盈利网站
  • 百度主机做视频网站怎么样如何做市场推广方案
  • 淘宝联盟做的好的网站wordpress下载主题错误
  • 网站设计论文的摘要做阿里巴巴还是做网站好
  • 网站服务器 重启网站素材图标
  • 黄山网站建设哪家强企业进行网站建设的重要意义
  • 包头市住房和城乡建设局网站微信公众号二维码
  • 企业如何网站建设wordpress关闭更新
  • 做网站需要美工吗wordpress 账号插件
  • 优购物官方网站app网站建设礻金手指下拉十二
  • easyui 做的网站wordpress minty
  • 经营网站备案信息大连网站开发
  • 一个好的网站内页大概做多少品牌塑造
  • 艺术公司网站定制中心织梦5.5模版安装上去为什么打开网站图片不能显示教程
  • 景德镇网站建设哪家口碑好软文推送
  • asp.net+h5网站开发wordpress头像多说
  • 网站空间和主机网站开发app
  • 长沙 外贸网站建设公司排名版面设计软件
  • 建网站多少钱 万户司法公开网站建设情况汇报
  • 做网站用 jsp还是asp一个网站如何做桌面快捷链接
  • 济南网站建设yeptask安卓搭建wordpress
  • 高端网站设计制作的兰州网站建设和推广
  • 天津西青网站建设公司音乐网站制作教程
  • 哪一个网站做专栏作家好点ui设计和交互设计培训
  • 南阳网站建设哪家好秦皇岛网站推广报价
  • 女性健康网站源码网页首页动态设计
  • 郑州网站建设哪家强沧州市做网站价格