上一篇说完了如何控制英雄的移动,在这一篇我将补全剩余部分。
代码注释较为详细,直接贴出来吧。
public class MyPlayerHealth : MonoBehaviour
{
public Color mColor = new Vector4(1, 0, 0, 0.1f); //更换闪烁背景色
public Image mImage; //红色背景闪烁提醒受伤
public Slider mSlider; //滑块显示当前生命值
public float mFashTime = 5f; //闪烁时间
public int mCurrentHealth; //当前生命值
Animator _Animator;
int _StartHealth = 100;
bool _TsTakedamage;
bool _IsDeath;
private void Awake()
{
mCurrentHealth = _StartHealth;
_Animator = GetComponent<Animator>();
}
前面部分给所需对象赋予了初始值,需要注意的是一般应该反着来,需要那种效果,为了达到那种效果,我才声明了某个对象来实现效果
这样可以锻炼脑的逆推能力,接下来时业务逻辑部分
private void Update()
{
//受到伤害
if (_TsTakedamage)
{
mImage.color = mColor;
}
else
{
mImage.color = Color.Lerp(mImage.color, Color.clear, mFashTime * Time.deltaTime);
}
_TsTakedamage = false;
}
解释一下:IsTakedamage 判断英雄是否受到伤害,如果有临时给全屏Image控件颜色赋值,之后下一帧该bool变量自动变为false,之后对颜色插值,知道变为透明
public void TakeDamage(int amoutn)
{
if (_IsDeath)
return;
mCurrentHealth -= amoutn;
mSlider.value = mCurrentHealth; //UI Slider组件值对应英雄生命值变化
//如果英雄生命值小于0并且已经死亡,不应继续执行Death中的逻辑
if (mCurrentHealth <= 0 && !_IsDeath)
{
_IsDeath = true;
Death();
}
_TsTakedamage = true;
}
private void Death()
{
_Animator.SetTrigger("Die");
}
//此函数在"Die"动画启动时执行
public void RestartLevel()
{
// Reload the level that is currently loaded.
SceneManager.LoadScene(0);
}
上面两个函数,均是外部引用,如TakeDamage被敌人攻击脚本所引用,RestartLevel被动画事件驱动
===============================
下面是英雄射击脚本,相比较前两个脚本,虽然它代码数量多,但逻辑理解之后反而比较容易
public class MyPlayerShoot : MonoBehaviour
{
public float mTimeInterval = 0.15f; //射击时间间隔
public float mDamagePerShoot = 20f; //射击伤害点数
public float mEffectDisplayTime = 0.2f; //射击产生效果持续时间
float timer; //记时器
LineRenderer _GunLine; //射击轨道效果
Light _GunLight; //射击灯光效果
Light _FaceLight; //面部灯光效果
Ray _Ray = new Ray();
RaycastHit _Rh;
float _Range = 100; //射击最远距离
int _LayerMask; //哪些层纳入射击目标
private void Awake()
{
_GunLine = GetComponent<LineRenderer>();
_GunLight = GetComponent<Light>();
_FaceLight = transform.GetChild(0).GetComponent<Light>();
_LayerMask = LayerMask.GetMask("Shootable");
}
代码注释应该比较清晰了。接下来贴出业务逻辑部分代码
private void Update()
{
timer += Time.deltaTime;
if (Input.GetButton("Fire1") && timer >= mTimeInterval)
{
Shoot();
}
//计时器达到效果停止时间
if (timer >= mTimeInterval * mEffectDisplayTime)
{
DisableEffects(); //关闭所有射击效果
}
}
GetButton("Fire1"),表示按下或按住鼠标左键返回true;接下来贴出具体实现部分代码
private void Shoot()
{
//计时器归0,等待射击时间间隔
timer = 0f;
//开启三个射击特效
_GunLine.enabled = true;
_GunLight.enabled = true;
_FaceLight.enabled = true;
_Ray.origin = transform.position; //设置射线的初始位置
_Ray.direction = transform.forward; //设置射线的方向
_GunLine.SetPosition(0, transform.position); //轨道第一个点位英雄位置
if (Physics.Raycast(_Ray, out _Rh, _Range, _LayerMask))
{
MyEnemyHealth meh = _Rh.collider.gameObject.GetComponent<MyEnemyHealth>();
//如果击中点所属对象有MyEnemyHealth脚本返回值不为null
if (meh != null)
{
meh.TakeDamage(mDamagePerShoot); //给敌人造成伤害
}
_GunLine.SetPosition(1, _Rh.point); //此时将轨道第二个点设置为击中点
}
else
{
_GunLine.SetPosition(1, _Ray.origin + _Ray.direction * _Range); //如果没有击中点,直接沿着初始方向射出即可
}
}
private void DisableEffects()
{
//关闭三个射击特效
_GunLine.enabled = false;
_GunLight.enabled = false;
_FaceLight.enabled = false;
}
关于英雄脚本的介绍完毕,到此英雄可以简单的自由移动了。