枪口火焰特效
将特效包下载后导入项目
编写 WeaponGraphics.cs
类,用于管理每把武器的特效。
using UnityEngine;
public class WeaponGraphics
{
[SerializeField]
public ParticleSystem muzzleFlash; //枪口火焰
[SerializeField]
public GameObject stoneHitEffectPrefab; //击中石头特效
[SerializeField]
public GameObject metalHitEffectPrefab; //击中金属特效
}
将WeaponGraphics.cs脚本挂载到武器预制体上,之后在WeaponManager类中动态获取。
将选好的火焰特效放入Prefab文件夹中,并修改一下特效的大小、播放速度等。
具体的火焰特效播放是在开枪后执行,所以修改PlayerShoot类。
在Shoot()函数中加入一行 OnShootServerRpc()
,具体代码逻辑如下.
// 处理射击时的特效、音效等
private void OnShoot()
{
weaponManager.GetCurrentGraphics().muzzleFlash.Play();
}
[ServerRpc]
private void OnShootServerRpc()
{
if (!IsHost)
{
OnShoot();
}
OnShootClientRpc();
}
[ClientRpc]
private void OnShootClientRpc()
{
OnShoot();
}
击中粒子特效
粒子特效和火焰特效类似,只不过需要区分 击中石头、击中金属是不同的。
enum HitEffectMaterial { Stone, Metal };
定义一个枚举类型,用于区分特效类型。
写一个OnHit函数,用于执行具体物体被击中时的粒子动画播放逻辑。简单说就是在击中点动态实例化一个预制体,然后播放其中的ParticleSystem。
private void OnHit(Vector3 position, Vector3 normal, HitEffectMaterial material)
{
GameObject hitEffectPrefab;
if (material == HitEffectMaterial.Metal)
{
hitEffectPrefab = weaponManager.GetCurrentGraphics().metalHitEffectPrefab;
}
else
{
hitEffectPrefab = weaponManager.GetCurrentGraphics().stoneHitEffectPrefab;
}
GameObject hitEffectObject = Instantiate(hitEffectPrefab, position, Quaternion.LookRotation(normal));
ParticleSystem particleSystem = hitEffectObject.GetComponent<ParticleSystem>();
particleSystem.Emit(1);
particleSystem.Play();
Destroy(hitEffectObject, 0.5f);
}
private void Shoot()
{
OnShootServerRpc(recoilForce);
RaycastHit hit;
if (Physics.Raycast(eyesCamera.transform.position, eyesCamera.transform.forward, out hit, currentWeapon.range))
{
if (hit.collider.tag == PLAYER_TAG)
{
ShootServerRpc(hit.collider.name, currentWeapon.damage);
OnHitServerRpc(hit.point, hit.normal, HitEffectMaterial.Metal);
}
else
{
OnHitServerRpc(hit.point, hit.normal, HitEffectMaterial.Stone);
}
}
}
击中特效同样要同步到其他客户端。
[ClientRpc]
private void OnHitClientRpc(Vector3 position, Vector3 normal, HitEffectMaterial material)
{
OnHit(position, normal, material);
}
[ServerRpc]
private void OnHitServerRpc(Vector3 position, Vector3 normal, HitEffectMaterial material)
{
if (!IsHost)
{
OnHit(position, normal, material);
}
OnHitClientRpc(position, normal, material);
}
评论区