激光武器,继承gun类,能实现枪口面朝鼠标方向和一些基本的功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class WeaponInfo
{
public float interval;
public int ammoCount;//子弹数
public int maxButtleCount;
public float presistTime;
public Sprite sprite;
}
public class Gun : MonoBehaviour
{
public GameObject bulletPrefab;
public GameObject shellPrefab;
public WeaponInfo weaponInfo;
protected Transform muzzlePos;
protected Transform shellPos;
protected Vector2 mousePos;
protected Vector2 direction;
protected float timer;
protected float flipY;
protected Animator animator;
protected virtual void Awake()
{
animator = GetComponent<Animator>();
weaponInfo.sprite= GetComponent<SpriteRenderer>().sprite;
muzzlePos = transform.Find("Muzzle");
shellPos = transform.Find("BulletShell");
}
protected virtual void Start()
{
flipY = transform.localScale.y;
}
protected virtual void Update()
{
Filp();
}
public virtual void Enter()
{
Debug.Log("当前的枪 进入"+gameObject.name);
}
public virtual void Exit()
{
Debug.Log("当前的枪 退出时"+gameObject.name);
}
protected virtual void Filp()
{
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
direction = (mousePos - new Vector2(transform.position.x, transform.position.y)).normalized;
transform.right = direction;
if (mousePos.x < transform.position.x)
transform.localScale = new Vector3(flipY, -flipY, 1);
else
transform.localScale = new Vector3(flipY, flipY, 1);
}
public virtual void Fire()
{
if (weaponInfo.ammoCount > 0)
{
// 实现枪的射击逻辑
weaponInfo.ammoCount--;
animator.SetTrigger("Shoot");
//对象池生成子弹壳
GameObject bullet = ObjectPool.Instance.GetObject(bulletPrefab);
bullet.transform.position = muzzlePos.position;
//子弹随机偏移角度
float angel = Random.Range(-5f, 5f);
bullet.GetComponent<Bullet>().SetSpeed(Quaternion.AngleAxis(angel, Vector3.forward) * direction);
GameObject shell = ObjectPool.Instance.GetObject(shellPrefab);
shell.transform.position = shellPos.position;
shell.transform.rotation = shellPos.rotation;
}
else
{
Reload();
}
}
public virtual void StopFire()
{
}
//换弹
public virtual void Reload()
{
if(weaponInfo.maxButtleCount-weaponInfo.ammoCount > 0)
{
weaponInfo.ammoCount = 10;
weaponInfo.maxButtleCount-=10;
}
else
{
weaponInfo.ammoCount=weaponInfo.maxButtleCount;
weaponInfo.maxButtleCount=0;
}
}
public virtual void AddButtleNumber(int number)
{
weaponInfo.maxButtleCount+=number;
}
}
激光我使用LineRenderer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lasergun : Gun
{
public int damage;
public int backForce;//击退力
public float hitInterval;
public bool isCanHit = true;
public int maxReflections = 2;//反射次数
public float maxLength = 100f;//每次反射的距离
private GameObject effect;
private LineRenderer laser;
private bool isShooting;
protected override void Start()
{
base.Start();
laser = muzzlePos.GetComponent<LineRenderer>();
effect = transform.Find("Effect").gameObject;
}
private void OnDisable()
{
isCanHit=true;
}
public override void Fire()
{
//激光持续时间
if(weaponInfo.presistTime<=0)
{
StopFire();
Reload();
return;
}
else
{
weaponInfo.presistTime-=Time.deltaTime;
}
isShooting = true;
laser.enabled = true;
effect.SetActive(true);
animator.SetBool("Shoot", isShooting);
// 定义敌人层和墙壁层的LayerMask
int enemyLayerMask = 1 << LayerMask.NameToLayer("Enemy");
int wallLayerMask = 1 << LayerMask.NameToLayer("Default");
// 合并两个LayerMask
int combinedLayerMask = enemyLayerMask | wallLayerMask;
//激光反射
int reflectionCount = 0;
Vector2 currentPosition = muzzlePos.position;
laser.positionCount = 1;
laser.SetPosition(0, currentPosition);
for (int i = 0; i < maxReflections; i++)
{
RaycastHit2D hit = Physics2D.Raycast(currentPosition, direction, maxLength, combinedLayerMask);
粒子特效
effect.transform.position = hit.point;
effect.transform.forward = -direction;
if (hit.collider != null)
{
reflectionCount++;
laser.positionCount = reflectionCount + 1;
laser.SetPosition(reflectionCount, hit.point);
direction = Vector2.Reflect(direction, hit.normal);
currentPosition = hit.point + direction * 0.01f; // 避免连续两次射线检测命中同一物体
}
else
{
currentPosition += maxLength * direction;
laser.positionCount = reflectionCount + 2;
laser.SetPosition(reflectionCount + 1, currentPosition);
break;
}
// 击中敌人
if (isCanHit)
{
if (hit.collider.gameObject)
{
GameObject other = hit.collider.gameObject;
if (other.TryGetComponent<Enemy>(out Enemy enemy))
{
Vector3 reflectedDirection = Vector3.Reflect(direction, hit.normal); // 获取反射方向
//击退
enemy.TakeDamage(damage, reflectedDirection, backForce);
StartCoroutine(nameof(HitIntervalCoroutine));
}
}
}
}
}
public override void AddButtleNumber(int number)
{
weaponInfo.presistTime+=number;
}
public override void StopFire()
{
isShooting = false;
laser.enabled = false;
effect.SetActive(false);
animator.SetBool("Shoot", isShooting);
}
public override void Reload()
{
}
IEnumerator HitIntervalCoroutine()
{
isCanHit=false;
yield return new WaitForSeconds(hitInterval);
isCanHit=true;
}
}
配置看自己需求更改