总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482
1. 受击反馈
用 Unity 探究 2D 游戏的打击感_技术宅也爱玩游戏的博客-CSDN博客_unity击退引言这是我毕业设计的一部分emmm……我的毕设和格斗游戏相关,而对于打击感的研究算是其中我比较在意的一环。现在临近毕业,我将毕设中开发部分的一些内容整理出来分享,希望能通过这样学习到更多的东西。打击感为何物?字面意思,“打到了的感觉”;好的打击感是易读的,包含信息充足的;它可以让玩家感受到这次的攻击奏效了、这次攻击的轻重程度、感受到这是怎样的攻击。在电子游戏中,则通过视觉和听觉呈现这些。实现方式市面上已经有很多作品供我们参考,让我自己想出一个独特的实现方式如同天方夜谭,不过我喜欢参照已有作品,去探究他们如何https://blog.csdn.net/wubaohu1314/article/details/120348767?spm=1001.2014.3001.5506
在我的程序里,我也使用了攻击碰撞盒的建立。并且是通过受击动画和击退来完成受击反馈的。最后通过协程来结束受击判定条件。当然根据大佬的教程来说,如果并没有受击动画的话,咱们可以改变动画播放速度+协程调回原来的速度和改变精灵图变白色来进行受击反馈。
敌人角色动画的创建
2.Unity2D 横版 帧动画sprite animation+动画状态机animator+丝滑连击动作_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客Unity2D 横版 帧动画sprite animation+动画状态机animator+丝滑连击动作 为什么设置了attack之后还要设置normalizedTime参数?因为如果设置一个参数的话,你点击攻击按钮会直接跳转到下一个动作。并不能完整的将攻击动作放完,那么就多添加一个。他们参数用来判断行为达到哪个阶段,并通过脚本来控制他们参数在进入因为和退出行为时都设置normalizedTime成零。这样就可以使得你点击攻击按钮动作放完了之后才到下一个动作。............https://blog.csdn.net/qq_54263076/article/details/125631721?spm=1001.2014.3001.5502
敌人状态机及其参数
如果手动验证的话,打开受伤参数Ishurt的话,你会停留在受伤状态hurt里,所以需要通过协程来自动将受伤参数调回false。
4.Unity2D 横版 帧事件+攻击判定+冲砍挑飞+更真实的打击_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客Unity2D 横版 帧事件+攻击判定+冲砍挑飞+更真实的打击1.攻击碰撞盒的创建在玩家下面新建两个空物体命名为攻击一和攻击二。然后为两个物体分别添加碰撞盒,根据帧动化来调整碰撞盒位置。并都打开触发器...............https://blog.csdn.net/qq_54263076/article/details/125654235?spm=1001.2014.3001.5502
承接上面第4节课,攻击判定触发器更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class attackTrigger : MonoBehaviour
{
private Transform player;//获取人物
private Animator ani;//获取人物动画器
private AnimatorStateInfo state;//动画状态
private GameObject em;//敌人管理器,用来对象池
public float atkItemsBack = 1;
public float atkItemsUp = 1;
public float playerSpeedInfectBack = 1;
// Start is called before the first frame update
void Start()
{
player = gameObject.transform.parent;
ani = player.GetComponent<Animator>();
em = GameObject.Find("EnemyManager");
}
// Update is called once per frame
void Update()
{
}
public void OnTriggerEnter2D(Collider2D collision)
{
//攻击到了物品或敌人产生击退
if (collision.tag == "items" || collision.tag == "enemy")
{
//获取人物与物品位置向量
Vector3 v = collision.transform.position-player.position ;
//冻结z轴
v.z = 0;
//获取横轴,速度影响击退距离
float h = Input.GetAxis("Horizontal");
//如果处于动画2,4时额外实施向上的力、速度
//挑飞
state = ani.GetCurrentAnimatorStateInfo(0);
if (state.IsName("attack2") || state.IsName("attack4"))
{
v.y += (atkItemsBack * 5*atkItemsUp);
}
collision.GetComponent<Rigidbody2D>().velocity=v* atkItemsBack+Vector3.right*h* playerSpeedInfectBack*5;
}
//攻击到了敌人
if (collision.tag == "enemy")
{
//敌人受伤
//找到被攻击到的敌人
GameObject enemyGo = collision.gameObject;
//受伤动画
enemyGo.GetComponent<Animator>().SetBool("Ishurt",true);
StartCoroutine(endHurt(enemyGo));//开启协程结束受伤动画
//伤害计算
enemyGo.GetComponent<CharacterPanel>().hurt(transform.parent.GetComponent<CharacterPanel>().Atk);
/* //在敌人管理器中找到敌人对象池,并保存信息
em.GetComponent<Pool>().Push(enemyGo);*/
}
}
IEnumerator endHurt(GameObject enemyGo)
{
yield return 0;//此处暂停,下一帧执行
enemyGo.GetComponent<Animator>().SetBool("Ishurt", false);
StopCoroutine(endHurt( enemyGo));
}
}
上面的伤害计算hurt()函数就是我下面要讲的角色的面板脚本
2.为了方便进行数值计算,为每个角色增加角色面板脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CharacterPanel : MonoBehaviour
{
public float Hpmax = 100;//最大生命
public float Hp = 100;//生命
public float Atk = 10;//攻击力
public float AtkRan = 1;//攻击浮动
public float Def = 10;//防御力
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
check();
}
//标准化检查
private void check()
{
if (Hp > Hpmax) Hp = Hpmax;//血量不超过上限
if (Hp < 0) Hp = 0;//血量不超过下限
}
public void hurt(float atk)
{
Hp -= (20*atk / (20 + Def))+ Random.Range(-AtkRan, AtkRan);
Debug.Log(atk);
}
}
只要谁受伤了就直接调用它面板里的函数hurt
3.跟随血条+延迟血条的创建
由于血条需要移动,如果用UI的话(UI必须放在画布下面且固定),需要计算坐标,很难处理。所以直接加上去血条作为角色的子体更加方便,我们需要创建一个血条空对象。然后在血条项下加入最大血条,延迟扣血血条和目前血条三个空物体,并分别赋予不同的颜色。并未这三个空物体加上sprite渲染组件放血条图片。
注意为三个精灵图设置好图层顺序,按照实际效果显示
Unity血条跟随对象_作孽就得先起床的博客-CSDN博客_unity血条跟随物体Unity血条跟随对象https://blog.csdn.net/qq_46043095/article/details/124656203?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165727842616782391833961%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165727842616782391833961&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-124656203-null-null.142%5Ev32%5Edown_rank,185%5Ev2%5Etag_show&utm_term=unity2d%E8%A1%80%E6%9D%A1%E8%B7%9F%E9%9A%8F&spm=1018.2226.3001.4187
根据上面教程, 需要注意的是要更改血条精灵图的锚点为靠左边,这样可以通过控制localScale中x来使得图片缩短。注意:作为子物体,当调整HP的大小和位置的时候,子物体用的是相对坐标,它的Scale的x永远是1;
现在为HP加上脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HPControl : MonoBehaviour
{
public float delHpSpeed = 1;//延迟血条减少速度
public float delHpTime = 1;//延时血条减少时间间隔
private CharacterPanel character ;//角色面板
private Transform hpBox;//血条图片
private Transform delhpBox;//延迟血条图片
// Start is called before the first frame update
void Start()
{
character = transform.GetComponentInParent<CharacterPanel>();
hpBox = transform.GetChild(1);//0-HPmaxBox 1-hpBox 2-delhpBox
delhpBox = transform.GetChild(2);
}
// Update is called once per frame
void FixedUpdate()
{
check();
}
//检查血量变化控制血条
private void check() {
float x = character.Hp / character.Hpmax;
if (delhpBox.localScale.x >= x)//延迟血条与血条有数差
{
hpBox.localScale = new Vector3(x, 1, 1);
//延迟血条开启协程
StartCoroutine(delHP(x));
}
}
IEnumerator delHP(float x)
{
while (delhpBox.localScale.x >= x)//直到延迟血条完成
{
Debug.Log(1);
yield return new WaitForSeconds(0.2f* delHpTime);//等待0.2*delHpTime秒
delhpBox.localScale =new Vector3(delhpBox.localScale.x-0.0001f* delHpSpeed, 1, 1);
}
}
}
其中协程是为了延迟执行需要,可以用来制作延迟扣血血条
Unity3D协程介绍 以及 使用_huang9012的博客-CSDN博客_unity协程作者ChevyRay ,2013年9月28日,snaker7译 原文地址:http://unitypatterns.com/introduction-to-coroutines/在Unity中,协程(Coroutines)的形式是我最喜欢的功能之一,几乎在所有的项目中,我都会使用它来控制运动,序列,以及对象的行为。在这个教程中,我将会说明协程是如何工作的,并且会附上一些例子来介绍https://blog.csdn.net/huang9012/article/details/38492937?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165727870416782395341488%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165727870416782395341488&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-38492937-null-null.142%5Ev32%5Edown_rank,185%5Ev2%5Etag_show&utm_term=unity%E5%8D%8F%E7%A8%8B&spm=1018.2226.3001.4187将这些组件脚本同样复制到敌人身上,注意不要忘了将面板里的敌人更新成预制体
完成了!!!
代码优化,在我后面调试中发现协程不止执行了一次,丢失了间隔执行的特性,下面是我的优化代码
思路就是引入一个新的变量deltime,if那一句中。加上可执行次数判断,协程执行完成后立刻让他变成0,在协程中,while语句执行完后再让他回1。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HPControl : MonoBehaviour
{
public float delHpSpeed = 1;//延迟血条减少速度
public float delHpTime = 1;//延时血条减少时间间隔
public float AlpHpTime = 1;//延时血条变淡速度
private CharacterPanel character ;//角色面板
private Transform hpBox;//血条图片
private Transform delhpBox;//延迟血条图片
private float delHPtime = 1;
// Start is called before the first frame update
void Start()
{
character = transform.GetComponentInParent<CharacterPanel>();
hpBox = transform.GetChild(1);//0-HPmaxBox 1-hpBox 2-delhpBox
delhpBox = transform.GetChild(2);
}
// Update is called once per frame
void FixedUpdate()
{
check();
}
//检查血量变化控制血条
private void check() {
float x = character.Hp / character.Hpmax;
hpBox.localScale = new Vector3(x, 1, 1);
if (delhpBox.localScale.x > x)
{//血条显示
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetComponent<SpriteRenderer>().color = new Color(transform.GetChild(i).GetComponent<SpriteRenderer>().color.r, transform.GetChild(i).GetComponent<SpriteRenderer>().color.g, transform.GetChild(i).GetComponent<SpriteRenderer>().color.b, 1);
}
}
if ((delhpBox.localScale.x > x)&& delHPtime == 1)//延迟血条与血条有数差
{
//延迟血条开启协程
StartCoroutine(delHP(x));
delHPtime = 0;
}
}
IEnumerator delHP(float x)
{
yield return new WaitForSeconds(0.7f);//起初停顿时间
while (delhpBox.localScale.x >= x)//直到延迟血条完成
{
yield return new WaitForSeconds(0.005f* delHpTime);//间隔0.005*delHpTime秒
delhpBox.localScale =new Vector3(delhpBox.localScale.x-0.001f* delHpSpeed, 1, 1);
}
delHPtime = 1;
}
}
协程有俩个作用,
一个是延时既有帧延时(yield return 数字/null(延时一帧) )也有时间延时,例如上面的
yield return new WaitForSeconds(0.7f);//起初停顿时间
第二个是暂停分帧/分时执行函数,使得函数不在一帧中瞬间执行完。将yield return 放在for或者while循环中,例如上面的
while (delhpBox.localScale.x >= x)//直到延迟血条完成
{yield return new WaitForSeconds(0.005f* delHpTime);//间隔0.005*delHpTime秒
delhpBox.localScale =new Vector3(delhpBox.localScale.x-0.001f* delHpSpeed, 1, 1);
}
下一篇文章来源:https://www.toymoban.com/news/detail-401141.html
7.Unity2D 横版 未受伤害时,血条缓慢变透明+伤害数值显示(浮动,大小,颜色)+协程的应用_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客Unity2D 横版 未受伤害时,血条缓慢变透明+伤害数值显示(浮动,大小,颜色)+协程的应用1.血条缓慢变淡。 我们都知道,当敌人过多的时候,血条重叠在一起会给人在视觉上造成很大的干扰,也不利于打击感。所以,有必要建立血条缓慢变透明的脚本。 2.伤害数值显示。为角色下面新建一个画布,然后在画布下面在新建txt文本。注意打开。画布的这模式为世界空间这样他就可以跟随角色进行移动。控制画布的scale调整好文本框和画布的位置。......https://blog.csdn.net/qq_54263076/article/details/125699204?spm=1001.2014.3001.5501文章来源地址https://www.toymoban.com/news/detail-401141.html
到了这里,关于6.Unity2D 横版 受击反馈+跟随血条+延时/延迟扣血+协程的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!