这次将为我们的角色添加武器,并为武器添加脚本使其运行。
将武器模型模型添加到场景中的角色Main Camera目录下(这样做之后可能会存在bug),我还在枪口处添加了muzzle物体,用来发射射击判定的射线和播放枪焰动画。
添加Gun脚本,并添加如下变量:
这些变量在不同的武器种类(如手枪,步枪,冲锋枪,狙击步枪等)都会有不同的数值及视觉效果。
新建ActionMap和Action,并且将开火键绑定为鼠标左键。
在枪械脚本中引入并启用InputAction
接下来创建射击功能,将使用射线检测的方式进行射击和击中物体的判定
先创建muzzle引用变量,使用physic.raycast发射射线
这段代码中,muzzle.position表示射线发射原点,muzzle.forward表示射线发射方向,hitInfo表示击中物体的信息,shootRange表示射击距离。
当射线接触到物体之后,如果被击中的物体有刚体,则对物体施加一个发生方向上的冲击力,模拟被子弹击飞的效果。
但现在无法看到子弹的预计击中点,在HUD上增加准星。
增加准星很简单,新建一个image UI元素,再修改其中的Image组建为准星图案(自己画也行),并缩放到合适的大小。
当子弹击中物体时,应该留下弹孔,烟雾等视觉特效,这里使用Instantiate函数进行生成。
代码解析:第一个参数impactEffect为弹孔与烟雾特效,第二个参数hitInfo.point表示的是生成特效的位置,这里是被击中物体击中点的位置,第三个参数是击中点的法线方向,使特效的方向正确,第四个参数hitInfo.transform表示生成该物体的父对象,这里是被击中的物体。
Gun的脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gun : MonoBehaviour
{
// 射击速率
[SerializeField] private float shootRate = 20f;
// 射击范围
[SerializeField] private float shootRange = 100f;
// 冲击力
[SerializeField] private float impactForce = 150f;
// 枪口火焰
[SerializeField] private ParticleSystem muzzleFlash;
// 击中效果
[SerializeField] private GameObject impactEffect;
[SerializeField] private Transform muzzle;
private Player playerInput;
// Start is called before the first frame update
void Start()
{
playerInput=new Player();
playerInput.Enable();
}
// Update is called once per frame
void Update()
{
if (playerInput.Fire.WeaponFire.triggered)
{
muzzleFlash.Play();
if (Physics.Raycast(muzzle.position, muzzle.forward, out RaycastHit hitInfo, shootRange))
{
if(hitInfo.rigidbody != null)
{
hitInfo.rigidbody.AddForce(muzzle.forward * impactForce, ForceMode.Impulse);
}
Instantiate(impactEffect, hitInfo.point, Quaternion.LookRotation(hitInfo.normal),hitInfo.transform);
}
}
}
}