zoukankan      html  css  js  c++  java
  • Tanks!Tutorial 学习

    using UnityEngine;
    
    namespace Complete
    {
        public class CameraControl : MonoBehaviour
        {
            /// <summary>
            /// 相机重新聚焦的时间
            /// </summary>
            public float m_DampTime = 0.2f;                 
            /// <summary>
            /// 
            /// </summary>
            public float m_ScreenEdgeBuffer = 4f;           
            /// <summary>
            /// 正交模式吓的最小视口大小
            /// </summary>
            public float m_MinSize = 6.5f;                  
            /// <summary>
            /// 相机需要保卫的目标数组
            /// </summary>
            [HideInInspector] public Transform[] m_Targets; 
    
            /// <summary>
            /// 相机
            /// </summary>
            private Camera m_Camera;                        
            /// <summary>
            /// 变焦速度
            /// </summary>
            private float m_ZoomSpeed;                      
            /// <summary>
            /// 移动速度
            /// </summary>
            private Vector3 m_MoveVelocity;                 
            /// <summary>
            /// 目标位置
            /// </summary>
            private Vector3 m_DesiredPosition;                                   
    
    
            private void Awake ()
            {
                m_Camera = GetComponentInChildren<Camera> ();
            }
    
    
            private void FixedUpdate ()
            {
                Move ();
                Zoom ();
            }
    
            /// <summary>
            /// 移动
            /// </summary>
            private void Move ()
            {
                FindAveragePosition ();
    
                transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
            }
    
            /// <summary>
            /// 查找所有目标的中间位置
            /// </summary>
            private void FindAveragePosition ()
            {
                Vector3 averagePos = new Vector3 ();
                int numTargets = 0;
    
                for (int i = 0; i < m_Targets.Length; i++)
                {
                    if (!m_Targets[i].gameObject.activeSelf)
                        continue;
    
                    averagePos += m_Targets[i].position;
                    numTargets++;
                }
    
                if (numTargets > 0)
                    averagePos /= numTargets;
    
                averagePos.y = transform.position.y;
                m_DesiredPosition = averagePos;
            }
    
            /// <summary>
            /// 变焦
            /// </summary>
            private void Zoom ()
            {
                float requiredSize = FindRequiredSize();
                m_Camera.orthographicSize = Mathf.SmoothDamp (m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
            }
    
            /// <summary>
            /// 查找需要的视口大小
            /// </summary>
            /// <returns></returns>
            private float FindRequiredSize ()
            {
    
                Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);
    
                float size = 0f;
    
                for (int i = 0; i < m_Targets.Length; i++)
                {
                    if (!m_Targets[i].gameObject.activeSelf)
                        continue;
    
                    Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);
    
                    Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;
    
                    size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y));
    
                    size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / m_Camera.aspect);
                }
    
                size += m_ScreenEdgeBuffer;
    
                size = Mathf.Max (size, m_MinSize);
    
                return size;
            }
    
            /// <summary>
            /// 设置相机的起始位置和大小
            /// </summary>
            public void SetStartPositionAndSize ()
            {
                FindAveragePosition ();
    
                transform.position = m_DesiredPosition;
    
                m_Camera.orthographicSize = FindRequiredSize ();
            }
        }
    }
    CameraControl
    using System.Collections;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    
    namespace Complete
    {
        public class GameManager : MonoBehaviour
        {
            /// <summary>
            /// 要赢得游戏的局数
            /// </summary>
            public int m_NumRoundsToWin = 5;            
            /// <summary>
            /// 从回合准备转换到回合开始的时间
            /// </summary>
            public float m_StartDelay = 3f;             
            /// <summary>
            /// 从回合开始转换到回合结束的时间
            /// </summary>
            public float m_EndDelay = 3f;               
            /// <summary>
            /// 摄像机控制
            /// </summary>
            public CameraControl m_CameraControl;       
            /// <summary>
            /// 消息文本
            /// </summary>
            public Text m_MessageText;                  
            /// <summary>
            /// 坦克预设
            /// </summary>
            public GameObject m_TankPrefab;             
            /// <summary>
            /// 坦克管理数组
            /// </summary>
            public TankManager[] m_Tanks;               
    
            /// <summary>
            /// 当前回合数
            /// </summary>
            private int m_RoundNumber;                  
            /// <summary>
            /// 回合开始后的等待时间
            /// </summary>
            private WaitForSeconds m_StartWait;         
            /// <summary>
            /// 回合结束后的等待时间
            /// </summary>
            private WaitForSeconds m_EndWait;           
            /// <summary>
            /// 回合获胜者
            /// </summary>
            private TankManager m_RoundWinner;          
            /// <summary>
            /// 游戏获胜者
            /// </summary>
            private TankManager m_GameWinner;                                   
    
    
            private void Start()
            {
                m_StartWait = new WaitForSeconds (m_StartDelay);
                m_EndWait = new WaitForSeconds (m_EndDelay);
    
                SpawnAllTanks();
                SetCameraTargets();
    
                //开启游戏主循环协程
                StartCoroutine (GameLoop ());
            }
    
            /// <summary>
            /// 孵化所有坦克
            /// </summary>
            private void SpawnAllTanks()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    m_Tanks[i].m_Instance =
                        Instantiate(m_TankPrefab, m_Tanks[i].m_SpawnPoint.position, m_Tanks[i].m_SpawnPoint.rotation) as GameObject;
                    m_Tanks[i].m_PlayerNumber = i + 1;
                    m_Tanks[i].Setup();
                }
            }
    
            /// <summary>
            /// 设置相机目标
            /// </summary>
            private void SetCameraTargets()
            {
                Transform[] targets = new Transform[m_Tanks.Length];
    
                for (int i = 0; i < targets.Length; i++)
                {
                    targets[i] = m_Tanks[i].m_Instance.transform;
                }
    
                m_CameraControl.m_Targets = targets;
            }
    
    
            /// <summary>
            /// 游戏循环协程
            /// </summary>
            /// <returns></returns>
            private IEnumerator GameLoop ()
            {
                yield return StartCoroutine (RoundStarting ());
    
                yield return StartCoroutine (RoundPlaying());
    
                yield return StartCoroutine (RoundEnding());
    
                if (m_GameWinner != null)
                {
                    SceneManager.LoadScene (0);
                }
                else
                {
                    StartCoroutine (GameLoop ());
                }
            }
    
            /// <summary>
            /// 回合准备协程
            /// </summary>
            /// <returns></returns>
            private IEnumerator RoundStarting ()
            {
                ResetAllTanks ();
                DisableTankControl ();
    
                m_CameraControl.SetStartPositionAndSize ();
    
                m_RoundNumber++;
                m_MessageText.text = "ROUND " + m_RoundNumber;
    
                yield return m_StartWait;
            }
    
            /// <summary>
            /// 回合开始协程
            /// </summary>
            /// <returns></returns>
            private IEnumerator RoundPlaying ()
            {
                EnableTankControl ();
    
                m_MessageText.text = string.Empty;
    
                while (!OneTankLeft())
                {
                    yield return null;
                }
            }
    
            /// <summary>
            /// 游戏结束协程
            /// </summary>
            /// <returns></returns>
            private IEnumerator RoundEnding ()
            {
                DisableTankControl ();
    
    
                m_RoundWinner = null;
    
                m_RoundWinner = GetRoundWinner ();
    
                if (m_RoundWinner != null)
                    m_RoundWinner.m_Wins++;
    
                m_GameWinner = GetGameWinner ();
    
                string message = EndMessage ();
                m_MessageText.text = message;
    
                yield return m_EndWait;
            }
    
    
            /// <summary>
            /// 检查激活的坦克数量是否小于等于1,用来设置这局游戏是否结束
            /// </summary>
            /// <returns></returns>
            private bool OneTankLeft()
            {
                int numTanksLeft = 0;
    
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    if (m_Tanks[i].m_Instance.activeSelf)
                        numTanksLeft++;
                }
    
                return numTanksLeft <= 1;
            }
            
            /// <summary>
            /// 获取每局的胜者
            /// </summary>
            /// <returns></returns>
            private TankManager GetRoundWinner()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    if (m_Tanks[i].m_Instance.activeSelf)
                        return m_Tanks[i];
                }
    
                return null;
            }
    
    
            /// <summary>
            /// 获取游戏的胜者
            /// </summary>
            /// <returns></returns>
            private TankManager GetGameWinner()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    if (m_Tanks[i].m_Wins == m_NumRoundsToWin)
                        return m_Tanks[i];
                }
    
                return null;
            }
    
    
            /// <summary>
            /// 每回合结束或游戏结束的消息
            /// </summary>
            /// <returns></returns>
            private string EndMessage()
            {
                //默认信息为平局
                string message = "DRAW!";
    
                //有回合赢家,显示这回合谁赢了
                if(m_RoundWinner != null)
                    message = m_RoundWinner.m_ColoredPlayerText + " WINS THE ROUND!";
    
                
                message += "
    
    
    
    ";
    
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    message += m_Tanks[i].m_ColoredPlayerText + ": " + m_Tanks[i].m_Wins + " WINS
    ";
                }
    
                if (m_GameWinner != null)
                    message = m_GameWinner.m_ColoredPlayerText + " WINS THE GAME!";
    
                return message;
            }
    
    
            /// <summary>
            /// 重置所有坦克
            /// </summary>
            private void ResetAllTanks()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    m_Tanks[i].Reset();
                }
            }
    
            /// <summary>
            /// 开启所有坦克的控制
            /// </summary>
            private void EnableTankControl()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    m_Tanks[i].EnableControl();
                }
            }
    
            /// <summary>
            /// 关闭所有坦克的控制
            /// </summary>
            private void DisableTankControl()
            {
                for (int i = 0; i < m_Tanks.Length; i++)
                {
                    m_Tanks[i].DisableControl();
                }
            }
        }
    }
    GameManager
    using System;
    using UnityEngine;
    
    namespace Complete
    {
        [Serializable]
        public class TankManager
        {
            /// <summary>
            /// 坦克颜色
            /// </summary>
            public Color m_PlayerColor;                             
            /// <summary>
            /// 坦克孵化点
            /// </summary>
            public Transform m_SpawnPoint;                          
            /// <summary>
            /// 玩家编号
            /// </summary>
            [HideInInspector] public int m_PlayerNumber;            
            /// <summary>
            /// 包含颜色的代表玩家的字符串
            /// </summary>
            [HideInInspector] public string m_ColoredPlayerText;    
            /// <summary>
            /// 坦克实例的引用
            /// </summary>
            [HideInInspector] public GameObject m_Instance;         
            /// <summary>
            /// 玩家已赢得的局数
            /// </summary>
            [HideInInspector] public int m_Wins;                    
            
            /// <summary>
            /// 坦克移动
            /// </summary>
            private TankMovement m_Movement;                        
            /// <summary>
            /// 坦克射击
            /// </summary>
            private TankShooting m_Shooting;                        
            /// <summary>
            /// 坦克游戏物体上的canvas
            /// </summary>
            private GameObject m_CanvasGameObject;                  
    
            /// <summary>
            /// 设置坦克
            /// </summary>
            public void Setup ()
            {
    
                m_Movement = m_Instance.GetComponent<TankMovement> ();
                m_Shooting = m_Instance.GetComponent<TankShooting> ();
                m_CanvasGameObject = m_Instance.GetComponentInChildren<Canvas> ().gameObject;
    
                m_Movement.m_PlayerNumber = m_PlayerNumber;
                m_Shooting.m_PlayerNumber = m_PlayerNumber;
    
                //设置带颜色的玩家名
                m_ColoredPlayerText = "<color=#" + ColorUtility.ToHtmlStringRGB(m_PlayerColor) + ">PLAYER " + m_PlayerNumber + "</color>";
    
                //获取并设置坦克及子物体的颜色
                MeshRenderer[] renderers = m_Instance.GetComponentsInChildren<MeshRenderer> ();
    
                for (int i = 0; i < renderers.Length; i++)
                {
                    renderers[i].material.color = m_PlayerColor;
                }
            }
    
    
            /// <summary>
            /// 关闭控制
            /// </summary>
            public void DisableControl ()
            {
                m_Movement.enabled = false;
                m_Shooting.enabled = false;
    
                m_CanvasGameObject.SetActive (false);
            }
    
    
            /// <summary>
            /// 开启控制
            /// </summary>
            public void EnableControl ()
            {
                m_Movement.enabled = true;
                m_Shooting.enabled = true;
    
                m_CanvasGameObject.SetActive (true);
            }
    
    
            /// <summary>
            /// 重置坦克状态
            /// </summary>
            public void Reset ()
            {
                m_Instance.transform.position = m_SpawnPoint.position;
                m_Instance.transform.rotation = m_SpawnPoint.rotation;
    
                m_Instance.SetActive (false);
                m_Instance.SetActive (true);
            }
        }
    }
    TankManager
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Complete
    {
        /// <summary>
        /// 坦克生命
        /// </summary>
        public class TankHealth : MonoBehaviour
        {
            /// <summary>
            /// 初始坦克生命
            /// </summary>
            public float m_StartingHealth = 100f;               
            /// <summary>
            /// 血量滑动条
            /// </summary>
            public Slider m_Slider;                             
            /// <summary>
            /// 血量滑动条的图片
            /// </summary>
            public Image m_FillImage;                           
            /// <summary>
            /// 坦克满血的滑动条颜色
            /// </summary>
            public Color m_FullHealthColor = Color.green;       
            /// <summary>
            /// 坦克没血的滑动条颜色
            /// </summary>
            public Color m_ZeroHealthColor = Color.red;         
            /// <summary>
            /// 坦克爆炸的预设
            /// </summary>
            public GameObject m_ExplosionPrefab;                
            
            /// <summary>
            /// 坦克爆炸的音效
            /// </summary>
            private AudioSource m_ExplosionAudio;               
            /// <summary>
            /// 坦克爆炸的粒子系统
            /// </summary>
            private ParticleSystem m_ExplosionParticles;        
            /// <summary>
            /// 坦克当前的血量
            /// </summary>
            private float m_CurrentHealth;                      
            /// <summary>
            /// 坦克是否死亡
            /// </summary>
            private bool m_Dead;                                             
    
    
            private void Awake ()
            {
                //实例化爆炸预设并获取爆炸粒子系统的引用
                m_ExplosionParticles = Instantiate (m_ExplosionPrefab).GetComponent<ParticleSystem> ();
    
                //获取爆炸的音效
                m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource> ();
    
                //禁用爆炸粒子系统
                m_ExplosionParticles.gameObject.SetActive (false);
            }
    
    
            private void OnEnable()
            {
                //设置当前血量为起始血量
                m_CurrentHealth = m_StartingHealth;
                //设置死亡标志位为false
                m_Dead = false;
    
                //修改血量UI
                SetHealthUI();
            }
    
            /// <summary>
            /// 坦克受到伤害
            /// </summary>
            /// <param name="amount"></param>
            public void TakeDamage (float amount)
            {
                //修改当前血量
                m_CurrentHealth -= amount;
    
                //修改血量UI
                SetHealthUI ();
    
                //如果死亡,当前血量<=0
                if (m_CurrentHealth <= 0f && !m_Dead)
                {
                    OnDeath ();
                }
            }
    
            /// <summary>
            /// 设置坦克血量UI
            /// </summary>
            private void SetHealthUI ()
            {
                //设置滑动条的值为当前血量
                m_Slider.value = m_CurrentHealth;
    
                //根据当前血量和起始血量的比值设置坦克的滑动条血量的颜色
                m_FillImage.color = Color.Lerp (m_ZeroHealthColor, m_FullHealthColor, m_CurrentHealth / m_StartingHealth);
            }
    
            /// <summary>
            /// 坦克死亡
            /// </summary>
            private void OnDeath ()
            {
                //设置死亡标志位 true
                m_Dead = true;
    
                //将爆炸粒子系统的位置移动到坦克的位置
                m_ExplosionParticles.transform.position = transform.position;
                m_ExplosionParticles.gameObject.SetActive (true);
    
                //播放爆炸粒子系统
                m_ExplosionParticles.Play ();
    
                //播放爆炸音效
                m_ExplosionAudio.Play();
    
                //禁用坦克
                gameObject.SetActive (false);
            }
        }
    }
    TankHealth
    using UnityEngine;
    
    namespace Complete
    {
        /// <summary>
        /// 坦克移动
        /// </summary>
        public class TankMovement : MonoBehaviour
        {
            /// <summary>
            /// 玩家编号
            /// </summary>
            public int m_PlayerNumber = 1;              
            /// <summary>
            /// 坦克的移动速度
            /// </summary>
            public float m_Speed = 12f;                 
            /// <summary>
            /// 坦克的转向速度
            /// </summary>
            public float m_TurnSpeed = 180f;            
            /// <summary>
            /// 移动声源
            /// </summary>
            public AudioSource m_MovementAudio;           
            /// <summary>
            /// 空闲时的声音
            /// </summary>
            public AudioClip m_EngineIdling;            
            /// <summary>
            /// 移动时的声音
            /// </summary>
            public AudioClip m_EngineDriving;           
            /// <summary>
            /// 音高范围
            /// </summary>
            public float m_PitchRange = 0.2f;           
    
            /// <summary>
            /// 控制前后移动的轴名
            /// </summary>
            private string m_MovementAxisName;          
            /// <summary>
            /// 控制
            /// </summary>
            private string m_TurnAxisName;              
            /// <summary>
            /// 刚体
            /// </summary>
            private Rigidbody m_Rigidbody;              
    
            /// <summary>
            /// 移动输入
            /// </summary>
            private float m_MovementInputValue;         
            /// <summary>
            /// 转向输入
            /// </summary>
            private float m_TurnInputValue;             
            /// <summary>
            /// 原始音高
            /// </summary>
            private float m_OriginalPitch;                           
    
    
            private void Awake ()
            {
                m_Rigidbody = GetComponent<Rigidbody> ();
            }
    
    
            private void OnEnable ()
            {
    
                m_Rigidbody.isKinematic = false;
    
                m_MovementInputValue = 0f;
                m_TurnInputValue = 0f;
            }
    
    
            private void OnDisable ()
            {
                m_Rigidbody.isKinematic = true;
            }
    
            private void Start ()
            {
                //通过玩家编号获取输入轴
                m_MovementAxisName = "Vertical" + m_PlayerNumber;
                m_TurnAxisName = "Horizontal" + m_PlayerNumber;
    
                //存储原始音高
                m_OriginalPitch = m_MovementAudio.pitch;
            }
    
    
            private void Update ()
            {
                //获取输入轴的值
                m_MovementInputValue = Input.GetAxis (m_MovementAxisName);
                m_TurnInputValue = Input.GetAxis (m_TurnAxisName);
    
                EngineAudio ();
            }
    
            /// <summary>
            /// 处理引擎的声音
            /// </summary>
            private void EngineAudio ()
            {
                //如果没有输入
                if (Mathf.Abs (m_MovementInputValue) < 0.1f && Mathf.Abs (m_TurnInputValue) < 0.1f)
                {
                    //如果正在播放移动的声音
                    if (m_MovementAudio.clip == m_EngineDriving)
                    {
                        //播放闲置的声音
                        m_MovementAudio.clip = m_EngineIdling;
                        m_MovementAudio.pitch = Random.Range (m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
                        m_MovementAudio.Play ();
                    }
                }
                //如果有输入
                else
                {
                    //如果正在播放闲置的声音
                    if (m_MovementAudio.clip == m_EngineIdling)
                    {
                        //播放移动的声音
                        m_MovementAudio.clip = m_EngineDriving;
                        m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
                        m_MovementAudio.Play();
                    }
                }
            }
    
    
            private void FixedUpdate ()
            {
                //移动
                Move ();
                //旋转
                Turn ();
            }
    
            /// <summary>
            /// 移动
            /// </summary>
            private void Move ()
            {
                //创建一个坦克的速度向量
                Vector3 movement = transform.forward * m_MovementInputValue * m_Speed * Time.deltaTime;
    
                //刚体移动
                m_Rigidbody.MovePosition(m_Rigidbody.position + movement);
            }
    
            /// <summary>
            /// 旋转
            /// </summary>
            private void Turn ()
            {
                //根据输入,旋转速度以及每帧的时间计算旋转的值
                float turn = m_TurnInputValue * m_TurnSpeed * Time.deltaTime;
    
                //创建y轴的四元数旋转
                Quaternion turnRotation = Quaternion.Euler (0f, turn, 0f);
    
                //刚体旋转
                m_Rigidbody.MoveRotation (m_Rigidbody.rotation * turnRotation);
            }
        }
    }
    TankMovement
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Complete
    {
        /// <summary>
        /// 坦克射击
        /// </summary>
        public class TankShooting : MonoBehaviour
        {
            /// <summary>
            /// 玩家编号
            /// </summary>
            public int m_PlayerNumber = 1;              
            /// <summary>
            /// 炮弹刚体
            /// </summary>
            public Rigidbody m_Shell;                   
            /// <summary>
            /// 射击的位置
            /// </summary>
            public Transform m_FireTransform;           
            /// <summary>
            /// 射击的箭头滑动条
            /// </summary>
            public Slider m_AimSlider;                  
            /// <summary>
            /// 发射声音
            /// </summary>
            public AudioSource m_ShootingAudio;         
            /// <summary>
            /// 充能声音
            /// </summary>
            public AudioClip m_ChargingClip;            
            /// <summary>
            /// 开火声音
            /// </summary>
            public AudioClip m_FireClip;                
            /// <summary>
            /// 发射炮弹最小的力
            /// </summary>
            public float m_MinLaunchForce = 15f;        
            /// <summary>
            /// 发射炮弹最大的力
            /// </summary>
            public float m_MaxLaunchForce = 30f;        
            /// <summary>
            /// 发射炮弹的最大充能时间
            /// </summary>
            public float m_MaxChargeTime = 0.75f;       
    
            /// <summary>
            /// 控制发射的轴名
            /// </summary>
            private string m_FireButton;                
            /// <summary>
            /// 当前的发射力
            /// </summary>
            private float m_CurrentLaunchForce;                                               
            /// <summary>
            /// 充能速度
            /// </summary>
            private float m_ChargeSpeed;                
            /// <summary>
            /// 是否已发射
            /// </summary>
            private bool m_Fired;                         
    
    
            private void OnEnable()
            {
                //重置当前发射力和箭头滑动条的值
                m_CurrentLaunchForce = m_MinLaunchForce;
                m_AimSlider.value = m_MinLaunchForce;
            }
    
    
            private void Start ()
            {
                //根据玩家编号设置 发射的轴名
                m_FireButton = "Fire" + m_PlayerNumber;
    
                //计算发射充能
                m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
            }
    
    
            private void Update ()
            {
                //设置箭头滑动条的值
                m_AimSlider.value = m_MinLaunchForce;
    
                //如果当前的发射力大于最大发射力,并且没有发射
                if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
                {
                    //用最大发射力发射
                    m_CurrentLaunchForce = m_MaxLaunchForce;
                    Fire ();
                }
                //如果按下了发射按钮
                else if (Input.GetButtonDown (m_FireButton))
                {
                    //设置发射标志位为false
                    m_Fired = false;
                    //设置当前发射力为最小力
                    m_CurrentLaunchForce = m_MinLaunchForce;
    
                    //播放充能声音
                    m_ShootingAudio.clip = m_ChargingClip;
                    m_ShootingAudio.Play ();
                }
                //如果发射按钮被按住且炮弹并没有发射
                else if (Input.GetButton (m_FireButton) && !m_Fired)
                {
                    //更新当前发射力
                    m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;
                    //更新箭头滑动条的值
                    m_AimSlider.value = m_CurrentLaunchForce;
                }
                //如果发射键松开且炮弹没有发射
                else if (Input.GetButtonUp (m_FireButton) && !m_Fired)
                {
                    //发射炮弹
                    Fire ();
                }
            }
    
            /// <summary>
            /// 发射
            /// </summary>
            private void Fire ()
            {
                //设置发射标志位
                m_Fired = true;
    
                //获取炮弹刚体的引用
                Rigidbody shellInstance =
                    Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
    
                //设置刚体的速度
                shellInstance.velocity = m_CurrentLaunchForce * m_FireTransform.forward; 
    
                //播放发射声音
                m_ShootingAudio.clip = m_FireClip;
                m_ShootingAudio.Play ();
    
                //重置当前发射力为最小发射力
                m_CurrentLaunchForce = m_MinLaunchForce;
            }
        }
    }
    TankShooting
    using UnityEngine;
    
    namespace Complete
    {
        /// <summary>
        /// 炮弹爆炸
        /// </summary>
        public class ShellExplosion : MonoBehaviour
        {
            /// <summary>
            /// 坦克层
            /// </summary>
            public LayerMask m_TankMask;                        
            public ParticleSystem m_ExplosionParticles;         
            /// <summary>
            /// 爆炸声源
            /// </summary>
            public AudioSource m_ExplosionAudio;                
            /// <summary>
            /// 最大伤害
            /// </summary>
            public float m_MaxDamage = 100f;                    
            /// <summary>
            /// 爆炸力
            /// </summary>
            public float m_ExplosionForce = 1000f;              
            /// <summary>
            /// 炮弹的生命周期
            /// </summary>
            public float m_MaxLifeTime = 2f;                    
            /// <summary>
            /// 爆炸半径
            /// </summary>
            public float m_ExplosionRadius = 5f;                  
    
    
            private void Start ()
            {
                //如果炸弹没有被销毁,经过指定时间后自动销毁
                Destroy (gameObject, m_MaxLifeTime);
            }
    
    
            private void OnTriggerEnter (Collider other)
            {
                //以炮弹为中心,爆炸半径为半径发射相交球
                Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask);
    
                //循环遍历碰撞体
                for (int i = 0; i < colliders.Length; i++)
                {
                    //获取目标刚体
                    Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody> ();
    
                    //如果没有刚体,则继续检测下一个
                    if (!targetRigidbody)
                        continue;
    
                    //目标刚体添加爆炸力
                    targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius);
    
                    //获取目标的血量
                    TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> ();
    
                    //如果没有,检测下一个
                    if (!targetHealth)
                        continue;
    
                    //根据目标位置计算伤害
                    float damage = CalculateDamage (targetRigidbody.position);
    
                    //目标受到伤害
                    targetHealth.TakeDamage (damage);
                }
    
                
                m_ExplosionParticles.transform.parent = null;
    
                //播放爆炸粒子效果
                m_ExplosionParticles.Play();
    
                //播放爆炸声音
                m_ExplosionAudio.Play();
    
                //定时销毁粒子系统
                Destroy (m_ExplosionParticles.gameObject, m_ExplosionParticles.duration);
    
                //销毁炮弹
                Destroy (gameObject);
            }
    
            /// <summary>
            /// 计算伤害
            /// </summary>
            /// <param name="targetPosition">目标位置</param>
            /// <returns></returns>
            private float CalculateDamage (Vector3 targetPosition)
            {
                //创建一个从自身到目标的向量
                Vector3 explosionToTarget = targetPosition - transform.position;
    
                //计算这个向量的模
                float explosionDistance = explosionToTarget.magnitude;
    
                //计算相对距离
                float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius;
    
                //根据距离比例和最大伤害计算伤害
                float damage = relativeDistance * m_MaxDamage;
    
                //确保最小伤害为0
                damage = Mathf.Max (0f, damage);
    
                return damage;
            }
        }
    }
    ShellExplosion
    using UnityEngine;
    
    namespace Complete
    {
        /// <summary>
        /// UI朝向控制
        /// </summary>
        public class UIDirectionControl : MonoBehaviour
        {
            /// <summary>
            /// 是否使用相对旋转
            /// </summary>
            public bool m_UseRelativeRotation = true;       
    
            /// <summary>
            /// 局部旋转
            /// </summary>
            private Quaternion m_RelativeRotation;                        
    
    
            private void Start ()
            {
                //局部旋转为父对象的局部旋转
                m_RelativeRotation = transform.parent.localRotation;
            }
    
    
            private void Update ()
            {
                if (m_UseRelativeRotation)
                    transform.rotation = m_RelativeRotation;
            }
        }
    }
    UIDirectionControl

    视频:https://pan.baidu.com/s/1eRFbQYA

    项目:https://pan.baidu.com/s/1midmmuc

  • 相关阅读:
    python3随记——字符编码
    python基础3(元祖、字典、深浅copy、集合、文件处理)
    python的颜色显示
    python基础2(数据类型、数据运算、for循环、while循环、列表)
    python基础之初始python
    0423作业(函数)
    0423上课练习(list、while、def)
    函数的定义与调用(4.23)
    0422作业:基础(if,while)
    while,for,if输入账号密码判断(还请各位大牛能够优化,本人刚学习一周)
  • 原文地址:https://www.cnblogs.com/revoid/p/6435223.html
Copyright © 2011-2022 走看看