Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等

这篇具有很好参考价值的文章主要介绍了Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文章目录


Hello大家好我是开罗小8,今天我来给大家带来Unity常用子弹弹幕类型的实现,功能的实现方式有很多种,在实现效果中,我会尽可能用简单的代码实现,文章的示例项目文件在文章底部

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏
环形弹幕实现
Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏
追踪弹

前言

本文子弹始终朝向其前进方向移动(在2D中红轴为前进方向,3D中蓝轴为前进方向),可以将坐标轴切换为local来查看当前物体的朝向

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

 子弹的基类脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BaseBullet : MonoBehaviour
{
    public float Speed=1;
    public GameObject ExpFX;
    protected Rigidbody2D rb;
    protected Transform m_tansform;
    // Update is called once per frame
    private void Awake()
    {
        rb = gameObject.AddComponent<Rigidbody2D>();
        rb.gravityScale = 0;
        rb.drag= 0;
        rb.freezeRotation = true;
        rb.bodyType = RigidbodyType2D.Dynamic;
        rb.constraints = RigidbodyConstraints2D.FreezeRotation;
        m_tansform = transform;
    }
    protected virtual void Update()
    {
        m_tansform.position= m_tansform.position+ m_tansform.right*Speed*Time.deltaTime;
        //m_tansform.Translate(Vector3.right * Speed * Time.deltaTime);
    }
    public void Explode()
    {
        Destroy(Instantiate(ExpFX, m_tansform.position,Quaternion.identity),2f);
        Destroy(gameObject);
    }
}
  • 脚本中Update两行代码均可实现让子弹沿自身的红轴(X轴)移动
  • 获取物体当前的轴向
  1. transform.right          红轴(X轴)
  2. transform.up             绿轴(Y轴)
  3. transform.forward     蓝轴(Z轴)
  • transform.right与Vector3.right的区别
  1. Vector3.right始终等于new Vector3(1,0,0)
  2. transform.right为当前物体红轴的朝向,受到物体旋转的影响 

transform.Translate方法如果只传入一个Vector3类型的,它会以自身的轴来进行移动

例如transform.Translate(new Vector3(1,0,0))表示物体朝自身的X轴方向移动1米

为了避免子弹相互碰撞,需要将子弹设置一个新的layer,命名为Bullet,layer设置完后还需要在Edit->ProjectSetting->Physics2D中取消勾选Bullet与Bullet之间的碰撞

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

一、各种类型子弹以及武器的实现

1.向鼠标方向发射子弹

using UnityEngine;

public class Weapon : MonoBehaviour
{
    public GameObject FireFX;
    public GameObject Bullet;
    private Transform m_transform;
    
    // Start is called before the first frame update
    Camera cam;
    void Start()
    {
        cam=Camera.main;
        m_transform = transform;
    }

    // Update is called once per frame
    void Update()
    {
        
        Vector3 mousePos= cam.ScreenToWorldPoint(Input.mousePosition);
        Vector3 weaponDir=mousePos- m_transform.position;
        weaponDir.z = 0;
        weaponDir.Normalize();
        m_transform.right=weaponDir;
        //float zAngle = Mathf.Atan2(weaponDir.y, weaponDir.x) * Mathf.Rad2Deg;
        //m_transform.localEulerAngles=new Vector3(0,0,zAngle);
        if(Input.GetKeyDown(KeyCode.Space))
        {
            //GameObject fireFX = Instantiate(FireFX);
            //fireFX.transform.position= m_transform.position;
            //Destroy( fireFX ,2f);
            GameObject bullet= Instantiate(Bullet);
            bullet.transform.position= m_transform.position;
            bullet.transform.right= m_transform.right;
        }
    }
}

1.使用本地变量缓存主摄像机和transform,使用transform获取变换和使用Camera.main获取摄像机比较消耗性能

2.将鼠标位置从屏幕空间转换到世界空间,使用cam.ScreenToWorldPoint(Input.mousePosition);传入当前鼠标的屏幕位置

注:屏幕位置为左下角为(0,0),右上角为屏幕分辨率,如(1920,1080)

3.计算向量,两个物体的位置相减,得到的方向指向被减的位置,示例中的代码可以得到武器位置指向鼠标的方向。

4.计算武器的旋转角,调整武器的朝向,同时在生成子弹时调整子弹的位置和旋转。

注:直接对transform.right赋值改变物体旋转只适合在2D中使用,不推荐在3D情况下使用,可能会导致其他轴的不正确旋转

2.子弹撞墙反弹

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

using UnityEngine;

public class BounceBullet : BaseBullet
{
    public int BounceCount = 3;


