【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节添加了暴击的攻击特效
EntityFX.cs
添加部分!!!
功能分析
1. 主要功能
CreateHitFX
方法:- 根据攻击是否为暴击(
_critical
),选择不同的特效预制体。 - 生成击中特效时,随机调整特效的旋转角度和生成位置,使得特效看起来更加自然和多样化。
- 在生成一段时间后销毁特效,避免游戏中出现过多的无用对象占用内存。
- 根据攻击是否为暴击(
2. 功能实现细节
暴击特效
- 选择暴击特效:
- 如果是暴击(
_critical == true
),特效预制体切换为criticalHitFx
。
- 如果是暴击(
- 额外旋转调整:
- 暴击特效的 Z轴旋转角度范围缩小到 -45° 到 45°,使暴击的特效看起来更加精准。
- 如果攻击者的朝向(
facingDir
)为 -1(朝左),则设置 Y轴旋转角度为 180°,使特效方向与角色朝向保持一致。 - 最终旋转向量:
hitFXRotation = new Vector3(0, yRotation, zRotation)
。
特效生成
- 生成特效实例:
- 调用
Instantiate
在目标位置生成特效实例,位置为_target.position + 随机偏移
,使每次击中特效的位置稍有不同。
- 调用
- 设置旋转角度:
- 调整生成的特效的旋转,使特效展示出多样化的方向。
- 销毁特效:
- 调用
Destroy
在 0.5 秒后销毁特效对象,避免长期占用内存。
- 调用
[Header("攻击特效")]//Hit FX
[SerializeField] private GameObject hitFX;
[SerializeField] private GameObject criticalHitFx;
public void CreateHitFX(Transform _target,bool _critical)//攻击特效
{
float zRotation = Random.Range(-90, 90);
float xPosition = Random.Range(-.5f, .5f);
float yPosition = Random.Range(-.5f, .5f);
Vector3 hitFXRotation = new Vector3(0,0,zRotation);//生成的旋转向量
GameObject hitPrefab = hitFX;
if(_critical)//如果暴击
{
hitPrefab = criticalHitFx;
float yRotation = 0;
zRotation = Random.Range(-45, 45);
if (GetComponent<Entity>().facingDir == -1)//如果玩家朝向左边
yRotation = 180;
hitFXRotation = new Vector3(0 , yRotation,zRotation);
}
GameObject newHitFX = Instantiate( hitPrefab , _target.position + new Vector3(xPosition,yPosition), Quaternion.identity);//生成特效实例
newHitFX.transform.Rotate(hitFXRotation);//设置旋转角度
Destroy(newHitFX,.5f);
}
完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityFX : MonoBehaviour
{
private SpriteRenderer sr;
[Header("Flash FX")]
[SerializeField] private float flashDuration;
[SerializeField] private Material hitMat;
private Material originalMat;
[Header("异常状态颜色")]//Ailment colors
[SerializeField] private Color[] chillColor;
[SerializeField] private Color[] igniteColor;
[SerializeField] private Color[] shockColor;
[Header("异常状态粒子")]//Ailment particles
[SerializeField] private ParticleSystem igniteFx;
[SerializeField] private ParticleSystem chillFx;
[SerializeField] private ParticleSystem shockFx;
[Header("攻击特效")]//Hit FX
[SerializeField] private GameObject hitFX;
[SerializeField] private GameObject criticalHitFx;
private void Start()
{
sr = GetComponentInChildren <SpriteRenderer>();//这行代码使用 GetComponentInChildren 方法查找并获取当前游戏对象或其子对象中的 SpriteRenderer 组件,并将其赋值给 sr 变量。
originalMat = sr.material;
}
public void MakeTransprent(bool _transparent)//攻击命中时候的透明特效
{
if (_transparent)
sr.color = Color.clear;
else
sr.color = Color.white;
}
private IEnumerator FlashFX()//定义了一个私有的协程 FlashFX,用于在一段时间内改变 SpriteRenderer 的材质,然后恢复原始材质。
{
sr.material = hitMat;
Color currentColor = sr.color;//保存最开始的颜色,闪光之后变回去
sr.color = Color.white;
yield return new WaitForSeconds(flashDuration);
sr.color = currentColor;
sr.material = originalMat;
}
//P59,骷髅战士的血条闪烁
private void RedColorBlink()
{
if(sr.color !=Color.white)
sr.color = Color.white;
else
{
sr.color = Color.red;
}
}
private void CancelColorChange()
{
CancelInvoke();//调用 CancelInvoke 方法取消所有与当前游戏对象关联的 Invoke 调用。
sr.color = Color.white;
igniteFx.Stop();
chillFx.Stop();
shockFx.Stop();
}
//10月30日
//三个状态的携程
public void ShockFxFor(float _seconds)
{
shockFx.Play();
InvokeRepeating("ShockColorFx", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
public void IgniteFxFor(float _seconds)
{
igniteFx.Play();
InvokeRepeating("IgniteColorFx", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
public void ChillFxFor(float _seconds)
{
chillFx.Play();
InvokeRepeating("ChillColorFx", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
private void ShockColorFx()
{
if (sr.color != shockColor[0])
sr.color = shockColor[0];
else
{
sr.color = shockColor[1];
}
}
private void IgniteColorFx()//燃烧状态颜色
{
if (sr.color != igniteColor[0])
sr.color = igniteColor[0];
else
{
sr.color = igniteColor[1];
}
}
private void ChillColorFx()//燃烧状态颜色
{
if (sr.color != chillColor[0])
sr.color = chillColor[0];
else
{
sr.color = chillColor[1];
}
}
public void CreateHitFX(Transform _target,bool _critical)//攻击特效
{
float zRotation = Random.Range(-90, 90);
float xPosition = Random.Range(-.5f, .5f);
float yPosition = Random.Range(-.5f, .5f);
Vector3 hitFXRotation = new Vector3(0,0,zRotation);
GameObject hitPrefab = hitFX;
if(_critical)
{
hitPrefab = criticalHitFx;
float yRotation = 0;
zRotation = Random.Range(-45, 45);
if (GetComponent<Entity>().facingDir == -1)//如果玩家朝向左边
yRotation = 180;
hitFXRotation = new Vector3(0 , yRotation,zRotation);
}
GameObject newHitFX = Instantiate( hitPrefab , _target.position + new Vector3(xPosition,yPosition), Quaternion.identity);
newHitFX.transform.Rotate(hitFXRotation);
Destroy(newHitFX,.5f);
}
}
CharacterStats.cs
修改部分!!!
创建攻击的特效
bool criticalStrike = false;
fx.CreateHitFX(_targetStats.transform,criticalStrike);//创建击中特效
public virtual void DoDamage(CharacterStats _targetStats)//只是一次物理攻击
{
bool criticalStrike = false;
if (TargetCanAvoidAttack(_targetStats))
return;
_targetStats.GetComponent<Entity>().SetupKnockbackDir(transform);//设置击退方向
int totalDamage = damage.GetValue() + strength.GetValue();
if (Cancrit())
{
totalDamage = CalculateCriticalDamage(totalDamage);
criticalStrike = true;
}
fx.CreateHitFX(_targetStats.transform,criticalStrike);//创建击中特效
totalDamage = CheckTargetArmor(_targetStats, totalDamage);
_targetStats.TakeDamage(totalDamage);//把造成的给到继承CharacterStats的类
DoMagicDamage(_targetStats);//如果普通攻击不想要魔法伤害移除
}
标签:特效,P169,Hit,暴击,color,sr,void,private,SerializeField
From: https://blog.csdn.net/suzh1qian/article/details/144267051