unity中可反射的激光武器(2d游戏)

本文介绍了如何在Unity中创建一个继承自Gun类的激光武器,实现射击逻辑,包括枪口方向跟随鼠标,子弹发射、激光反射、碰撞检测以及击退效果。同时,文中还涉及了激光持续时间和粒子特效的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

激光武器,继承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;
    }
}

配置看自己需求更改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值