unity3d射箭模拟小游戏

本文详细介绍了使用Unity3D开发一款射箭模拟小游戏的过程,包括箭矢的鼠标控制、蓄力发射、箭矢中靶响应等功能。通过项目代码分享,展示了游戏的关键实现细节,如箭矢跟随鼠标旋转、碰撞处理、计分系统等,帮助读者理解游戏开发中的物理模拟和事件响应机制。
摘要由CSDN通过智能技术生成

该博客是继上次打飞碟小游戏的另一次尝试,且此次设计过程是在上次的经验上完全的由自己完成,因此尽管经历了更多的弯折和死路,但终究也获得了更多。
项目的代码已经上传至github,可以点击此处获取:
射箭小游戏
下面就来分享下这款小游戏的制作过程。


介绍

该小游戏中,玩家可以控制一根箭矢,通过鼠标左键调整箭矢指向,键盘F按下蓄力,松开发射,命中远处的箭靶则加分。

游戏画面

游戏尚未编写更加具体的规则和玩法,因为这只是一个学习类的项目。
那么这次游戏的看点:

  1. 模拟箭矢的飞行;
  2. 鼠标控制箭矢的指向;
  3. 键盘按下蓄力,松开发射;
  4. 场景内箭矢管理(并不太尽如人意)。
  5. 箭矢中靶响应。

每次介绍制作过程时,更多的还是讲解途中了解到的新知识,或是新认知。


项目总览

首先来看一下这个项目的结构及内容:

对象总览

  • 其中Base_1是一个空对象,具有刚体组件。作用是模拟子物体Cube(箭矢实体)的围绕一点旋转的情况。
  • Cube即箭矢的实际碰撞盒,但不添加刚体组件,该点会在后面说明。
  • Mass也是一个空对象,但位置相对于Cube更加偏向箭矢头部一点点,用于模拟重心偏离,即箭矢箭头朝下落地的情况。这个需要配合函数AddForceAtPosition来实现该效果。
  • Cylinder是一个圆柱状的箭靶,这里不使用系统默认加上的 胶囊碰撞器 ,因为只要试着去编辑它的碰撞盒形状,你就会发现前后柱面会多一个半球状的碰撞盒突起,这会使得箭矢提前触发碰撞效果。因此这里取消掉默认碰撞器,转而使用Mesh Collider( 网格碰撞器 ),该碰撞器可以很好地拟合物体表面,但需要花费更多的计算资源。不过对于此处的单一物件就没什么关系了。
  • Manager_1是一个空物体,用于挂载控制类脚本。在这些脚本上可以设置一些游戏的参数。
  • Canvas,画布对象,用于分数显示。内容和作用与先前的游戏相同,想要了解的可以到那篇博客里去查阅或是自行搜索相关内容。

下面是各项的具体参数:
Base_1:
Base_1
Cube:
箭矢碰撞盒
Mass_1:
Mass_1
其中子物体的坐标是相对于它的上一级父物体的相对坐标,而非世界坐标。
这里要是想获取相对坐标的话,使用transform.localPosition,世界坐标使用transform.position

注意

  • 关于 父子物体 设置。子物体的运动受父物体的运动影响,也就是说父物体移动的话,子物体也会跟随着移动,子物体移动的话,父物体并不会改变位置。因此相关的操作都需要相对于父物体来进行。另外对于 刚体组件 来说,
    1. 父物体单独持有刚体组件,子物体都会具有刚体属性,即会发生碰撞以及受物理力的影响。
    2. 子物体单独持有刚体,父物体并不具备刚体性质,也就是不会受力也不会发生碰撞。
    3. 父子都持有刚体组件,双方并不会进行相同的行为,而是根据各自的情况而运动,都具有刚体性质。

所以一般来说只需要父物体持有刚体组件就可以了。碰撞器的体积为所有具有碰撞器组件的子物体体积。在这里就是Cube子物体。

  • 关于 重心 的设置。常见的AddForce及相关函数所添加的力是不会出现力矩的。换句话来说就是不会出现让物体旋转的力。很明显箭矢之所以能够命中,就是因为它的箭头更沉导致重心偏前。在重力的影响下最后会箭头指向地面。
    为了达成这一点,需要用到函数AddForceAtPosition,在某个点施加物理力。这样只要力不是指向质心,就会出现力矩。可以用这个函数来模拟重力的作用,而这就需要一个偏移的质心。也就是上面的 Mass_1 ,它只负责传入它的位置信息,即transform组件。注意这里需要用到该空对象的 世界坐标 而非相对坐标。

箭矢(Arrow)

这里所谓的箭矢指的是即将发射的箭矢对象,在该程序中,落地,中靶的箭矢将会被销毁挂载在上面的脚本,并在一定时间后被回收。

这里需要额外说明一下,脚本也是游戏对象的一个组件,不仅可以通过this.gameObject来访问对象,更可以通过GetComponent<"脚本名">()来找到相应脚本。
Destroy(Arrow)只是销毁挂载在游戏对象上的脚本对象,Destroy(Arrow.gameObject)才是销毁挂载该脚本的游戏对象,当然同时脚本对象也被销毁了。
具体实例可以看一下ArrowController中的RecycleArrow函数。

ArrowController.RecycleArrow

public void RecycleArrow()
{
   
    if(arrow != null && arrow.transform.position.y < -5)
    {
   
        Destroy(arrow.gameObject);
        isOver = false;
        variable = true;
    }
    if (arrow != null && arrow.stopped)
    {
   
        used.Add(arrow.gameObject);
        Destroy(arrow);
        isOver = false;
        variable = true;
    }
    if(interval < 30f)
    {
   
        interval += Time.deltaTime;
    }
    else
    {
   
        for
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值