ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

车辆车轮控制

2021-05-01 15:29:28  阅读:215  来源: 互联网

标签:surfaceManager 控制 wheelCollider transform private terrainSurfaceTypes 车辆 skidAud


using UnityEngine;
using System.Collections.Generic;

namespace RGSK
{
    public class Wheels : MonoBehaviour
    {
        private SurfaceManager surfaceManager;

        private Texture2D currentTexture;                     
        private PhysicMaterial currentPhysicMaterial;       

        private WheelCollider wheelCollider;                   
        private WheelHit wheelHit;                             
        private Skidmark skidmarks;                          
        private int lastSkid;                                

        private Terrain terrain;                             
        private TerrainData terrainData;                    
        private SplatPrototype[] splatPrototypes;             

        private AudioSource skidAudioSource;                  

        [HideInInspector]
        public bool shouldEmit = false;                  
        [HideInInspector]
        public bool wheelOnPenaltySurface;                 
        private ParticleSystem particleToEmit;            
        private bool useSkidmarks;                        
        private List<string> wheelParticleChildren = new List<string>();    

        void Start()
        {
            //Get the surface manager
            if (GameObject.FindObjectOfType(typeof(SurfaceManager)))          
            {
                surfaceManager = GameObject.FindObjectOfType(typeof(SurfaceManager)) as SurfaceManager;   
            }
            else
            {
                return;             //如果没有则不返回参数
            }

            SetupWheelComponents();

            GetTerrainInfo();      //获取地形信息
        }

        void SetupWheelComponents()
        {
            if (!wheelCollider)
                wheelCollider = GetComponent<WheelCollider>();   

            //Get the skidmarks object
            if (GameObject.FindObjectOfType(typeof(Skidmark)))
            {
                skidmarks = GameObject.FindObjectOfType(typeof(Skidmark)) as Skidmark;  
            }

            //Configure the sound
            if (GetComponent<AudioSource>()) skidAudioSource = GetComponent<AudioSource>();   

            if (skidAudioSource)
            {
                skidAudioSource.spatialBlend = 1.0f;    
                skidAudioSource.loop = true;           
            }


            //将所有的地形实例为子对象
            if (surfaceManager.terrainSurfaceTypes.Count > 0)       
            {
                for (int i = 0; i < surfaceManager.terrainSurfaceTypes.Count; i++)
                {
                    if (surfaceManager.terrainSurfaceTypes[i].skidParticle)
                    {
                        if (!wheelParticleChildren.Contains(surfaceManager.terrainSurfaceTypes[i].skidParticle.transform.name + "(Clone)"))         //确保无副本
                        {
                            GameObject particle = (GameObject)Instantiate(surfaceManager.terrainSurfaceTypes[i].skidParticle, transform.position, Quaternion.identity);
                            particle.transform.parent = transform;
                            var em = particle.GetComponent<ParticleSystem>().emission;
                            em.enabled = false;
                            wheelParticleChildren.Add(particle.transform.name);
                        }
                    }
                }
            }


            //将所有的物理材质实例为子对象
            if (surfaceManager.physicMaterialSurface.Count > 0)
            {
                for (int i = 0; i < surfaceManager.physicMaterialSurface.Count; i++)
                {
                    if (surfaceManager.physicMaterialSurface[i].skidParticle)
                    {
                        if (!wheelParticleChildren.Contains(surfaceManager.physicMaterialSurface[i].skidParticle.transform.name + "(Clone)")) //确保无副本
                        {
                            GameObject particle = (GameObject)Instantiate(surfaceManager.physicMaterialSurface[i].skidParticle, transform.position, Quaternion.identity);
                            particle.transform.parent = transform;
                            var em = particle.GetComponent<ParticleSystem>().emission;
                            em.enabled = false;
                            wheelParticleChildren.Add(particle.transform.name);
                        }
                    }
                }
            }
        }

        void Update()
        {
            if (!surfaceManager) return;

           
            if (skidAudioSource && !skidAudioSource.isPlaying)      //确保音乐一直循环
                skidAudioSource.Play();

            
            wheelCollider.GetGroundHit(out wheelHit);      //获取轮胎碰撞数据

            //Get the surfaces
            PhysicMaterialSurfaceDetection();      //获取物理材质信息

            TerrainSurfaceDetection();      //获取地形信息

            
            Emit();     //发射粒子
        }

        void PhysicMaterialSurfaceDetection()
        {
            if (wheelHit.collider)
            {
                //Are we on a renderer
                if (wheelHit.collider.material)     //如果对象存在材质
                {
                    currentPhysicMaterial = wheelHit.collider.material;     //则将当前材质设定为对应材质的对应材质

                    for (int i = 0; i < surfaceManager.physicMaterialSurface.Count; i++)        //遍历材质系统,寻找是否有对应的材质
                    {
                        if (currentPhysicMaterial.name.Replace(" (Instance)", "") == surfaceManager.physicMaterialSurface[i].physicMaterial.name)
                        {
                            //播放对应材质的音效
                            if (skidAudioSource && surfaceManager.physicMaterialSurface[i].skidSound) skidAudioSource.clip = surfaceManager.physicMaterialSurface[i].skidSound;

                            // 发射对应材质的粒子
                            foreach (Transform t in transform)
                            {
                                if (t.name == surfaceManager.physicMaterialSurface[i].skidParticle.name + "(Clone)")
                                    particleToEmit = t.GetComponent<ParticleSystem>();
                            }

                            //判断表面类型是否是连续的
                            if (surfaceManager.physicMaterialSurface[i].surfaceType == SurfaceManager.SurfaceType.OffRoad)
                            {
                                if (skidAudioSource && wheelCollider.attachedRigidbody.velocity.magnitude > 5.0f) { shouldEmit = true; skidAudioSource.volume = .5f; }
                            }

                            //判断当前平面是否需要使用滑动痕迹
                            useSkidmarks = surfaceManager.physicMaterialSurface[i].allowSkidmark;

                            wheelOnPenaltySurface = surfaceManager.physicMaterialSurface[i].isPenaltySurface;
                        }
                    }
                }
            }
        }

