美文网首页
VR开发实战HTC Vive项目之星球大战

VR开发实战HTC Vive项目之星球大战

作者: TonyWan_AR | 来源:发表于2019-01-29 18:32 被阅读107次

    一、框架视图

    二、主要代码

    Indoor

    AnimatorSetup

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AnimatorSetup  {
        public float speedDampTime=0.1f;  //缓冲时间
        public float angularSpeedDampTime = 0.7f;
        public float angleResponseTime = 1f;
        private Animator anim;
        private HashIDs hash;
    
        /// <summary>
        /// 构造函数
        /// </summary>
        public  AnimatorSetup(Animator anim,HashIDs hash) {
            this.anim = anim;
            this.hash = hash;
        }
    
    
        public void Setup(float speed, float angle) {
            float angularSpeed = angle / angleResponseTime;
            anim.SetFloat(hash.speedFloat,speed,speedDampTime,Time.deltaTime);
            anim.SetFloat(hash.angularSpeedFloat,angularSpeed,angularSpeedDampTime,Time.deltaTime);
        }
    }
    
    

    FadeInOut

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    /// <summary>
    /// 屏幕淡入淡出效果
    /// </summary>
    public class FadeInOut : MonoBehaviour {
    
        public  float fadeSpeed=0.2f;
        private bool sceneStarting = true;
         //private GUITexture tex;
        private RawImage tex;
        void Start () {
    
            //tex = this.GetComponent<GUITexture>();
            tex = this.GetComponent<RawImage>();
            //tex.pixelInset = new Rect(0,0,Screen.width,Screen.height);
        }
        void Update () {
            if (sceneStarting)
            {
                StartScene();
            }
        }
    
        //渐入
        private void FadeToClear() {
    
            tex.color = Color.Lerp(tex.color,Color.clear,fadeSpeed*Time.deltaTime);
    
        }
    
        //渐出
        private void FadeToBlack() {
    
            tex.color = Color.Lerp(tex.color,Color.black,fadeSpeed*Time.deltaTime);
        }
    
        /// <summary>
        /// 进入场景
        /// </summary>
        public void StartScene() {
    
            FadeToClear();
            if (tex.color.a<=0.05f)
            {
                tex.color = Color.clear;
                //tex.enabled = false;
                sceneStarting = false;
            }
        }
    
    
        /// <summary>
        /// 结束场景
        /// </summary>
        public void EndScene() {
          
            sceneStarting = true;
            FadeToBlack();
            if (tex.color.a>=0.95f)
            {
                //SceneManager.LoadScene("Indoor");
                SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    
            }
        }
    
    
        /// <summary>
        /// 进入下一个场景
        /// </summary>
        public void NextScene() {
            sceneStarting = true;
            FadeToBlack();
            if (tex.color.a >= 0.95f)
            {
                SceneManager.LoadScene("Outdoor");
            }
        }
    }
    
    

    fps_Crosshair

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 武器设置以及准星绘制
    /// </summary>
    public class fps_Crosshair : MonoBehaviour {
    
    
        public float length;
        public float width;
        public float distance;
        public Texture2D crosshairTexture;
    
    
    
        public GUIStyle lineStyle;
        private Texture tex;
    
        void Start () {
    
            lineStyle = new GUIStyle();
            lineStyle.normal.background = crosshairTexture;
        }
        
        
        void Update () {
            
        }
    
    
        /// <summary>
        /// 绘制准星
        /// </summary>
        void OnGUI() {
    
            GUI.Box(new Rect((Screen.width-distance)/2-length,(Screen.height-width)/2,length,width),tex,lineStyle);
            GUI.Box(new Rect((Screen.width+distance)/2,(Screen.height-width)/2,length,width),tex,lineStyle);
            GUI.Box(new Rect((Screen.width-width)/2,(Screen.height-distance)/2 - length, width,length),tex,lineStyle);
            GUI.Box(new Rect((Screen.width- width) /2,(Screen.height+distance)/2, width,length),tex,lineStyle);
    
        }
    
    }
    
    

    fps_DoorControl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 静态滑动门设置-1
    /// </summary>
    public class fps_DoorControl : MonoBehaviour {
    
        public int doorId;  //门的id号
        public Vector3 from; //原始位置
        public Vector3 to;//滑动位置
        public float fadeSpeed=5; //滑动速度
        public bool requireKey = false; //通过钥匙打开
        public AudioClip doorSwitchClip; //开门声效
        public AudioClip accessDeniedClip; //进入声效
    
    
        private Transform door; //获取门
        private GameObject player;  //玩家
        private AudioSource audioSource; //声效
        private fps_PlayerInventory playerInventory;  
        private int count;
        public int Count {
            get { return count; }
            set {
                if (count == 0 && value == 1 || count == 1 && value == 0)
                {
                    audioSource.clip = doorSwitchClip;
                    audioSource.Play();
                }
                count = value;
            }
        }
    
    
        void Start() {
    
            if (transform.childCount > 0)
            {
                door = transform.GetChild(0);
            }
            player = GameObject.FindGameObjectWithTag(Tags.player);
            audioSource = this.GetComponent<AudioSource>();
            playerInventory = player.GetComponent<fps_PlayerInventory>();
            door.localPosition = from;
        }
    
    
        void Update() {
    
            if (Count>0)
            {
                door.localPosition = Vector3.Lerp(door.localPosition, to, fadeSpeed * Time.deltaTime);
               // Debug.Log("Count++" + Count);
            }
            else
            {
                door.localPosition = Vector3.Lerp(door.localPosition, from, fadeSpeed * Time.deltaTime);
            }
    
    
        }
    
    
        /// <summary>
        /// 进入触发器
        /// </summary>
        /// <param name="other"></param>
        void OnTriggerEnter(Collider other) {
    
            Debug.Log("进入门的触发器");
    
            if (other.gameObject == player)
            {
                if (requireKey)
                {
    
                    if (playerInventory.HasKey(doorId))
                    {
                        Count++;
                    }
                    else
                    {
                        audioSource.clip = accessDeniedClip;
                        audioSource.Play();
                    }
                }
                else
                {
                    Count++;
                }
            }
            else if (other.gameObject.tag == Tags.enemy && other is CapsuleCollider)
            {
                Count++;
            }
    
         
        }
    
        /// <summary>
        /// 离开触发器
        /// </summary>
        void OnTriggerExit(Collider other) {
    
            Debug.Log("离开门的触发器");
            if (other.gameObject == player||other.gameObject.tag==Tags.enemy&&other is CapsuleCollider)
            {
                Count = Mathf.Max(0,Count-1);
            }
        }
    
    
    }
    
    

    fps_EnemyAI

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class fps_EnemyAI : MonoBehaviour {
    
        public float patrolSpeed = 2f; //巡逻时间
        public float chaseSpeed = 5f;   //追击时间
        public float chaseWaitTime = 5f;
        public float patrolWaitTime = 1f;
        public Transform[] patrolWayPoint;//寻路点
    
        private fps_EnemySight enemySight;
        private NavMeshAgent nav;
        private Transform player;
        private fps_PlayerHealth playHealth ; //玩家血量  
        private float chaseTimer;
        private float patrolTimer;
        private int wayPointIndex;
    
        void Start() {
    
            enemySight = this.GetComponent<fps_EnemySight>();
            nav = this.GetComponent<NavMeshAgent>();
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            playHealth = player.GetComponent<fps_PlayerHealth>();
    
        }
    
    
        void Update() {
    
            if (enemySight.playerInSight && playHealth.hp > 0)
            {
                Shooting();
            }
            else if (enemySight.playerPosition != enemySight.resetPosition && playHealth.hp > 0)
            {
                Chasing();
            }
            else
            {
                Patrolling();
            }
    
    
    
    
        }
    
        /// <summary>
        /// 设置寻路点
        /// </summary>
        private void Shooting() {
            nav.SetDestination(transform.position);
        }
    
        /// <summary>
        /// 追击
        /// </summary>
        private void Chasing() {
            Vector3 sightingDeltaPos = enemySight.playerPosition - transform.position;
    
            if (sightingDeltaPos.sqrMagnitude > 4f)
            {
                nav.destination = enemySight.playerPosition;
            }
    
            nav.speed = chaseSpeed;
    
            if (nav.remainingDistance < nav.stoppingDistance)
            {
                chaseTimer += Time.deltaTime;
                if (chaseTimer >= chaseWaitTime)
                {
                    enemySight.playerPosition = enemySight.resetPosition;
                    chaseTimer = 0;
                }
            }
            else
            {
                chaseTimer = 0;
            }
    
    
        }
    
        /// <summary>
        /// 巡逻
        /// </summary>
        private void Patrolling() {
    
            nav.speed = patrolSpeed;
            if (nav.destination == enemySight.resetPosition||nav.remainingDistance<nav.stoppingDistance)
            {
                patrolTimer += Time.deltaTime;
    
                if (patrolTimer>=patrolWaitTime)
                {
                    if (wayPointIndex==patrolWayPoint.Length-1)
                    {
                        wayPointIndex = 0;
                    }
                    else
                    {
                        wayPointIndex++;
                    }
                    patrolTimer = 0;
                }
            }
            else
            {
                patrolTimer = 0;
            }
    
            nav.destination = patrolWayPoint[wayPointIndex].position;
        }
    
    
    }
    
    

    fps_EnemyAnimation

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class fps_EnemyAnimation : MonoBehaviour {
    
        public float deadZone = 5f;
    
        private Transform player;
        private fps_EnemySight enemySight;
        private NavMeshAgent nav;
        private Animator anim;
        private HashIDs hash;
        private AnimatorSetup animSetup;
    
        void Start() {
    
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            enemySight = this.GetComponent<fps_EnemySight>();
            nav = this.GetComponent<NavMeshAgent>();
            anim = this.GetComponent<Animator>();
            hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
            animSetup = new AnimatorSetup(anim, hash);
    
            nav.updateRotation = false;
            anim.SetLayerWeight(1, 1f); //设置权重
            anim.SetLayerWeight(2, 1f);
    
            deadZone *= Mathf.Deg2Rad;  //弧度
        }
    
    
        void Update() {
            NavAnimSetup();
        }
    
        //动画内置函数
        void OnAnimatorMove() {
            nav.velocity = anim.deltaPosition / Time.deltaTime;
            transform.rotation = anim.rootRotation;
    
        }
    
    
        void NavAnimSetup() {
            float speed;
            float angle;
    
            if (enemySight.playerInSight)
            {
                speed = 0;
                angle = FindAngle(transform.forward,player.position-transform.position,transform.up);
            }
            else
            {
                speed = Vector3.Project(nav.desiredVelocity,transform.forward).magnitude;
                angle = FindAngle(transform.forward,nav.desiredVelocity,transform.up);
    
                if (Mathf.Abs(angle)<deadZone)
                {
                    transform.LookAt(transform.position+nav.desiredVelocity);
                    angle = 0;
                }
            }
    
            animSetup.Setup(speed,angle);
        }
    
        private float FindAngle(Vector3 formVector,Vector3 toVector,Vector3 upVector){
            if (toVector==Vector3.zero)
                return 0f;
            float angle = Vector3.Angle(formVector,toVector);
            Vector3 nomal = Vector3.Cross(formVector,toVector);
            angle *= Mathf.Sign(Vector3.Dot(nomal,upVector));
            angle *= Mathf.Deg2Rad;
            return angle;
    
        }
    }
    
    

    fps_EnemyHealth

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class fps_EnemyHealth : MonoBehaviour {
    
        public float hp = 100;
        private Animator anim;
        private HashIDs hash;
        private bool isDead=false;
    
    
        void Start () {
    
            anim = this.GetComponent<Animator>();
            hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
    
    
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 如果被枪打中的话调用此方法
        /// </summary>
        /// <param name="damage"></param>
        public void TakeDamage(float damage) {
    
            hp -= damage;
            if (hp<=0&&!isDead)
            {
                isDead = true;
                GetComponent<CapsuleCollider>().enabled=false;
                GetComponent<fps_EnemyAnimation>().enabled=false;
                GetComponent<fps_EnemyAI>().enabled=false;
                GetComponent<fps_EnemySight>().enabled=false;
                GetComponent<fps_EnemyShoot>().enabled=false;
                GetComponent<UnityEngine.AI.NavMeshAgent>().enabled=false;
                GetComponentInChildren<Light>().enabled = false;
                GetComponentInChildren<LineRenderer>().enabled = false;
    
                anim.SetBool(hash.playerInSightBool,false);
                anim.SetBool(hash.deadBool,true);
    
                //销毁
                Destroy(gameObject,2f);
            }
    
        }
    
    }
    
    
    

    fps_EnemyShoot

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class fps_EnemyShoot : MonoBehaviour {
    
        public float maximumDamage = 120;
        public float minimumDamage=45;
        public AudioClip shotClip;
        public float flashIntensity = 3f; //闪烁强度
        public float fadeSpeed = 10f;
    
        private Animator anim;
        private HashIDs hash;
        private LineRenderer laserShotLine;
        private Light laserShotLight; //光的特效
        private SphereCollider col;
        private Transform player;
        private fps_PlayerHealth playerHealth; //玩家血量
        private bool shooting;
        private float scaleDamage;
    
    
        void Start () {
    
            anim = this.GetComponent<Animator>();
            laserShotLine = this.GetComponentInChildren<LineRenderer>();
            laserShotLight = laserShotLine.gameObject.GetComponent<Light>();
    
            col = this.GetComponentInChildren<SphereCollider>();
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            playerHealth = player.GetComponent<fps_PlayerHealth>();
            hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
    
            laserShotLine.enabled = false;
            laserShotLight.intensity = 0;
    
            scaleDamage = maximumDamage - minimumDamage;
           
    
        }
        
        
        void Update () {
            
            float shot=anim.GetFloat(hash.shotFloat);
           // Debug.Log("射击:::"+shot);
            
            if (shot>0.05f&&!shooting)  //不断监听 符合条件调用射击的方法
            {
                Shoot();
            }
            if (shot<0.05f)
            {
                shooting = false;
                laserShotLine.enabled = false;
            }
    
            laserShotLight.intensity = Mathf.Lerp(laserShotLight.intensity,0f,fadeSpeed*Time.deltaTime);
        }
    
        void OnAnimatorIK(int layerIndex) {
            float aimWeight = anim.GetFloat(hash.aimWeightFloat);
            anim.SetIKPosition(AvatarIKGoal.RightHand,player.position+Vector3.up*1.5f);
            anim.SetIKPositionWeight(AvatarIKGoal.RightHand,aimWeight);
        }
    
    
        /// <summary>
        /// 射击
        /// </summary>
        public void Shoot() {
    
            shooting = true;
            float fractionalDitance = (col.radius - Vector3.Distance(transform.position, player.position)) / col.radius;
            float damage = scaleDamage * fractionalDitance + minimumDamage;
            playerHealth.TakeDamage(damage);
    
            //调用枪的特效
            ShotEffects();
    
        }
    
        /// <summary>
        /// 枪的特效
        /// </summary>
        private void ShotEffects() {
            laserShotLine.SetPosition(0,laserShotLine.transform.position);
            laserShotLine.SetPosition(1,player.position+Vector3.up*1.5f); //射击的第二个位置点
            laserShotLine.enabled = true;
            laserShotLight.intensity = flashIntensity;
            // AudioSource.PlayClipAtPoint(shotClip,laserShotLight.transform.position);
            AudioSource.PlayClipAtPoint(shotClip, transform.position);
        }
    
    
    
    }
    
    

    fps_EnemySight

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    
    public class fps_EnemySight : MonoBehaviour {
    
        public float fieldOfViewAngle = 110f;
    
        public bool playerInSight;
    
        public Vector3 playerPosition;
    
        public Vector3 resetPosition=Vector3.zero;
    
      
    
        private NavMeshAgent nav;
        private SphereCollider col;
        private Animator anim;
        private  GameObject player;
        private fps_PlayerHealth playerHealth;
        private HashIDs hash;
        private fps_PlayerControl playerControl;
    
    
        
    
        void Start () {
    
            nav = this.GetComponent<NavMeshAgent>();
            col = GetComponentInChildren<SphereCollider>();
            anim = this.GetComponent<Animator>();
            player = GameObject.FindGameObjectWithTag(Tags.player);
            playerHealth = player.GetComponent<fps_PlayerHealth>();
            playerControl = player.GetComponent<fps_PlayerControl>();
    
            hash =GameObject.FindGameObjectWithTag("GameController").GetComponent<HashIDs>();
    
            fps_GunScripts.PlayerShootEvent += ListenPlayer;
        }
        
        
        void Update () {
    
            //判断如果玩家的血量大于0
            if (playerHealth.hp>0)
            {
                anim.SetBool(hash.playerInSightBool,playerInSight);//1205
                //anim.SetBool("PlayerInSight", playerInSight); //靠近玩家范围开始攻打
               // anim.SetBool(hash.playerInSightBool, true);
            }
            else
            {
                anim.SetBool(hash.playerInSightBool,false);
            }
    
        }
    
    
        void OnTriggerStay(Collider other) {
           // Debug.Log("进入视野范围之内");
    
            if (other.gameObject.tag == "Player")
            {
                playerInSight = false;
    
                Vector3 direction = other.transform.position - transform.position;
                float angle = Vector3.Angle(direction,transform.forward);
    
                if (angle<fieldOfViewAngle*0.5f)
                {
                    RaycastHit hit;
                    if (Physics.Raycast(transform.position+transform.up,direction,out hit))  //1204
                    {
                        if (hit.collider.gameObject==player)
                        {
                            playerInSight = true;
                            playerPosition = player.transform.position;
                           // Debug.Log("进入范围");
                        }
                    }
    
                }
    
    
                //判断如果玩家处于行走或者跑步状态  哪就监听玩家  调用监听玩家的函数
                if (playerControl.State==PlayerState.Walk||playerControl.State==PlayerState.Run)
                {
                    ListenPlayer();
                }
                
    
            }
        }
    
        /// <summary>
        /// 退出触发器
        /// </summary>
        void OnTriggerExit(Collider other) {
    
           // Debug.Log("退出视野范围");
            if (other.gameObject == player)
            {
                playerInSight = false;
            }
    
        }
    
    
    
        /// <summary>
        /// 监听玩家的方法
        /// </summary>
        private void ListenPlayer()
        {
            if (Vector3.Distance(player.transform.position,transform.position)<=col.radius)
            {
                playerPosition = player.transform.position;
            }
        }
    
    
        /// <summary>
        /// 销毁时调用的函数
        /// </summary>
        void OnDestroy() {
    
            //注销监听的方法 -=ListenPlayer
            fps_GunScripts.PlayerShootEvent -= ListenPlayer;
            Debug.Log("销毁--注销监听");
        }
    }
    
    
    

    fps_ExitTrigger

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 出口制作
    /// </summary>
    public class fps_ExitTrigger : MonoBehaviour {
    
        public float timeToInactivePlayer=2.0f;
        public float timeToRestart = 2.0f;
    
        private GameObject player;
        private bool playerInExit;
        private float timer;
        private FadeInOut fader;
    
    
        void Start () {
    
            player = GameObject.FindGameObjectWithTag(Tags.player);
            fader = GameObject.FindGameObjectWithTag(Tags.fader).GetComponent<FadeInOut>();
    
        }
        
        
        void Update () {
            if (playerInExit)
            {
                InExitActivation();
            }
        }
    
        /// <summary>
        /// 进入出口范围
        /// </summary>
        /// <param name="other"></param>
        void OnTriggerEnter(Collider other) {
    
            //Debug.Log("进入触发器");
    
            if (other.gameObject==player)
            {
                playerInExit = true;
                timer = 0;
            }
    
        }
    
    
        /// <summary>
        /// 离开触发范围
        /// </summary>
        void OnTriggerExit(Collider other) {
    
            Debug.Log("退出 离开范围");
            if (other.gameObject==player)
            {
                playerInExit = false;
                timer = 0;
            }
    
    
        }
    
    
        /// <summary>
        /// 激活出口
        /// </summary>
        private void InExitActivation() {
    
            timer += Time.deltaTime;
            if (timer>=timeToInactivePlayer)
            {
                player.GetComponent<fps_PlayerHealth>().DisableInput();
            }
    
            if (timer>=timeToRestart)
            {
                //fader.EndScene();
                fader.NextScene();
    
            }
    
        }
    
    
    }
    
    
    

    fps_FPCamera

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 控制相机的旋转逻辑  鼠标和按键
    /// </summary>
    [RequireComponent(typeof(Camera))]
    public class fps_FPCamera : MonoBehaviour {
    
        public Vector2 mouseLookSensitivity = new Vector2(5,5);
        public Vector2 rotationXLimit = new Vector2(87,-87);
        public Vector2 rotationYLimit = new Vector2(-360,360);
        public Vector3 positionOffset = new Vector3(0,2,-0.2f);
    
    
        private Vector2 currentMouseLook = Vector2.zero;
        private float x_Angle = 0;
        private float y_Angle = 0;
        private fps_PlayerParemeter paremeter;
        private Transform m_Transform;
        
        void Start () {
            paremeter = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerParemeter>();
            m_Transform= transform;
            m_Transform.localPosition = positionOffset;
    
        }
        
        
        void Update () {
            UpdateInput();
    
        }
    
        void LateUpdate() {
            Quaternion xQuaternion = Quaternion.AngleAxis(y_Angle,Vector3.up);
            Quaternion yQuaternion = Quaternion.AngleAxis(0,Vector3.left);
            m_Transform.parent.rotation = xQuaternion * yQuaternion;
    
            yQuaternion = Quaternion.AngleAxis(-x_Angle,Vector3.left);
            m_Transform.rotation = xQuaternion * yQuaternion;
        }
    
    
        private void UpdateInput() {
    
            if (paremeter.inputSmoothLook==Vector2.zero)
            {
                return;
            }
            GetMouseLook();
            y_Angle += currentMouseLook.x;
            x_Angle += currentMouseLook.y;
    
            y_Angle = y_Angle < -360 ? y_Angle += 360 : y_Angle;
            y_Angle = y_Angle > 360 ? y_Angle -= 360 : y_Angle;
            y_Angle = Mathf.Clamp(y_Angle,rotationYLimit.x,rotationYLimit.y);
    
            x_Angle = x_Angle < -360 ? x_Angle += 360 : x_Angle;
            x_Angle = x_Angle > 360 ? x_Angle -= 360 : x_Angle;
            x_Angle = Mathf.Clamp(x_Angle, -rotationXLimit.x, -rotationXLimit.y);
    
        }
    
        /// <summary>
        /// 鼠标的观看角度
        /// </summary>
        private void GetMouseLook() {
    
            currentMouseLook.x = paremeter.inputSmoothLook.x;
            currentMouseLook.y = paremeter.inputSmoothLook.y;
    
            currentMouseLook.x *= mouseLookSensitivity.x;
            currentMouseLook.y *= mouseLookSensitivity.y;
    
            currentMouseLook.y *= -1;
    
        }
    
    
    
    }
    
    

    fps_FPInput

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 玩家输入
    /// </summary>
    public class fps_FPInput : MonoBehaviour {
    
        public bool LockCursor {
            get { return Cursor.lockState == CursorLockMode.Locked ? true : false; }
            set {
                Cursor.visible = value;
                Cursor.lockState = value ? CursorLockMode.Locked : CursorLockMode.None;
            }
        }
    
        private fps_PlayerParemeter paremeter;
        private fps_Input input;
    
        void Start() {
    
            LockCursor = true;
            paremeter = this.GetComponent<fps_PlayerParemeter>();
            input = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<fps_Input>();
        }
    
        void Update() {
            InitialInput();
        }
    
        /// <summary>
        /// 监听输入
        /// </summary>
        private void InitialInput() {
            paremeter.inputMoveVector = new Vector2(input.GetAxis("Horizontal"),input.GetAxis("Vertical"));
            paremeter.inputSmoothLook = new Vector2(input.GetAxisRaw("Mouse X"), input.GetAxisRaw("Mouse Y"));
            paremeter.inputCrouch = input.GetButton("Crouch");
            paremeter.inputJump = input.GetButton("Jump");
            paremeter.inputSprint = input.GetButton("Sprint");
            paremeter.inputFire = input.GetButton("Fire");
            paremeter.inputReload = input.GetButton("Reload");
        }
    
    
    }
    
    
    

    fps_GunScripts

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public delegate void PlayerShoot(); 
    
    /// <summary>
    /// 武器动画
    /// </summary>
    public class fps_GunScripts : MonoBehaviour {
    
        public static event PlayerShoot PlayerShootEvent;
        public float fireRate = 0.1f;
        public float damage = 40;
        public float reloadTime = 1.5f;
        public float flashRate = 0.02f;
        public AudioClip fireAudio;
        public AudioClip reloadAudio;
        public AudioClip damageAudio;
        public AudioClip dryFireAudio;
        public GameObject explosion;
        public int bulletCount=30;
        public int chargeBulletCount = 60;
        public Text bulletText;
    
        //动画片段名称
        private string reloadAnim = "Reload";
        private string fireAnim = "Single_Shot";
        private string walkAnim = "Walk";
        private string runAnim = "Run";
        private string jumpAnim = "Jump";
        private string idledAnim = "Idle";
    
    
        private Animation anim;
        private float nextFireTime = 0.0f;
        private MeshRenderer flash;
        private int currentBullet;
        private int currentChargeBullet;
        private fps_PlayerParemeter paremeter;
        private fps_PlayerControl playerControl;
    
    
    
        void Start () {
    
            paremeter = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerParemeter>();
            playerControl = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerControl>();
            anim = this.GetComponent<Animation>();
          //  flash = this.transform.FindChild("muzzle_flash").GetComponent<MeshRenderer>();
            flash = this.transform.Find("muzzle_flash").GetComponent<MeshRenderer>();
            flash.enabled = false;
            currentBullet = bulletCount;
            currentChargeBullet = chargeBulletCount;
            bulletText.text = currentBullet + "/" + currentChargeBullet;
    
        }
        
        
        void Update () {
            if (paremeter.inputReload&&currentBullet<bulletCount)
            {
                Reload();
            }
            else if (paremeter.inputFire&&!anim.IsPlaying(reloadAnim))
            {
                Fire();
            }
            else if (!anim.IsPlaying(reloadAnim))
            {
                StateAnim(playerControl.State);
            }
    
    
    
    
        }
    
    
        /// <summary>
        /// 换枪动画
        /// </summary>
        private void ReloadAnim() {
    
            anim.Stop(reloadAnim);
            anim[reloadAnim].speed = (anim[reloadAnim].clip.length/reloadTime);
            anim.Rewind(reloadAnim);
            anim.Play(reloadAnim);
    
        }
    
        private IEnumerator ReloadFinish() {
    
            yield return new WaitForSeconds(reloadTime);
            if (currentChargeBullet>=bulletCount-currentBullet)
            {
                currentChargeBullet -= (bulletCount-currentBullet);
                currentBullet = bulletCount;
            }
            else
            {
                currentBullet += currentChargeBullet;
                currentChargeBullet = 0;
            }
            bulletText.text = currentBullet + "/" + currentChargeBullet;
        }
    
    
    
        /// <summary>
        /// 重装子弹
        /// </summary>
        private void Reload() {
    
            if (!anim.IsPlaying(reloadAnim))
            {
                if (currentChargeBullet>0)
                {
                    StartCoroutine(ReloadFinish());
                }
                else
                {
                    anim.Rewind(fireAnim);
                    anim.Play(fireAnim);
                    AudioSource.PlayClipAtPoint(dryFireAudio,transform.position);
                    return;
                }
    
                AudioSource.PlayClipAtPoint(reloadAudio,transform.position);
                ReloadAnim();
            }
        }
    
        /// <summary>
        /// 开火特效
        /// </summary>
        /// <returns></returns>
        private IEnumerator Flash() {
    
            flash.enabled = true;
            yield return new WaitForSeconds(flashRate);
            flash.enabled = false;
        }
    
        /// <summary>
        /// 射击
        /// </summary>
        private void Fire() {
            if (Time.time>nextFireTime)
            {
                if (currentBullet<=0)
                {
                    Reload();
                    nextFireTime = Time.time + fireRate;
                    return;
                }
                currentBullet--;
                bulletText.text = currentBullet + "/" + currentChargeBullet;
                DamageEnemy();
                if (PlayerShootEvent!=null)
                {
                    PlayerShootEvent();
                }
                AudioSource.PlayClipAtPoint(fireAudio,transform.position);
                nextFireTime = Time.time + fireRate;
                anim.Rewind(fireAnim);
                anim.Play(fireAnim);
                StartCoroutine(Flash());
            }
        }
    
    
    
        /// <summary>
        /// 敌人收到攻击
        /// </summary>
        private void DamageEnemy() {
    
            Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));
            RaycastHit hit;
    
            if (Physics.Raycast(ray,out hit))
            {
                if (hit.transform.tag==Tags.enemy&&hit.collider is CapsuleCollider) //机器人
                {
                    AudioSource.PlayClipAtPoint(damageAudio,hit.transform.position);
                    GameObject go = Instantiate(explosion,hit.point,Quaternion.identity);
                    Destroy(go,3f);
                    hit.transform.GetComponent<fps_EnemyHealth>().TakeDamage(damage);
    
                }else if (hit.transform.tag == Tags.buzzer )  //无人机
                {
                    AudioSource.PlayClipAtPoint(damageAudio, hit.transform.position);
                    GameObject go = Instantiate(explosion, hit.point, Quaternion.identity);
                    Destroy(go, 3f);
                    hit.transform.GetComponent<fps_BuzzerHealth>().TakeDamage(damage);
    
                }
                else if (hit.transform.tag == Tags.spider)  //无人机
                {
                    AudioSource.PlayClipAtPoint(damageAudio, hit.transform.position);
                    GameObject go = Instantiate(explosion, hit.point, Quaternion.identity);
                    Destroy(go, 3f);
                    hit.transform.GetComponent<fps_SpiderHealth>().TakeDamage(damage);
    
                }
    
    
    
            }
    
    
        }
    
        /// <summary>
        /// 动画状态控制
        /// </summary>
        /// <param name="animName"></param>
        private void PlayerStateAnim(string animName) {
    
            if (!anim.IsPlaying(animName))
            {
                anim.Rewind(animName);
                anim.Play(animName);
            }
        }
    
    
        /// <summary>
        /// 动画状态
        /// </summary>
        /// <param name="state"></param>
        private void StateAnim(PlayerState state) {
    
            switch (state)
            {
              
                case PlayerState.Idle:
                    PlayerStateAnim(idledAnim);
                    break;
                case PlayerState.Walk:
                    PlayerStateAnim(walkAnim);
                    break;
                case PlayerState.Coruch:
                    PlayerStateAnim(walkAnim);
                    break;
                case PlayerState.Run:
                    PlayerStateAnim(runAnim);
                    break;
              
            }
    
        }
    
    }
    
    
    

    fps_Input

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 输入按键控制控制
    /// </summary>
    public class fps_Input : MonoBehaviour {
    
        public class fps_InputAxis {
    
            public KeyCode positive;
            public KeyCode negative;
        }
    
    
        //字典 键值对  按键 鼠标 水平 垂直
        public Dictionary<string, KeyCode> buttons = new Dictionary<string, KeyCode>();
    
        public Dictionary<string, fps_InputAxis> axis = new Dictionary<string, fps_InputAxis>();
    
        public List<string> unityAxis = new List<string>();
    
        //执行配置
        void Start() {
            SetupDefaults();
        }
    
    
    
        /// <summary>
        /// 按键配置
        /// </summary>
        /// <param name="type"></param>
        private void SetupDefaults(string type ="") {
            if (type==""||type=="buttons")
            {
                if (buttons.Count==0)
                {
                    AddButton("Fire",KeyCode.Mouse0);
                    AddButton("Reload",KeyCode.R);
                    AddButton("Jump",KeyCode.Space);
                    AddButton("Crouch",KeyCode.C);
                    AddButton("Sprint",KeyCode.LeftShift);
    
                }
            }
    
    
            if (type == "" || type == "Axis")
            {
                if (axis.Count == 0)
                {
                    AddAxis("Horizontal", KeyCode.W,KeyCode.S);
                    AddAxis("Vertical", KeyCode.A,KeyCode.D);
    
                }
            }
    
            if (type == "" || type == "UnityAxis")
            {
                if (unityAxis.Count == 0)
                {
    
                    AddUnityAxis("Mouse X");
                    AddUnityAxis("Mouse Y");
                    AddUnityAxis("Horizontal");
                    AddUnityAxis("Vertical");
                }
            }
        }
    
    
        private void AddButton(string n,KeyCode k) {
            if (buttons.ContainsKey(n))
            {
                buttons[n] = k;
            }
            else
            {
                buttons.Add(n,k);
            }
        }
    
    
        private void AddAxis(string n,KeyCode pk,KeyCode nk) {
    
            if (axis.ContainsKey(n))
            {
                axis[n] = new fps_InputAxis() { positive=pk,negative=nk};
            }
            else
            {
                axis.Add(n,new fps_InputAxis() { positive = pk, negative = nk });
            }
        }
    
    
    
        private void AddUnityAxis(string n) {
            if (!unityAxis.Contains(n))
            {
                unityAxis.Add(n);
            }
        }
    
        /// <summary>
        /// 判断是否有按键输入
        /// </summary>
        /// <returns></returns>
        public bool GetButton(string button) {
            if (buttons.ContainsKey(button))
            {
                return Input.GetKey(buttons[button]);
            }
            return false;
        }
    
        /// <summary>
        /// 是否有按下
        /// </summary>
        /// <param name="button"></param>
        /// <returns></returns>
        public bool GetButtonDown(string button)
        {
            if (buttons.ContainsKey(button))
            {
                return Input.GetKeyDown(buttons[button]);
            }
            return false;
        }
    
        /// <summary>
        /// 是否有值输入
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public float GetAxis(string axis) {
    
            if (this.unityAxis.Contains(axis))
            {
                return Input.GetAxis(axis);
            }
    
            return 0;
        }
    
    
        public float GetAxisRaw(string axis) {
    
            if (this.axis.ContainsKey(axis))
            {
                float val = 0;
                if (Input.GetKey(this.axis[axis].positive))
                {
                    return 1;
                }
                if (Input.GetKey(this.axis[axis].negative))
                {
                    return -1;
                }
                return val;
            }
            else if (unityAxis.Contains(axis))
            {
                return Input.GetAxisRaw(axis);
            }
            else
            {
                return 0;
            }
    
    
    
        }
    
    
    }
    
    

    fps_KeyPickUp

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 钥匙卡
    /// </summary>
    public class fps_KeyPickUp : MonoBehaviour {
    
        public AudioClip keyGrab;
        public int keyId;
    
        private GameObject player;
        private fps_PlayerInventory playerInventory;
    
    
    
        void Start () {
    
            player = GameObject.FindGameObjectWithTag(Tags.player);
            playerInventory = player.GetComponent<fps_PlayerInventory>();
    
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 进入触发范围
        /// </summary>
        /// <param name="other"></param>
        void OnTriggerEnter(Collider other) {
            Debug.Log("进入钥匙触发范围--准备执起钥匙卡");
            if (other.gameObject==player)
            {
                AudioSource.PlayClipAtPoint(keyGrab,transform.position);  //播放执起声效
                playerInventory.AddKey(keyId);  //设置的id号对应 钥匙  跟 门 是配对
                Destroy(this.gameObject);
    
            }
        }
    
    
    }
    
    

    fps_LaserDamage

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 激光墙
    /// </summary>
    public class fps_LaserDamage : MonoBehaviour {
    
        public int damage = 30;
        public float damageDelay = 1; //1秒伤害1次
    
        private float lastDamageTime = 0;
        private GameObject player;
    
        void Start () {
            player = GameObject.FindGameObjectWithTag(Tags.player); //获取玩家的引用
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 触发器逗留
        /// </summary>
        void OnTriggerStay(Collider other) {
           // Debug.Log("进入激光墙触发");
            if (other.gameObject==player&&Time.time>lastDamageTime+damageDelay)
            {
                player.GetComponent<fps_PlayerHealth>().TakeDamage(damage); //执行玩家受伤害的方法
                lastDamageTime = Time.time; //确认当前时间
            }
        }
    
    }
    
    

    fps_PlayerControl

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 玩家4种状态
    /// </summary>
    public enum PlayerState
    {
    
        None,
        Idle,
        Walk,
        Coruch,
        Run,
    }
    /// <summary>
    /// 玩家控制
    /// </summary>
    public class fps_PlayerControl : MonoBehaviour {
    
        private PlayerState state = PlayerState.None;
        public PlayerState State {
            get {
                if (running)
                    state = PlayerState.Run;
                else if (walking)
                    state = PlayerState.Walk;
                else if (crouching)
                    state = PlayerState.Coruch;
                else
                    state = PlayerState.Idle;
    
                return state;
            }
        }
    
        public float sprintSpeed = 10.0f;
        public float sprintJumpSpeed = 8.0f;
        public float normalSpeed = 6.0f;
        public float normalJumpSpeed = 7.0f;
        public float crouchSpeed = 2.0f;
        public float crouchJumpSpeed = 5.0f;
        public float crouchDeltaHeight = 0.5f;
    
    
        public float gravity = 20.0f;
        public float cameraMoveSpeed = 8.0f;
        public AudioClip jumpAudio;
    
    
        private float speed;
        private float jumpSpeed;
        private Transform mainCamera;
        private float standardCamHeight;
        private float crouchingCamHeight;
        private bool grounded = false;
        private bool walking = false;
        private bool crouching = false;
        private bool stopCrouching = false;
        private bool running = false;
        private Vector3 normalControllerCenter = Vector3.zero;
        private float normalControllerHeight = 0.0f;
        private float timer = 0;
        private CharacterController controller;
        private AudioSource audioSource;
        private fps_PlayerParemeter paremeter;
        private Vector3 moveDirection = Vector3.zero;
    
    
        void Start() {
            crouching = false;
            walking = false;
            running = false;
            speed = normalSpeed;
            jumpSpeed = normalJumpSpeed;
            mainCamera = GameObject.FindGameObjectWithTag(Tags.mainCamera).transform;
            standardCamHeight = mainCamera.localPosition.y;
            crouchingCamHeight = standardCamHeight - crouchDeltaHeight;
            audioSource = this.GetComponent<AudioSource>();
            controller = this.GetComponent<CharacterController>();
            paremeter = this.GetComponent<fps_PlayerParemeter>();
            normalControllerCenter = controller.center;
            normalControllerHeight = controller.height;
        }
    
    
      
    
        void FixedUpdate() {
            UpdateMove();
            AudioManager();
        }
    
    
        /// <summary>
        /// 更新有移动
        /// </summary>
    
        void UpdateMove(){
            if (grounded)
            {
                moveDirection = new Vector3(paremeter.inputMoveVector.x, 0, paremeter.inputMoveVector.y);
                moveDirection = transform.TransformDirection(moveDirection);
                moveDirection *= speed;
    
                if (paremeter.inputJump)
                {
                    moveDirection.y = jumpSpeed;
                    AudioSource.PlayClipAtPoint(jumpAudio, transform.position);
                    CurrentSpeed();
                }
            }
    
            moveDirection.y -= gravity * Time.deltaTime;
            CollisionFlags flags = controller.Move(moveDirection*Time.deltaTime);
            grounded = (flags&CollisionFlags.CollidedBelow) != 0;
    
            if (Mathf.Abs(moveDirection.x)>0&&grounded||Mathf.Abs(moveDirection.z)>0&&grounded)
            {
                if (paremeter.inputSprint)
                {
                    walking = false;
                    running = true;
                    crouching = false;
                }
                else if (paremeter.inputCrouch)
                {
                    walking = false;
                    running = false;
                    crouching = true;
    
                }
                else
                {
                    walking = true ;
                    running = false;
                    crouching = false;
                }
    
    
            }
            else
            {
                if (walking)
                    walking = false;
                if (running)
                    running = false;
                if (paremeter.inputCrouch)
                    crouching = true;
                else
                    crouching = false;
    
            }
    
            if (crouching)
            {
                controller.height = normalControllerHeight - crouchDeltaHeight;
                controller.center = normalControllerCenter - new Vector3(0, crouchDeltaHeight/2,0);
            }
            else
            {
                controller.height = normalControllerHeight ;
                controller.center = normalControllerCenter;
    
            }
            UpdateCrouch();
            CurrentSpeed();
        }
    
    
        /// <summary>
        /// 玩家当前速度管理
        /// </summary>
        private void CurrentSpeed() {
            switch (State)
            {
                
                case PlayerState.Idle:
                    speed = normalSpeed;
                    jumpSpeed = normalJumpSpeed;
                    break;
                case PlayerState.Walk:
                    speed = normalSpeed;
                    jumpSpeed = normalJumpSpeed;
                    break;
                case PlayerState.Coruch:
                    speed = crouchSpeed;
                    jumpSpeed = crouchJumpSpeed;
                    break;
                case PlayerState.Run:
                    speed = sprintSpeed;
                    jumpSpeed = sprintJumpSpeed;
                    break;
               
            }
    
    
        }
    
    
        /// <summary>
        /// 声效管理器
        /// </summary>
        private void AudioManager() {
    
            if (State == PlayerState.Walk)
            {
                audioSource.pitch = 1.0f;
                if (!audioSource.isPlaying)
                {
                    audioSource.Play();
                }
            }
            else if (State == PlayerState.Run)
            {
                audioSource.pitch = 1.3f;
                if (!audioSource.isPlaying)
                {
                    audioSource.Play();
                }
            }
            else
                audioSource.Stop();
        }
    
    
        /// <summary>
        /// 更新蹲伏状态
        /// </summary>
        private void UpdateCrouch() {
    
            if (crouching)
            {
                if (mainCamera.localPosition.y > crouchingCamHeight)
                {
                    if (mainCamera.localPosition.y - (crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed) < crouchingCamHeight)
                        mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, crouchingCamHeight, mainCamera.localPosition.z);
                    else
                        mainCamera.localPosition -= new Vector3(0, crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed, 0);
                }
                else
                    mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, crouchingCamHeight, mainCamera.localPosition.z);
            }
            else
            {
                if (mainCamera.localPosition.y < standardCamHeight)
                {
                    if (mainCamera.localPosition.y + (crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed) > standardCamHeight)
                        mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, standardCamHeight, mainCamera.localPosition.z);
                    else
                        mainCamera.localPosition += new Vector3(0, crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed, 0);
                }
                else
                    mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, standardCamHeight, mainCamera.localPosition.z);
    
            }
    
        }
    
    }
    
    

    fps_PlayerHealth

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityStandardAssets.ImageEffects;
    
    
    /// <summary>
    /// 玩家生命值
    /// </summary>
    public class fps_PlayerHealth : MonoBehaviour {
    
        public bool isDead;
        public float resetAfterDeathTime = 0;
        public AudioClip deadClip;
        public AudioClip damageClip;
        public float maxHP = 100;
        public float hp = 100;
        public float recoverSpeed = 1;
    
        private float timer = 0;
        private FadeInOut fader;
        private ColorCorrectionCurves colorCurves;  //屏幕特效
    
        void Start () {
    
            hp = maxHP;
            fader = GameObject.FindGameObjectWithTag(Tags.fader).GetComponent<FadeInOut>();
            colorCurves = GameObject.FindGameObjectWithTag(Tags.mainCamera).GetComponent<ColorCorrectionCurves>();
            BleedBehavior.BloodAmount = 0; //设置为0  没有显示红色的区域
        }
        
        
        void Update () {
            if (!isDead)
            {
                hp += recoverSpeed * Time.deltaTime; //恢复时间
                if (hp>maxHP)
                {
                    hp = maxHP;
                }
            }
    
            if (hp<0)
            {
                if (!isDead)
                {
                    PlayerDead();
                }
                else
                {
                    LevelReset();
                }
            }
    
    
        }
    
        /// <summary>
        /// 玩家受到攻击
        /// </summary>
        public void TakeDamage(float damage) {
            if (isDead)
            {
                return;
            }
            AudioSource.PlayClipAtPoint(damageClip,transform.position);
            float damage01 = damage;
            if (damage01<40)
            {
                damage01 *= 30;
            }
            //BleedBehavior.BloodAmount += Mathf.Clamp01(damage/hp);
            BleedBehavior.BloodAmount += Mathf.Clamp01(damage01 / hp);
            hp -= damage;
        }
    
    
        /// <summary>
        /// 不能继续输入
        /// </summary>
        public void DisableInput() {
    
            transform.Find("FP_Camera/Weapon_Camera").gameObject.SetActive(false);
            this.GetComponent<AudioSource>().enabled = false;
            this.GetComponent<fps_PlayerControl>().enabled = false;
            this.GetComponent<fps_FPInput>().enabled = false;
            if (GameObject.Find("Canvas") !=null) //注意画布的隐藏和显示
            {
                GameObject.Find("Canvas").SetActive (false);
            }
            colorCurves.gameObject.GetComponent<fps_FPCamera>().enabled = false;
        }
    
    
        /// <summary>
        /// 玩家挂掉
        /// </summary>
        public void PlayerDead() {
    
            isDead = true;
            colorCurves.enabled = true;
            DisableInput();
            AudioSource.PlayClipAtPoint(deadClip,transform.position);
        }
    
    
        /// <summary>
        /// 重置
        /// </summary>
        public void LevelReset() {
            timer += Time.deltaTime;
            colorCurves.saturation -= (Time.deltaTime / 2);
            colorCurves.saturation = Mathf.Max(0,colorCurves.saturation);
            if (timer>=resetAfterDeathTime)
            {
                fader.EndScene(); //播放渐暗的效果
            }
    
        }
    
    }
    
    

    fps_PlayerInventory

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 控制id号
    /// </summary>
    public class fps_PlayerInventory : MonoBehaviour {
    
        private List<int> keyArr;
    
        void Start () {
    
            keyArr = new List<int>();
        }
        
        
        void Update () {
            
        }
    
        /// <summary>
        /// 加入Id号
        /// </summary>
        /// <param name="keyId"></param>
        public void AddKey(int keyId) {
            if (!keyArr.Contains(keyId))
            {
                keyArr.Add(keyId);
            }
    
        }
    
    
        /// <summary>
        /// 对应门ID号确认是否可以打开
        /// </summary>
        /// <param name="doorId"></param>
        /// <returns></returns>
        public bool HasKey(int doorId) {
            if (keyArr.Contains(doorId))
            {
                return true;
            }
            return false;
    
        }
    
    
    }
    
    

    fps_PlayerParemeter

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 玩家输入参数的封装
    /// </summary>
    [RequireComponent(typeof(CharacterController))]
    public class fps_PlayerParemeter : MonoBehaviour {
        [HideInInspector]
        public Vector2 inputSmoothLook;
        [HideInInspector]
        public Vector2 inputMoveVector;
        [HideInInspector]
        public bool inputCrouch;
        [HideInInspector]
        public bool inputJump;
        [HideInInspector]
        public bool inputSprint;
        [HideInInspector]
        public bool inputFire;
        [HideInInspector]
        public bool inputReload;
    
    
    
        
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    }
    
    

    HashIDs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 动画哈希值 
    /// </summary>
    public class HashIDs : MonoBehaviour {
    
        public int deadBool;
    
        public int speedFloat;
    
        public int playerInSightBool;
    
        public int shotFloat;
    
        public int aimWeightFloat;
    
        public int angularSpeedFloat;
    
    
        void Awake() {
    
            deadBool = Animator.StringToHash("Dead");
    
            speedFloat = Animator.StringToHash("Speed");
    
            playerInSightBool = Animator.StringToHash("PlayerInSight");
    
            shotFloat = Animator.StringToHash("Shot");
    
            aimWeightFloat = Animator.StringToHash("AimWeight");
    
            angularSpeedFloat = Animator.StringToHash("AngularSpeed");
        }
    
    
        void Start () {
            
        }
        
        
        void Update () {
            
        }
    }
    
    
    Outdoor

    BuzzerAttack

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /// <summary>
    /// 无人机攻击脚本
    /// </summary>
    public class BuzzerAttack : MonoBehaviour
    {
    
        public LineRenderer electricArc;//攻击闪电特效
        public float coldTime = 1.0f;
        public BuzzerMove move;
        public  float damage=40;//攻击力
    
    
        private Transform player;
        private Vector3 zapNoise = Vector3.zero;
        private AudioSource audioSource;
        private float rechargeTimer ; //间隔计时器 冷却时间
        private bool canAttack = false; //是否到达攻击范围
        private fps_PlayerHealth playerHealth;
    
        void Awake()
        {
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            playerHealth = player.GetComponent<fps_PlayerHealth>();
            audioSource = GetComponent<AudioSource>();
            rechargeTimer = coldTime;
        }
    
    
        void Update()
        {
            move.moveTarget = player.position;
            //Vector3.Distance(transform.position, player.position);
            Vector3 dir = player.position - transform.position;
            // canAttack = dir.magnitude < 2.0f; //布尔值赋值
            canAttack = false;
            if (dir.magnitude < 3.8f)
            {
                canAttack = true;
                move.moveTarget = Vector3.zero; //注意位置信息1213
            }
             rechargeTimer -= Time.deltaTime; //冷却中
            
            if (rechargeTimer < 0&&canAttack)
            {
                zapNoise = new Vector3(Random.Range(-1.0f, 1.0f), 0.0f, Random.Range(-1.0f, 1.0f)) * 0.5f;
                StartCoroutine(DoElectricArc());
                // rechargeTimer = coldTime;
                rechargeTimer = Random.Range(1.0f,2.0f); //重置冷却时间
                playerHealth.TakeDamage(damage);//玩家受到攻击
    
            }
        }
    
    
    
        /// <summary>
        /// 开启雷电攻击功能
        /// </summary>
        /// <returns></returns>
        IEnumerator DoElectricArc()
        {
    
            if (electricArc.enabled)
            {
                yield return 0;
            }
            //播放闪电音效
            audioSource.Play();
    
    
            electricArc.enabled = true;
    
            zapNoise = transform.rotation * zapNoise;
    
            float stopTime = Time.time + 0.2f;
            while (Time.time < stopTime)
            {
                electricArc.SetPosition(0, electricArc.transform.position);
                electricArc.SetPosition(1, player.position + zapNoise);
                yield return 0;
            }
    
            electricArc.enabled = false;
    
    
    
        }
    
    
    }
    
    

    BuzzerMove

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 无人机移动
    /// </summary>
    public class BuzzerMove : MonoBehaviour {
    
        public float flyingSpeed = 5.0f; //飞行速度
        public float zigZagness = 3.0f; //范围
        public float zigZagSpeed = 2.5f;//速度
        public float backtrackIntensity = 0.5f; //回退系数
        public float oriantationMultiplier = 2.5f;   //旋转系数
        public Vector3 moveTarget; //追踪目标
    
        private Transform player;
        private Rigidbody rigi;
        private Vector3 smoothDirection = Vector3.zero;  //使移动更平滑
    
    
        void Awake() {
            player = GameObject.FindGameObjectWithTag("Player").transform;
            rigi = transform.GetComponent<Rigidbody>();
        }
    
    
        
        
        void FixedUpdate () {
            //Vector3 direction = player.position - transform.position;
            Vector3 direction = moveTarget - transform.position;
            direction.Normalize(); //平滑归零 避免越来越大
            smoothDirection = Vector3.Lerp(smoothDirection,direction,Time.deltaTime*3.0f);
    
            Vector3 zigzag = transform.right * (Mathf.PingPong(Time.time* zigZagSpeed, 2.0f)-1.0f)* zigZagness;
            float orientationSpeed = 1.0f;
                
            Vector3 deltaVelocity = (smoothDirection * flyingSpeed+zigzag)- rigi.velocity;
    
            if (Vector3.Dot(direction,transform.forward)>0.8f)
            {
                rigi.AddForce(deltaVelocity, ForceMode.Force);
            }
            else
            {
                rigi.AddForce(-deltaVelocity*backtrackIntensity, ForceMode.Force);
                orientationSpeed = oriantationMultiplier;
            }
           
    
            float rotationAngle = AngleAroundAxis(transform.forward,direction,Vector3.up);
            rigi.angularVelocity = Vector3.up * rotationAngle * 0.2f*orientationSpeed;
        }
    
    
        /// <summary>
        /// 旋转角度
        /// </summary>
        /// <returns></returns>
        static float AngleAroundAxis(Vector3 dirA,Vector3 dirB, Vector3 axis) {
    
            dirA = dirA - Vector3.Project(dirA,axis);
            dirB = dirB - Vector3.Project(dirB,axis);
    
            float angle=Vector3.Angle(dirA,dirB);
    
            return angle * (Vector3.Dot(axis,Vector3.Cross(dirA,dirB))<0?-1:1);
    
        }
    
    }
    
    

    fps_BuzzerHealth

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class fps_BuzzerHealth : MonoBehaviour {
    
        public float hp = 100;
        public GameObject explosion;
    
        private bool isDead = false;
    
        /// <summary>
        /// 无人机受到攻击
        /// </summary>
        public void TakeDamage(float damage) {
    
            hp -= damage;
            if (hp<=0&&!isDead)
            {
                isDead = true;
                transform.GetComponent<BuzzerMove>().enabled = false;
                transform.GetComponent<BuzzerAttack>().enabled = false;
                transform.GetComponent<fps_BuzzerHealth>().enabled = false;
                GameObject go = Instantiate(explosion, transform.position, Quaternion.identity);
                Destroy(go, 2f);
                Destroy(gameObject);
            }
    
        }
    
    
    
    }
    
    

    fps_BuzzerSight

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class fps_BuzzerSight : MonoBehaviour {
    
        
    
        void Start () {
            transform.GetComponent<BuzzerMove>().enabled = false;
            transform.GetComponent<BuzzerAttack>().enabled = false;
            transform.GetComponent<fps_BuzzerHealth>().enabled = false;
        }
        
    
        /// <summary>
        /// 进入视野范围
        /// </summary>
        void OnTriggerEnter(Collider collider) {
    
            Debug.Log("进入无人机视野范围");
            if (collider.gameObject.tag==Tags.player)
            {
                transform.GetComponent<BuzzerMove>().enabled = true;
                transform.GetComponent<BuzzerAttack>().enabled = true;
                transform.GetComponent<fps_BuzzerHealth>().enabled = true;
               
            }
    
        }
    
    
    }
    
    

    SpiderAttack

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SpiderAttack : MonoBehaviour
    {
    
        public GameObject bot; //子物体
        public GameObject explosionPrefab;//爆炸预制体
        public float damageRadius = 5.0f;   //破坏范围
        public SpiderMove move;
        public float damage = 40;//攻击力
    
       public  Transform player;
        private bool canAttack = false;
        private Animation anim;
        private fps_PlayerHealth playerHealth;
    
        void Awake()
        {
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            playerHealth = player.GetComponent<fps_PlayerHealth>();
            anim = bot.GetComponent<Animation>();
        }
    
        void Start()
        {
    
        }
    
    
        void Update()
        {
    
            Vector3 playerDirection = (player.position - transform.position);
            float playerDis = playerDirection.magnitude;
            playerDirection /= playerDis;
    
    
    
            Vector3 dir = player.position - transform.position;
           // canAttack = false;
            //达到指定距离后就不在播放动画 1213
            if (dir.magnitude < 2.0f)
            {
                // canAttack = true;
                move.moveDirection = Vector3.zero;
                anim.Stop();
                StartCoroutine(Explode());
            }
            else
            {
                move.moveDirection = playerDirection;
                anim.Play("forward");
    
            }
            //anim.Play("forward");
        }
    
    
        /// <summary>
        /// 爆炸
        /// </summary>
        IEnumerator Explode()
        {
            yield return new WaitForSeconds(1f);
            float damageFraction = 1 - (Vector3.Distance(player.position,transform.position)/damageRadius);
            // player.GetComponent<Rigidbody>().AddExplosionForce(10,transform.position,damageRadius,0.0f,ForceMode.Impulse);
            playerHealth.TakeDamage(damage);//玩家受到攻击
            GameObject go=Instantiate(explosionPrefab,transform.position,Quaternion.identity);
            Destroy(go,2f);
            Destroy(gameObject);
    
        }
    }
    
    

    SpiderMove

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SpiderMove : MonoBehaviour {
    
     
        public float walkingSpeed = 5.0f; //移动速度
    
        [HideInInspector]
        public Vector3 moveDirection;  //移动方向
        [HideInInspector]
        public Vector3 facingDirection; //面向方向
    
        private Transform player; //玩家
        private Rigidbody rigi;
        private float orientationSpeed = 0.3f;
        void Awake(){
            player = GameObject.FindGameObjectWithTag(Tags.player).transform;
            rigi = this.GetComponent<Rigidbody>();
        }
        void Start () {
    
        }
        
        
        /// <summary>
        /// 追踪玩家
        /// </summary>
        void FixedUpdate () {
    
    
            Vector3 targetVeloctiy = moveDirection;// (player.position-transform.position) ;
           // targetVeloctiy.Normalize();
            Vector3 detalVeloctiy = targetVeloctiy * walkingSpeed - rigi.velocity;
            rigi.AddForce(detalVeloctiy,ForceMode.Acceleration);
    
            Vector3 faceDir = targetVeloctiy;
            if (faceDir==Vector3.zero)
            {
                rigi.angularVelocity = Vector3.zero;
            }
            else
            {
                float rotationAngle = AngleAroundAxis(transform.forward, faceDir, Vector3.up);
                rigi.angularVelocity = Vector3.up * rotationAngle * 0.2f * orientationSpeed;
            }
    
           
    
        }
    
    
        /// <summary>
        /// 旋转角度
        /// </summary>
        /// <returns></returns>
        static float AngleAroundAxis(Vector3 dirA, Vector3 dirB, Vector3 axis)
        {
    
            dirA = dirA - Vector3.Project(dirA, axis);
            dirB = dirB - Vector3.Project(dirB, axis);
    
            float angle = Vector3.Angle(dirA, dirB);
    
            return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
    
        }
    }
    
    

    三、效果图

    相关文章

      网友评论

          本文标题:VR开发实战HTC Vive项目之星球大战

          本文链接:https://www.haomeiwen.com/subject/etuvjqtx.html