学习游戏制作记录(视觉上的优化)
1.异常状态特效
自行制作三个粒子效果,燃烧,冰冻和麻痹
EntityFX脚本:
[Header("Ailments particles")]//三种粒子效果
[SerializeField] private ParticleSystem ignityFX;
[SerializeField] private ParticleSystem chillFX;
[SerializeField] private ParticleSystem shockFX;
private void CancelColorChange()
{
CancelInvoke();
sr.color = Color.white;
ignityFX.Stop();//取消粒子
chillFX.Stop();
shockFX.Stop();
}
public void IgniteFXfor(float _seconds)
{
ignityFX.Play();//燃烧时,打开粒子
InvokeRepeating("IgniteColorFX", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
public void ChillFXfor(float _seconds)
{
chillFX.Play();//同理
InvokeRepeating("ChillColorFX", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
public void ShockFXfor(float _seconds)
{
shockFX.Play();
InvokeRepeating("ShockColorFX", 0, .3f);
Invoke("CancelColorChange", _seconds);
}
2.命中与暴击的特效
自行制作两个命中和暴击的特效
EntityFX脚本:
[Header("Hit FX")]
[SerializeField] private GameObject hitFx;//上面的两个预制体
[SerializeField] private GameObject hitFxCritical;
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 hitRotation=new Vector3(0,0,zRotation);
GameObject hitPrefab = hitFx;
if (_Critical)//是否暴击
{
hitPrefab = hitFxCritical;
float yOffest = 0;
zRotation = Random.Range(-45, 45);
if (GetComponent<Entity>().facingDir == -1)
yOffest = 180;
hitRotation = new Vector3(0, yOffest, zRotation);//暴击则设置新的偏移量
}
GameObject newhit = Instantiate(hitPrefab, _target.position+new Vector3(xPosition,yPosition), Quaternion.identity);//产生预制体
newhit.transform.Rotate(hitRotation);
Destroy(newhit, .5f);
}
CharactorState脚本:
public virtual void DoDamage(CharactorState _target)
{
bool criticalStrike = false;//是否暴击
if(TargetCanAvoidAttack(_target))
{
return;
}
_target.GetComponent<Entity>().SetupKnocbackDir(transform);
int totalDamage =damage.GetValue()+strength.GetValue();
if(CanCrit())
{
totalDamage = CaculateCritDamage(totalDamage);
criticalStrike = true;//暴击
}
entityFX.CreateHitFX(_target.transform,criticalStrike);//产生击中特效
totalDamage =TargetCheckArmor(_target,totalDamage);
_target.TakeDamage(totalDamage);
DoMagicDamage(_target);
}
3.剑的灰尘特效
自行创建一个灰尘特效
EntityFX脚本:
[SerializeField] private ParticleSystem dustFX;
public void PlayDustFX()//播放灰尘
{
if(dustFX != null)
{
dustFX.Play();
}
}
PlayerCatchSwordState脚本:
public override void Enter()
{
base.Enter();
sword = _Player.sword;
_Player.entityFX.PlayDustFX();//玩家接剑时播放灰尘特效
if (_Player.transform.position.x < sword.transform.position.x && _Player.facingDir == -1)
_Player.Flip();
else if (_Player.transform.position.x > sword.transform.position.x && _Player.facingDir == 1)
_Player.Flip();
rb.velocity = new Vector2(_Player.SwordReturnImpact * -_Player.facingDir, rb.velocity.y);
}
Sword_Skill_Control脚本:
为剑的预制体添加一个灰尘的子对象
private void StuckInto(Collider2D collision)
{
if(pierceAmount>0&&collision.GetComponent<Enemy>() != null)
{
pierceAmount--;
return;
}
if(isSpinning)
{
StopWhenSpinning();
return;
}
canRotate = false;
cd.enabled = false;
rb.isKinematic = true;
rb.constraints = RigidbodyConstraints2D.FreezeAll;
GetComponentInChildren<ParticleSystem>().Play();//当剑插入到墙或地面时播放灰尘特效
if (isBouncing && enemyTarget.Count > 0)
return;
transform.parent = collision.transform;
anim.SetBool("rotation", false);
}
4.实现残影特效
创建一个残影的预制体
AfterImageFX脚本:
private SpriteRenderer sr;
private float colorLooseRate;
public void SetupAfterImage(float _colorLooseRate,Sprite _spriteImage)
{
sr = GetComponent<SpriteRenderer>();
sr.sprite = _spriteImage;
colorLooseRate = _colorLooseRate;
}
void Update()
{
float alpha=sr.color.a-colorLooseRate*Time.deltaTime;//实现残影的效果
sr.color=new Color(sr.color.r,sr.color.g,sr.color.b,alpha);
if(sr.color.a<=0)
{
Destroy(gameObject);
}
}
EntityFX脚本:
[Header("After Image FX")]
[SerializeField] private float afterImageCooldown;//残影的冷却时间
[SerializeField] private GameObject afterImagePrefab;//预制体
[SerializeField] private float colorLooseRate;//消失速度
private float afterImageTimer;//计时器
private void Update()
{
afterImageTimer -= Time.deltaTime;
}
public void CreateAfterImage()
{
if(afterImageTimer<0)
{
afterImageTimer = afterImageCooldown;
GameObject newAfterImage = Instantiate(afterImagePrefab, transform.position, transform.rotation);
newAfterImage.GetComponent<AfterImageFX>().SetupAfterImage(colorLooseRate, sr.sprite);//设置
}
}
PlayerDashState脚本:
public override void Update()
{
base.Update();
_Player.SetVelocity(_Player.dashDir * _Player.dashSpeed, 0);
if (!_Player.isGroundDetected() && _Player.isWallDetected())
{
_PlayerStateMachine.ChangeState(_Player.wallSlideState);
}
if (stateTimer < 0)
{
_PlayerStateMachine.ChangeState(_Player.idleState);
}
_Player.entityFX.CreateAfterImage();//调用残影函数
}