    private void OnCollisionEnter2D(Collision2D collision)
    {

        
        if (collision.gameObject.CompareTag("Wall"))
        {
            --BounceCount;
            if (BounceCount <= 0)
            {
                Explode();
                return;
            }
            Vector2 outDir = Vector2.Reflect(m_tansform.right, collision.GetContact(0).normal);
            m_tansform.right = outDir;
        }
    }
    
}

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

  • Vector2.Reflect第一个参数传入当前子弹的朝向,第二个参数传入碰撞的法向,会返回反射后的新向量
  • collision.GetContact(0).normal来获取碰撞点的法向 
  • 只有在OnCollisionEnter2D中才可以获取碰撞点的法向,OnTriggerEnter2D中无法获取碰撞点的法向
  • 子弹需要有Rigidbody2D组件,且刚体类型为Dynamic,否则碰撞函数不会被触发
  • 此处使用CompareTag方法比较碰撞体的标签,如果是Wall就反弹,使用CompareTag比直接gameObject.tag==“Wall”要更节省性能
  • 应当保证传入的参数都是归一化(向量的模为1)后的向量,可以使用vector3.Normalize();方法使向量归一化,否则计算出的方向可能会不正确
  • 可以直接给transform.right赋值来改变物体的朝向

3.子弹追踪敌人

简单版,这样写子弹会固定指向敌人,视觉效果并不好

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TargetingBullet : BaseBullet
{
    Transform target;
    private void Start()
    {
        target = GameObject.Find("Target").transform;
    }
    // Update is called once per frame
    protected override void Update()
    {
        Vector3 targetDir=target.position-transform.position;
        targetDir.Normalize();

        transform.right= targetDir;
        base.Update();
    }

}

 调整方法1:使用插值函数,子弹每次调整一定的角度

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

using UnityEngine;

public class TargetingBullet : BaseBullet
{
    Transform target;
    public float TurnSpeed=2;
    float lifeTime=0;
    private void Start()
    {
        target = GameObject.Find("Target").transform;
    }
    // Update is called once per frame
    protected override void Update()
    {
        Vector3 targetDir=target.position-transform.position;
        targetDir.z = 0;
        targetDir.Normalize();
        lifeTime += Time.deltaTime;
        
        m_tansform.right= Vector3.Slerp(m_tansform.right,targetDir,Mathf.Clamp01(Time.deltaTime*(lifeTime)* TurnSpeed));
        base.Update();
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            Explode();
        }
    }
}

lifeTime的作用:子弹存在的时间越长,转向速度越快,如果不增加转向速度,会导致子弹速度大于转向速度时,子弹会一直绕着敌人转圈,无法命中敌人 

Vector3.Slerp:前两个参数传入两个Vector3类型,第三个参数传入插值,当插值为0时返回第一个向量,插值为1时返回第二个向量,插值在0~1时返回两向量的过渡值

4.散弹枪

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

public void FireShotGun(float angle,int bulletCount)
    {
        int mid = bulletCount >> 1;
        for(int i=0;i<bulletCount; i++)
        {
            Vector3 dir =  Quaternion.Euler(new Vector3(0,0, (i - mid) * angle))*m_transform.right;
            GameObject bullet = Instantiate(Bullet);
            bullet.transform.position = m_transform.position;
            bullet.transform.right = dir;
        }
    }

angle为每个子弹的角度,bulletCount为子弹的个数,示例中传入的参数为10,4

1.使用位运算计算子弹数量的中位数,buttonCount>>1等价于buttonCount/2,位运算的计算效率比除法要高,但是位运算的优先级低于加减法,如果有加法要注意加括号

2. Quaternion.Euler传入的Vector3类型相当于旋转的的欧拉角度,乘以一个向量的返回值等于该向量在对应轴上旋转后的向量,注意四元数在乘号左边,向量在右边,位置不能交换,上面的代码在计算transform.right绕自身的z轴旋转一个角度后的向量

5.圆环弹幕

Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等,unity,游戏引擎,c#,游戏

public void FireCircle(int bulletCount,float angleOffset)
    {
        float angle=360/bulletCount;
        for (int i = 0; i < bulletCount; i++)
        {
            Vector3 dir = Quaternion.Euler(new Vector3(0, 0, i*angle+angleOffset)) * m_transform.right;
            GameObject bullet = Instantiate(Bullet);
            bullet.transform.position = m_transform.position;
            bullet.transform.right = dir;
        }
    }

 每次发射增加angleoffset即可产生不同的角度偏移

其他类型的弹幕会持续更新…… 

项目文件下载:

子弹和武器.unitypackage


总结

本文介绍了常用的2D游戏子弹以及武器的实现方式,为了方便,直接对transform.right赋值来调整旋转,这个操作只能保证transform.right这个轴朝向给定的方向,在3D中可能会导致奇怪的旋转,我会在下一篇文章中详细介绍使用数学以及四元数的方法计算旋转文章来源地址https://www.toymoban.com/news/detail-752760.html

