作为一个Unity初学者,独立开发FPS游戏时,无论怎么调整子弹都射不到准心位置,在网上也没找到比较适合的方法,后来突然想起来,摄像机射出一条射线获得位置,再让子弹朝向这个位置移动就可以了。
首先从网上找一个准心图片(我是自己做的)把它固定到屏幕中心就可以了
下面就是代码,不多废话,我直接上代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SimpleShoot : MonoBehaviour
{
public GameObject bulletPrefab;
/// <summary>
/// 碎子弹壳预制体
/// </summary>
public GameObject casingPrefab;
/// <summary>
/// 枪口火花预制体
/// </summary>
public GameObject muzzleFlashPrefab;
[SerializeField] private Animator gunAnimator;
/// <summary>
/// 枪管位置
/// </summary>
[SerializeField] private Transform barrelLocation;
/// <summary>
/// 枪口位置
/// </summary>
[SerializeField] private Transform casingExitLocation;
[SerializeField] private float destroyTimer = 1f;
[SerializeField] private float shotPower = 1000;//力量
[SerializeField] private float ejectPower = 150f;
private Vector3 target;
void Start()
{
if (barrelLocation == null)
barrelLocation = transform;
if (gunAnimator == null)
gunAnimator = GetComponentInChildren<Animator>();
}
void Update()
{
//按下左键
if (Input.GetButtonDown("Fire1"))
{
//播放开枪动画
gunAnimator.SetTrigger("Fire");
}
}
void Shoot()
{
//如果有预制体
if (muzzleFlashPrefab)
{
GameObject tempFlash;
//在枪口位置生成特效
tempFlash = Instantiate(muzzleFlashPrefab, barrelLocation.position, barrelLocation.rotation);
//在XX秒之后删掉
Destroy(tempFlash, destroyTimer);
}
//如果没有子弹预制体,直接返回
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
RaycastHit raycasthit;
if (Physics.Raycast(ray, out raycasthit))//如果射线碰撞到物体
{
target = raycasthit.point;//记录碰撞的目标点
}
else//射线没有碰撞到目标点
{
//将目标点设置在摄像机自身前方1000米处
target = Camera.main.transform.forward * 800;
}
GameObject go = Instantiate(bulletPrefab, barrelLocation.position, barrelLocation.rotation);
go.transform.LookAt(target);
go.GetComponent<Rigidbody>().AddForce(go.transform.forward * shotPower);
}
//This function creates a casing at the ejection slot
void CasingRelease()
{
//如果没有碎子弹预制体和枪口位置
if (!casingExitLocation || !casingPrefab)
{ return; }
//Create the casing
GameObject tempCasing;
//生成碎子弹预制体
tempCasing = Instantiate(casingPrefab, casingExitLocation.position, casingExitLocation.rotation) as GameObject;
// 爆炸物理效果
tempCasing.GetComponent<Rigidbody>().AddExplosionForce(Random.Range(ejectPower * 0.7f, ejectPower), (casingExitLocation.position - casingExitLocation.right * 0.3f - casingExitLocation.up * 0.6f), 1f);
//扭曲运动轨迹物理效果
tempCasing.GetComponent<Rigidbody>().AddTorque(new Vector3(0, Random.Range(100f, 500f), Random.Range(100f, 1000f)), ForceMode.Impulse);
//一段时间后销毁碎子弹预制体
Destroy(tempCasing, destroyTimer);
}
}