SurvivalShooter学习笔记(七.玩家射击)
玩家射击:(这个脚本放在玩家的空子物体上,这个位置为枪口位置)
点击鼠标,玩家射击;
射击枪口发光,射击通过射线,方向有激光效果;(关于射线不明白可以参考Unity射线相关)
射击有射击音效
射击有每发伤害,有CD 间隔时间,有射程
敌人射击脚本如下:
1.变量:
射击配置参数:
public int damagePerShot = 20; // 每枪伤害 public float timeBetweenBullets = 0.15f; // 普攻CD时间 public float range = 100f; // 射程
float timer; // 射击计时器,计时上次射击到现在时间 Ray shootRay = new Ray(); // 枪口向前的射线 RaycastHit shootHit; // 射线碰撞 int shootableMask; // 可射击的层:所有可射击的物体都应在这个层
怪物敌人可被玩家的枪射击,所以设置这个层
组件:
枪口粒子特效的Looping和PlayOnAwake当然不勾选,每次射击手动播放
枪口AudioSource拖入枪击声音,Looping和PlayOnAwake当然不勾选,每次射击手动播放
LineRenderer默认禁用,需要时手动启用:设置不同效果通过拖入材质,一般使用Unlit/Color普通Shader
Light默认禁用,需要时手动启用,为射击时枪口向地面和脸的点光源
ParticleSystem gunParticles; // 枪口粒子特效 LineRenderer gunLine; // 激光线 AudioSource gunAudio; // 枪上音效播放器 Light gunLight; // 点光 public Light faceLight; // Duh
float effectsDisplayTime = 0.2f; // 特效显示时间与普攻CD时间的比例
void Awake ()
{
// 设置射线射“Shootable”这个层
shootableMask = LayerMask.GetMask ("Shootable");
gunParticles = GetComponent<ParticleSystem> ();
gunLine = GetComponent <LineRenderer> ();
gunAudio = GetComponent<AudioSource> ();
gunLight = GetComponent<Light> ();
//faceLight = GetComponentInChildren<Light> ();
}
这里: 时间超过 射击普攻特效要相对普攻CD要显示的时间 要停止特效显示,特效显示时间要根据射击间隔时间乘以百分比,成功避免了普攻间隔端引起的:下次普攻把上次的特效给关了的情况,这样处理后,每次关都是关本次射击的特效。
void Update () { // 计时器计时从上次攻击到现在时间 timer += Time.deltaTime; //1.鼠标左键按 2.攻击已经CD 3.没有暂停 if(Input.GetButton ("Fire1") && timer >= timeBetweenBullets && Time.timeScale != 0) { Shoot (); //射击 } // 时间超过 射击普攻特效要相对普攻CD要显示的时间 if(timer >= timeBetweenBullets * effectsDisplayTime) { //禁用特效 DisableEffects (); } }
4.禁用特效:
public void DisableEffects ()
{
gunLine.enabled = false;
faceLight.enabled = false;
gunLight.enabled = false;
}
void Shoot () { //重置攻击计时器时间,重新开始计时 timer = 0f; // 播放攻击音效 gunAudio.Play (); // 显示光效 gunLight.enabled = true; faceLight.enabled = true; // 播放枪口粒子特效(避免上次播放未结束,先停止再播放) gunParticles.Stop (); gunParticles.Play (); // 启用LinRenderer,起始点设为枪口(这个脚本挂在枪口,所以this就是枪口) gunLine.enabled = true; gunLine.SetPosition (0, transform.position); // 设置射击射线,从枪口向前射 shootRay.origin = transform.position; shootRay.direction = transform.forward; // 射到了可射到的物体 if(Physics.Raycast (shootRay, out shootHit, range, shootableMask)) { // 尝试获取敌人生命脚本 EnemyHealth enemyHealth = shootHit.collider.GetComponent <EnemyHealth> (); if(enemyHealth != null) { // 敌人承受伤害,传入伤害值,和受击点用于播放受击特效 enemyHealth.TakeDamage (damagePerShot, shootHit.point); } //设置LineRnderer的终点位置为受击点,即射线击中的点 gunLine.SetPosition (1, shootHit.point); } // 没射到可射到的物体 else { // 设置LineRenderer的终点为射击方向(即枪口前方)的最大射程处 gunLine.SetPosition (1, shootRay.origin + shootRay.direction * range); } }