上一章地址:UnityStandardAsset工程、源码分析_2_赛车游戏[玩家控制]_车辆核心控制
在上一章的分析中,有这么一段代码:
// 播放轮胎烟雾,粒子效果等脚本下章分析
m_WheelEffects[i].EmitTyreSmoke();
// 避免有多个轮胎同时播放声音,如果有轮胎播放了,这个轮胎就不播放了
// avoiding all four tires screeching at the same time
// if they do it can lead to some strange audio artefacts
if (!AnySkidSoundPlaying())
{
m_WheelEffects[i].PlayAudio();
}
这里就是车辆的核心控制逻辑CarController
与特效、声效的交互点了。这章我们就来分析在CarController
调用了这两个方法之后,发生了什么,如何管理特效的显示。
特效、声效
先说特效,组成特效的主要有两个方面:
- 烟尘
- 轮胎印
烟尘就是一个粒子系统,仅有一个,位置为Car/Particales/ParticleBurnoutSmoke
,而不是对应四个轮胎有四个。在轮胎发生滑动,不论是正向滑动还是反向滑动的时候,就会移动到发生滑动的轮胎的位置,并即时发出数量为1的粒子。
而轮胎印是一个TrailRenderer
,为预制件,由每个轮胎在需要时独自克隆和使用。
每个轮胎上有一个WheelEffects
类,用于管理特效发生的逻辑,上面的代码中的m_WheelEffects[i]
,就是在遍历每一个轮胎的WheelEffects
并调用它的EmyTyreSmoke
和PlayAudio
方法来释放特效。
WheelEffects
类的代码:
namespace UnityStandardAssets.Vehicles.Car
{
[RequireComponent(typeof (AudioSource))]
public class WheelEffects : MonoBehaviour
{
public Transform SkidTrailPrefab;
public static Transform skidTrailsDetachedParent;
public ParticleSystem skidParticles;
public bool skidding {
get; private set; }
public bool PlayingAudio {
get; private set; }
private AudioSource m_AudioSource;
private Transform m_SkidTrail;
private WheelCollider m_WheelCollider;
private void Start()
{
// 寻找烟尘粒子
skidParticles = transform.root.GetComponentInChildren<ParticleSystem>();
if (skidParticles == null)
{
Debug.LogWarning(" no particle system found on car to generate smoke particles", gameObject);
}
else
{
skidParticles.Stop();
}
m_WheelCollider = GetComponent<WheelCollider>();
m_AudioSource = GetComponent<AudioSource>();
PlayingAudio = false;
// 用于滑动结束后保留轮胎印
if (skidTrailsDetachedParent == null)
{
skidTrailsDetachedParent = new GameObject("Skid Trails - Detached").transform;
}
}
public void EmitTyreSmoke()
{
// 把粒子效果起点置于轮胎底部
skidParticles.transform.position = transform.position - transform.up*m_WheelCollider.radius;
skidParticles.Emit(1);
// 没有启动滑动协程则启动,避免重复
if (!skidding)
{
StartCoroutine(StartSkidTrail());
}
}
public void PlayAudio()
{
m_AudioSource.Play();
PlayingAudio = true;
}
public void StopAudio()
{
m_AudioSource.Stop();
PlayingAudio = false;
}
// 开始出现滑动轨迹
public IEnumerator StartSkidTrail()