        void TerrainSurfaceDetection()
        {
            if (terrain == null) return;    //如果地形为空则直接返回

            if (wheelHit.collider)          //判断当前是否与地面相接触
            {
                
                if (wheelHit.collider.GetComponent<Terrain>())      //当与地面相接触时,将对应的材质返回
                {
                    currentTexture = splatPrototypes[GetTerrainTexture(transform.position)].texture;
                }
                else                                                //没有接触时,则不返回
                {
                    currentTexture = null;
                }
            }

            
            for (int i = 0; i < surfaceManager.terrainSurfaceTypes.Count; i++)      //设定或返回地面材质的细节数据
            {
                if (currentTexture == surfaceManager.terrainSurfaceTypes[i].texture)
                {
                    //返回对应材质的音效,并进行播放
                    if (surfaceManager.terrainSurfaceTypes[i].skidSound)
                    {
                        if (skidAudioSource && surfaceManager.terrainSurfaceTypes[i].skidSound) skidAudioSource.clip = surfaceManager.terrainSurfaceTypes[i].skidSound;
                    }

                    // 发射对应的粒子
                    foreach (Transform t in transform)
                    {
                        if (t.name == surfaceManager.terrainSurfaceTypes[i].skidParticle.name + "(Clone)")
                        {

                            particleToEmit = t.GetComponent<ParticleSystem>();
                        }
                    }

                    //判断表面是否是连续的
                    if (surfaceManager.terrainSurfaceTypes[i].surfaceType == SurfaceManager.SurfaceType.OffRoad)
                    {
                        if (skidAudioSource && wheelCollider.attachedRigidbody.velocity.magnitude > 5.0f) { shouldEmit = true; skidAudioSource.volume = .5f; }
                    }

                    //判断是否能够使用滑动痕迹
                    useSkidmarks = surfaceManager.terrainSurfaceTypes[i].allowSkidmark;

                    wheelOnPenaltySurface = surfaceManager.terrainSurfaceTypes[i].isPenaltySurface;
                }
            }
        }

        public void Emit()      //发射系统
        {
            if (shouldEmit && wheelCollider.isGrounded)     //当允许发射,且车辆着地时
            {
                //粒子
                if (particleToEmit) particleToEmit.Emit(1);

                //滑动痕迹
                Vector3 skidPoint = wheelHit.point + (wheelCollider.attachedRigidbody.velocity * Time.fixedDeltaTime);

                if (skidmarks != null)
                {
                    if (useSkidmarks)
                        lastSkid = skidmarks.AddSkidMark(skidPoint, wheelHit.normal, 0.5f, lastSkid);
                    else
                        lastSkid = -1;
                }

                //音效的音量
                if (skidAudioSource)
                    skidAudioSource.volume = Mathf.Abs(wheelHit.sidewaysSlip) + Mathf.Abs(wheelHit.forwardSlip) + 0.5f;
            }
            else
            {
                lastSkid = -1;

                //声音的线性差值
                if (skidAudioSource)
                    skidAudioSource.volume -= Time.deltaTime;
            }
        }

            //与地形相关的方法
        private void GetTerrainInfo()       //获取地形信息
        {
            if (Terrain.activeTerrain)
            {
                terrain = Terrain.activeTerrain;
                terrainData = terrain.terrainData;
                splatPrototypes = terrain.terrainData.splatPrototypes;
            }
        }

        private float[] GetTextureMix(Vector3 worldPos)     //获得纹理
        {

            terrain = Terrain.activeTerrain;       //激活地形  
            terrainData = terrain.terrainData;       //获取数据
            Vector3 terrainPos = terrain.transform.position;        //获取地形的位置信息

            int mapX = (int)(((worldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth);
            int mapZ = (int)(((worldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight);

            float[,,] splatmapData = terrainData.GetAlphamaps(mapX, mapZ, 1, 1);        //将地形的位置数据传递给贴图的位置数据

            float[] cellMix = new float[splatmapData.GetUpperBound(2) + 1];     //存储获得的数据
            for (int n = 0; n < cellMix.Length; ++n)        //遍历每一个数据,并将其返回
            {
                cellMix[n] = splatmapData[0, 0, n];
            }

            return cellMix;
        }

        private int GetTerrainTexture(Vector3 worldPos)     //获得地面的纹理
        {

            float[] mix = GetTextureMix(worldPos);
            float maxMix = 0;
            int maxIndex = 0;

            for (int n = 0; n < mix.Length; ++n)
            {

                if (mix[n] > maxMix)
                {
                    maxIndex = n;
                    maxMix = mix[n];
                }
            }

            return maxIndex;
        }

        public void SetupWheelCollider(float mass, float spring, float damper)      //设定轮胎的重量,弹簧以及减震器
        {
            if (!wheelCollider)
                wheelCollider = GetComponent<WheelCollider>();

            JointSpring _spring = wheelCollider.suspensionSpring;
            _spring.spring = spring;
            _spring.damper = damper;
            wheelCollider.suspensionSpring = _spring;
            wheelCollider.mass = mass;
            wheelCollider.wheelDampingRate = 1.0f;
        }
    }
}
 

标签:surfaceManager,控制,wheelCollider,transform,private,terrainSurfaceTypes,车辆,skidAud
来源: https://blog.csdn.net/kuyineko/article/details/116330548

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有