到了这里,关于Unity常用2D子弹弹幕以及枪械类型的实现:可实现霰弹枪,Boss弹幕,子弹反弹,追踪弹等的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • unity实现子弹散射效果和闪电链效果

    实现爆炸散射效果可以按照以下步骤进行: 1.准备子弹模型和爆炸特效模型,可以使用粒子特效或者模型。 2.创建子弹和敌人模型,同时添加刚体组件。 3.创建子弹的脚本,绑定到子弹上。 4.在脚本中,对子弹的 OnTriggerEnter 或 OnCollisionEnter 函数做出响应,检测敌人碰撞事件发

    2024年02月16日
    浏览(38)
  • js常用判断数据类型方法以及优缺点 以及 instanceof 原理实现

    使用typeof操作符可以 判断一个值的数据类型 。它返回一个表示数据类型的字符串。 优点:typeof 操作符是一种简单、快速的方式来 判断基本数据类型 。它返回的结果是一个字符串,可以直接用于条件判断。 缺点: 对于引用类型(除了函数)的判断结果都是\\\'object\\\' ,无法细

    2024年02月12日
    浏览(45)
  • 上期2D子弹跟随大受欢迎,想要个3D版本的?

    实现子弹跟随的游戏开发技巧之3D版本 大家好,在 上一篇文章 中,笔者介绍了如何在 Cocos游戏开发 中实现 2D子弹的跟随 效果。 有许多 感兴趣的小伙伴 私信我,有没有 3D版本 的呀? 3D 其实和 2D 的子弹跟随效果 大同小异 ,需要一些 简单的数学知识 。 于是,本文将介绍一

    2024年01月25日
    浏览(24)
  • [Unity] 使用 Animation Rigging 让角色双手正确持握枪械

    最近在制作角色状态机时,发现角色不同持枪动作下,握枪位置总是不能统一,例如瞄准时双手已经握住枪械:  但静态时左手却错位握不住:  于是找到了使用Animation Rigging做骨骼约束,下面是具体的解决方法: 打开Window/PackageManager/UnityRegistry,搜索Animation Rigging,安装并引

    2024年02月04日
    浏览(76)
  • Unity初学2——瓦片的制作以及世界的交互(2d)

    该文来自学习chutianbo老师的笔记,链接b站第56P至71P 右键点击主界面Sence➡GameObject➡2D Object➡Tilemap➡Rectanglar(这样是创建了一个RPG式的视角) 创建tiles文件夹 将素材拖入右上角打开的紫色按键TIle Palette,将素材拖入 或者直接在文件夹中创建 2.素材过大需要分割怎么办 回到素

    2023年04月09日
    浏览(42)
  • 【Unity2D】相机移动以及设置相机边界

    添加相机时,首先需要在unity中添加 Cinemachine 包 第一次使用这个包时,需要在Package Manager中搜索并安装  安装Camera Mechine包后,添加2D Camera 设置跟随对象为Ruby (从Hierarchy中将Ruby拖动到Follow中)   同时,由于世界是有边界的,要为相机设置边界 通过添加Extension为相机添加

    2024年02月16日
    浏览(44)
  • 【Ruby 2D】【unity learn】控制敌人随机运动以及动画控制

    前两天考完蓝桥杯稍微休息了一下,昨天做了一个动画控制,但是想到写出来可能会字很多,我就搁置到今天来写了,unity learn是一个官方教程平台,里面有unity assert store的配套教程,全是文档,比看视频高效太多了,想学习unity的可以去这里学习   网址 unity learn:Unity3d 教程

    2023年04月13日
    浏览(48)
  • Unity 新建你的第一个游戏,以及如何按WASD控制角色运动 (Unity Demo2D)

    当你打开 Unity Hub,初始化一个 2D 项目,进入了 Unity 编辑器,你会发现在 左侧 : 一个叫 SampleScene (或者其他) 的场景 场景下有一个 Main Camera,主相机 这就是一个新建的 2D 项目自带的内容。 在 Main Camera 同级目录新建: 2D Object - Sprites - Capsule ,这里 Capsule 是精灵的种类,我们

    2024年02月02日
    浏览(46)
  • unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)

    该文来是学习chutianbo老师的笔记,链接b站 1.右键Hierarchy空白处 UI➡canvas 2.这里一共使用了三个素材 层级结构 UI:初始画布 characters:头像 Mask:遮罩层 healthbar:血条 这里我们先回到UI(也就是一开始创建的Canvas) 我们一开始有用的应该只有渲染模式render Mode,他有三种模式

    2023年04月08日
    浏览(42)
  • Unity常用方法--Physics2D.OverlapCircleAll(获取一个圆形区域内所有碰撞器的列表)

    使用方式请直接看参考文献 使用案例 可以通过该方法判断在攻击范围内是否存在敌人,并在存在时,调用敌人组件的内部函数 代码 参考文献   https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.OverlapCircleAll.html

    2024年04月10日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包