• 在网上看了一些拾取物品的实现原理之后,自己摸索了一下,了个小Demo,下面来介绍一下基本功能。1)人物靠近物体,且视角朝向物体,改变物体颜色。 2)按E键拾取物品到背包,并销毁游戏对象。 3)按B键在背包中...

    Unity 3D 实现拾取物品功能(一)


    刚刚接触Unity不久,为了记录自己学习的过程。我决定写写博客,哈哈哈。
    
    在网上看了一些拾取物品的实现原理之后,自己摸索了一下,写了个小Demo,下面来介绍一下基本功能。
    
    1)人物靠近物体,且视角朝向物体,改变物体颜色。
    2)按E键拾取物品到背包,并销毁游戏对象。
    3)按B键在背包中显示已有物品。
    
    一般背包设定分为格子上限和负重上限两种,在这个Demo里我们使用格子上限的模式。且物品分为可叠加和不可叠加两种。
    

    首先,来预览一下成果。
    在游戏场景中建立这么一些游戏对象,来模拟游戏里的真实物品。
    游戏场景

    然后我们操作角色,移动到物体前。然后镜头指向游戏想,把默认颜色修改为红色。
    物品颜色变更

    一般游戏都使用E键拾取物品,我也使用E键拾取。拾取成功后,我们就使用Destroy()函数,销毁游戏对象。从而达到物品被加入背包的感觉。
    我们把ObjectItem挂到物体上,然后设置属性。
    方块1数量为685,可叠加,最大叠加数量为1000。
    方块2数量为888,可叠加,最大叠加数量为1000。
    相同物品的判断使用ObjId字段,所以同类物品就设置ObjId一致就可以了。
    这里写图片描述

    拾取以上两个方块后,按下B键,调用显示物品的函数,暂时显示到Debug控制台中。在后续的博客中再继续完善。
    这里写图片描述
    我们就可以看到,物品栏就有了两条记录。

    然后设置两个圆柱个数都为1,且不可叠加。拾取后按B键,查看控制台
    这里写图片描述
    就可以看到柱子的数量分别存在的单独的格子。

    把背包和物品属性抽象,形成两个类。Pack.cs和ObjectItem.cs

    Pack.cs代码如下:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class Pack : MonoBehaviour {
        //保存物品的List数组
        public List<ItemEntity> items = null;
        //背包最大容量
        public int maxItem = 32;
    
        // Use this for initialization
        void Start () {
            items = new List<ItemEntity>();
        }
    
        //拾取物品
        public ObjectItem getItem(ObjectItem item)
        {
            //使用中间过渡的实体类
            ItemEntity itemEntity = ItemEntity.FillData(item);
    
            //如果物品不可合并
            if (!itemEntity.IsCanAdd)
            {   
                //背包有空余
                if(items.Count < maxItem)
                {   
                    //获得物品
                    items.Add(itemEntity);
                    item.count = 0;
                } else
                {   
                    //拾取失败
                }
            } else
            {
                //空背包时,直接添加
                if (items.Count < 1)
                {
                    items.Add(itemEntity);
                    item.count = 0;
                } else
                {
                    //判断当前背包合并物品
                    foreach (ItemEntity currItem in items)
                    {
                        //相同物品,且可叠加,且分组未满
                        if (currItem.ObjId.Equals(itemEntity.ObjId) && currItem.Count < currItem.MaxAdd)
                        {
                            //数量叠加
                            currItem.Count = currItem.Count + itemEntity.Count;
                            //如果超出叠加范围
                            if (currItem.Count - currItem.MaxAdd > 0)
                            {
                                //拾取物品的剩余数量变更
                                item.count = currItem.Count - currItem.MaxAdd;
                                itemEntity.Count = item.count;
                                //背包里的数量为最大值
                                currItem.Count = currItem.MaxAdd;
                            } else
                            {
                                // 未超出叠加最大值,拾取成功
                                item.count = 0;
                            }
                        } else
                        {
                            //如果物品不是同类,或分组是满的,遍历下一个格子
                            continue;
                        }
                    }
                    //物品超出分组,有剩余格子则添加。否则剩余部分无法拾取
                    if(item.count > 0 && items.Count < maxItem)
                    {
                        items.Add(itemEntity);
                        item.count = 0;
                    }
                } 
            }
            return item;      
        }
    
        //显示物品
        public void showPack()
        {
            string show = "物品:\n";
            int i = 0;
            foreach (ItemEntity currItem in items)
            {  
                show += ++i + " [" + currItem.ObjName + "], 数量: " + currItem.Count + "\n";
            }
            Debug.Log(show);
        }
    }

    ObjectItem代码如下

    using UnityEngine;
    using System.Collections;
    
    public class ObjectItem : MonoBehaviour {
    
        public string objId;
        public string objName;
        public int count;
        public string note;
        public int level;
        public bool isCanAdd;
        public int maxAdd;
    
        public bool isChecked;
    
        // Use this for initialization
        void Start () {
            isChecked = false;
        }
    
    // Update is called once per frame
    void Update () {
            if (isChecked)
            {
                GetComponent<MeshRenderer>().material.color = Color.red;
            } else
            {
                GetComponent<MeshRenderer>().material.color = Color.white;
            }
            isChecked = false;
        }
    }

    在使用过程中,使用List保存物品时,调用Destroy()函数后,List里面的对象也会被删除掉。
    所以,我们在代码中使用一个中间类ItemEntity.cs,代码如下:

    public class ItemEntity {
    
        private string objId;
        private string objName;
        private int count;
        private string note;
        private int level;
        private bool isCanAdd;
        private int maxAdd;
        private bool isChecked;
    
    
        public static ItemEntity FillData(ObjectItem item)
        {
            ItemEntity itemEntity = new ItemEntity();
            itemEntity.ObjId = item.objId;
            itemEntity.ObjName = item.objName;
            itemEntity.Count = item.count;
            itemEntity.Note = item.note;
            itemEntity.Level = item.level;
            itemEntity.IsCanAdd = item.isCanAdd;
            itemEntity.MaxAdd = item.maxAdd;
            itemEntity.IsChecked = item.isChecked;
            return itemEntity;
        }
    
        public string ObjId
        {
            get
            {
                return objId;
            }
    
            set
            {
                objId = value;
            }
        }
    
        public string ObjName
        {
            get
            {
                return objName;
            }
    
            set
            {
                objName = value;
            }
        }
    
        public int Count
        {
            get
            {
                return count;
            }
    
            set
            {
                count = value;
            }
        }
    
        public string Note
        {
            get
            {
                return note;
            }
    
            set
            {
                note = value;
            }
        }
    
        public int Level
        {
            get
            {
                return level;
            }
    
            set
            {
                level = value;
            }
        }
    
        public bool IsCanAdd
        {
            get
            {
                return isCanAdd;
            }
    
            set
            {
                isCanAdd = value;
            }
        }
    
        public int MaxAdd
        {
            get
            {
                return maxAdd;
            }
    
            set
            {
                maxAdd = value;
            }
        }
    
        public bool IsChecked
        {
            get
            {
                return isChecked;
            }
    
            set
            {
                isChecked = value;
            }
        }
    }

    最后,我们在玩家控制的角色上使用代码:

    using UnityEngine;
    using System.Collections;
    
    public class PlayerController : MonoBehaviour {
    
        private Transform tr;
        //背包类
        private Pack pack;
    
        // Use this for initialization
        void Start () {
            tr = GetComponent<Transform>();
            pack = GetComponent<Pack>();
        }
    
        // Update is called once per frame
        void Update () {
    
            if (Input.GetKeyDown(KeyCode.B))
            {
                pack.showPack();
            }
    
            Debug.DrawRay(tr.position, tr.forward * 2.0f, Color.green);
            RaycastHit hit;
            if (Physics.Raycast (tr.position, tr.forward, out hit, 2.0f)) {
                //Debug.Log ("射线击中:" + hit.collider.gameObject.name + "\n tag:" + hit.collider.tag);
                GameObject gameObj = hit.collider.gameObject;
                ObjectItem obj = (ObjectItem)gameObj.GetComponent<ObjectItem>();
                if (obj != null)
                {
                    obj.isChecked = true;
                    //Debug.Log(obj.objName);
                    if (Input.GetKeyDown(KeyCode.E))
                    {
                        obj = pack.getItem(obj);
                        if(obj.count == 0)
                        {
                            //gameObj.SetActive(false);
                            Destroy(gameObj);
                        }
                    }
                }
            }
        }
    }

    这样,我们就可以实现了拾取物品的基本功能。
    当拾取超过了背包容量时,可以重叠的物品会叠加至最大数量,然后剩余数量依然存在于场景中。相当于只拾取了一部分。

    代码还有很多没有使用到的属性,也是临时的一些想法,方便后续拓展。
    代码变量的命名规范及代码流程还可以有更多的优化。有大牛可以给我指点指点 >.<

    以上就是我摸索出来的拾取物品的一个大概模型。不知道你们是怎么实现的呢!

    展开全文
  • Unity3d 颜色拾取C#

    2020-06-05 23:30:44
    本人学习shader时寻找到的资源,原作者Lele Feng,十分方便的小工具。 解压C#文件拖入Unity3d 摄像机上便可使用,点击屏幕可用得到对应点的颜色。
  • U3D小项目参考

    2018-05-23 16:30:06
    U3D小项目参考》 ++U3D小案例简述 ++++这里是立钻哥哥汇总的几个U3D小案例,通过案例学习U3D的基本编程和技巧。 ++++小案例会不断更新补充,通过学习掌握U3D的编程和思想。 ++小案例目录: ++++小案例001、...

    U3D项目参考

    ++U3D小案例简述

    ++++这里是立钻哥哥汇总的几个U3D小案例,通过案例学习U3D的基本编程和技巧。

    ++++小案例会不断更新补充,通过学习掌握U3D的编程和思想。

    ++小案例目录:

    ++++小案例001、贪吃蛇Demo

    ++++小案例002、飞机大战Demo

    ++++小案例003MVC框架(提升等级案例)

    ++++小案例004、简单背包案例

    ++++小案例005、塔防Demo

    ++++小案例006、秘密行动Demo

    ++++小案例007A_Star

    ++++小案例008、血条LiftBar跟随

    ++++小案例009、见缝插针StickPin

    ++++小案例010UnityNetDemo

    ++++小案例011SocketFileRecv

    ++++小案例012、切水果CutFruitDemo

    ++++小案例013、吃鸡_友军方位UV

    ++++小案例014、数据库背包SqliteEZ_Bag

    ++++小案例015Json数据存储

    ++++小案例016、关卡系统LevelSystem

    ++++超级Demo:斗地主


    #小案例001、贪吃蛇demo

    ++小案例001:贪吃蛇demo

    ++++Cube_Snake_Body.prefab

    ++++Cube_Snake_Food.prefab

    ++++Scene02Snake.unity

    ++++SnakeMoveScript.cs



    ###SnakeMoveScript.cs

    C:\000-ylzServ_U3D_Pro\小案例001\Assets\DemoSnake\SnakeMoveScript.cs

    ++SnakeMoveScript.cs

     

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System.Linq;

    using UnityEngine.SceneManagement;  //引入场景控制器

     

    public  class SnakeMoveScript :  MonoBehaviour{

        /*

     蛇头移动:

        #1、蛇头移动(默认方向朝上,wsad控制移动)

        #2、生成食物(随机生成)

        #3、吃到食物后生成蛇身

        #4、游戏结束

        */

     

        //1、蛇头移动(默认方向朝上,wsad控制移动)

        Vector2  dirV2Move  = Vector2.up; //默认向上移动

        public float speedMoveRate= 5f;  //速度

        public GameObject  snakeBody;  //身体

        public GameObject  snakeFood; //食物

     

        //创建集合存放身体(蛇身)

        List<Transform> bodyList = new List<Transform>();

     

        bool  isCreate  =  false;  //控制是否创建身体

     

        //Use this for initialization

        void Start(){

            for(int   i =0; i <5; i++){

                Invoke(CreatFood,1.0f);  //延迟1秒,调用Creat

            }

     

            //在游戏开始1.5秒调用Move方法,然后每隔0.2秒再重复调用

            InvokeRepeating(SnakeMove,1.5f, 0.2f);  //每几秒重复调用这个函数

        }

     

        //Update is called once per frame

        void Update(){

            dirV2Move = GetMoveDir(); //获取控制方向

        }

     

        //触发检测

        void OnTriggerEnter(Collider other){

            if(other.gameObject.CompareTag(SnakeFood)){

                //如果碰撞到的是食物

                Destroy(other.gameObject); //销毁食物

                isCreate = true;

     

                Invoke(CreatFood,0.3f); //0.3秒之后创建食物

     

            }else if(other.gameObject.CompareTag(SnakeBody)){

                //碰到自己

                Debug.Log(yanlzPrint:碰到自己身体了,游戏结束!);

                //todo优化碰到自己身体处理事件

     

            }else{

                Debug.Log(yanlzPrint:碰到墙了,游戏重新开始!);

                SceneManager.LoadScene(Scene02Snake); //重新加载场景(新一局)

            }

        }

     

        //自定义函数

     

        //获取方向控制

        //1、蛇头移动(默认方向朝上,wsad控制移动)

        Vector2 GetMoveDir(){

            if(Input.GetKeyDown(KeyCode.W)){

                dirV2Move = Vector2.up;

            }else if(Input.GetKeyDown(KeyCode.S)){

                dirV2Move = Vector2.down;

            }else if(Input.GetKeyDown(KeyCode.A)){

                dirV2Move = Vector2.left;

            }else if(Input.GetKeyDown(KeyCode.D)){

                dirV2Move = Vector2.right;

            }

     

             return dirV2Move;

        }

     

        //生成食物

        void CreatFood(){

            Vector3  foodPosV3 new Vector3(Random.Range(-14,14),Random.Range(-14,14),0);

            Instantiate(snakeFood,foodPosV3,Quaternion.identity);

        }

     

        //移动方法

        void SnakeMove(){

            Vector3  curPos=   transform.position;  //移动之前,首先记录蛇头位置

     

            //创建蛇身

             if(isCreate == true){

                 //创建身体

                Vector3 createBodyPosV3  = curPos; //在蛇头位置创建

                GameObject createBodyObj;

                createBodyObj = Instantiate(snakeBody,createBodyPosV3,Quaternion.identity);

                Color colorRandom  = new Color(Random.value,Random.value,Random.value);

                createBodyObj.GetComponent<MeshRenderer>().material.color  =  colorRandom;

     

                  bodyList.Insert(0,createBodyObj.transform); //将身体插入到集合当中

                  isCreate = false;  //将创建标志置为false

     

             }else if(bodyList.Count>0){

                    //身体个数大于0

                    //蛇身最后位置       //当前蛇头位置

                   bodyList.Last().position = curPos; //更新蛇身位置

     

                    //list里面元素进行交换位置,最后一个元素添加到最前面

                   bodyList.Insert(0, bodyList.Last());

                   bodyList.RemoveAt(bodyList.Count -1); //移除最后一个元素(因为其已经被加入到第一个位置)

              }

     

              transform.Translate(dirV2Move);  //改变当前蛇头位置

         }

    }




    #小案例002、耳轮跳(NG进行中)

    ++小案例002、耳轮跳demo

    ++++HudText.cs

    ++++BallFallScript.cs

    ++++CreateGap.cs

    ++++CreateRing.cs

    ++++CreateTrap.cs

    ++++GameMgr.cs

    ++++RingInfo.cs

    ++++RotatePillar.cs

    ++++SectorInfor.cs




    ###HudText.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\HudText.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public  class  HudText:MonoBehaviour{

        private void Start(){

            GameObject.Destroy(gameObject,1f);

        }

     

        //下落

        private  void  Update(){

            transform.position  -= Vector3.up*Time.deltaTime* 0.5f;

            GetComponent<CanvasGroup>().alpha  -= Time.deltaTime;

        }

     

        //设置值

        public void SetText(string s){

            transform.GetComponentInChildren<Text>().text=s;

        }

    }


    ###BallFallScript.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\BallFallScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  BallFallScript:MonoBehaviour{

        float  g = -9.8f;

        float v = 0;

        float timer = 0;

     

        //1m的间距最大速度达到4.4m/s,这里考虑小球和平板的高度,取3.5f,也就是说最大速度为3.5f

        float  maxV = 3.5f;

     

        public int  power =0;    //小球势能

        public int powerToggle =3;    //达到层数,可以获得击碎能力

     

        private  void  Update(){

            Fall();

        }

     

        private  void Fall(){

            v = v + g *Time.delatTime;

            v = Mathf.Clamp(v, -maxV, maxV);

            transform.position += transform.up*Time.deltaTime*v;

        }

     

        private  void  LateUpdate(){

            float  y = Camera.main.WorldToScreenPoint(transform.position).y;

            if(y /Screen.height<0.7f){

                Camera.main.transform.SetParent(transform);

            }else{

                Camera.main.transform.SetParent(null);

            }

        }

     

        //碰撞结算

        private  void  OnCollisionEnter(Collision collision){

            v =maxV;

            Camera.main.transform.SetParent(null);

     

            SectorInfo si =collision.collider.GetComponent<SectorInfo>();

            if(power>=powerToggle){

                si.transform.parent.GetComponent<RingInfo>().Explosion();

            }else if(si.IsTrap&&si.transform.parent.GetComponent<RingInfo>().isBreaken == false){

                GameObject.FindObjectOfType<GameMgr>().GameOver();

            }

     

            power = 0;

        }

    }


    ###CreateGap.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\CreateGap.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public  class  CreateGap:MonoBehaviour{

        public int minGapGroup=1;

        public int  maxGapGroup=3;

        public int  minGap=2;

        public int  maxGap=4;

     

        MeshCollider[]  sectors;

     

        private  void  Start(){

            sectors = GetComponentsInChildren<MeshCollider>()

     

            int group  = Random.Range(minGapGroup, maxGapGroup+1);

            for(int i =0; i<group; i++){

                int pos  = Random.Range(0,secotrs.Length);

                int gaps  = Random.Range(minGap,maxGap+1);

                for(int  j=0;j <gaps; j++){

                   sectors[(pos+j) %sectors.Length].gameObject.SetActive(false);

                }

            }

        }

    }


    ###CreateRing.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\CreateRing.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  CreateRing:MonoBehaviour{

        public  GameObject  ringPre;

     

        private  void  Start(){

            for(int  i = 0; i <100;i++){

                GameObject ring  = GameObject.Instantiate(ringPre,new Vector3(0, -50+i *1f),Quaternion.identity);

                ring.GetComponent<RingInfo>().index = i;

                ring.transform.SetParent(transform);

            }

        }

    }


    ###CreateTrap.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\CreateTrap.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public  class  CreateTrap:MonoBehaviour{

        public int  minTrapGroup = 1;

        public int  maxTrapGroup =3;

        public int  minTrap = 2;

        public int  maxTrap = 4;

     

        MeshCollider[]  sectors;

     

        private  void Start(){

            sectors = GetComponentsInChildren<MeshCollider>();

     

            int group = Random.Range(minTrapGroup,maxTrapGroup+1);

            for(int  i = 0; i<group;i++){

                int pos = Random.Range(0, sectors.Length);

                int gaps = Random.Range(minTrap,maxTrap+1);

                for(int j=0; j<gaps; j++){

                   int  index = (pos+ j) %sectors.Length;

                   if(sectors[index].gameObject.activeSelf&&transform.GetComponent<RingInfo>().index<95){

                       sectors[index].GetComponent<MeshRenderer>.material.color = Color.red;

                       sectors[index].GetComponent<SectorInfo>.IsTrap=true;

                    }

                }

            }

        }

    }


    ###GameMgr.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\GameMgr.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

    using UnityEngine.SceneManagement;

     

    public class GameMgr:MonoBehaviour{

        //设置分数

        public Text  scoreText;

        public Text  levelText;

        public Button  restartBtn;

     

        public int score=0;

        public  bool  gameOver=false;

     

        priavate  void  Awake(){

            Time.timeScale=0;

            Screen.SetResolution(750,1334,false);

        }

     

        private void  Start(){

            restartBtn.onClick.AddListener(GameStart);

            restartBtn.gameObject.SetActive(false);

        }

     

        public void GameStart(){

            SceneManger.LoadScene(Demo002_HelixJump_Lovezuanzuan);

        }

     

        public void GameOver(){

            gameOver = true;

            Time.timeScale = 0;

            restartBtn.gameObject.SetActive(true);

        }

     

        private  void  Update(){

            if(Input.GetMouseButtonDown(0) && gameOver ==false){

                Time.timeScale = 1;

            }

        }

     

        public void AddScore(int  s, RingInfoinfo){

            score += s;

            HudText hud = ((GameObject)GameObject.Instantiate(Resources.Load(HudText))).transform.GetComponent<HudText>();

            hud.SetText(+ + s);

     

            scoreText.text = score.ToString();

            levelText.text = info.index.ToString();

        }

    }


    ###RingInfo.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\RingInfo.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //立钻哥哥:环信息

    public  class RingInfo:MonoBehaviour{

        public int  index;    //层数

        public bool  isBreaken=false;    //是否击毁

        GameObject  ball;

     

        private  void  Start(){

            ball = GameObject.Find(Ball);

        }

     

        private  void Update(){

            if(ball == null){

                return;

            }

     

            if(ball.transform.position.y < transform.position.y - 0.1f && !isBreaken){

                isBreaken = true;

        

                //提高小球势能

                GameObject.Find(Ball).GetComponent<BallFallScript>().power += 1;

                int power=GameObject.Find(Ball).GetComponent<BallFallScript>().power;

     

                //计算分数,与通过的势能相等

                GameObject.FindObjectOfType<GameMgr>().AddScore(power*4,this);

     

                Explosion();

            }

        }

     

        public void Explosion(){

            //打散散开

            for(int i=0; i <transform.childCount;  i++){

                if(transform.GetChild(i).gameObject.activeSelf == false){

                   continue;

                }

     

                Rigidbody  rig;

                if((rig = transform.GetChild(i).gameObject.GetComponent<Rigidbody>()) == null){

                   rig = transform.GetChild(i).gameObject.AddComponent<Rigidbody>();

                }

                rig.AddForce((transform.GetChild(i).forward+Vector3.up*Random.Range(0.3f,1)) * Random.Range(40,80));

                transform.GetChild(i).GetComponent<MeshCollider>().enabled = false;

            }

     

            StartCoroutine(ChangeAlpha());    //渐隐

            GameObject.Destroy(gameObject,3);    //3s后销毁

        }

     

        IEnumerator ChangeAlpha(){

            float alpha = 1;

        

            while(true){

                alpha -= Time.deltaTime;

                for(int  i =0; i < transform.childCounti++){

                   if(transform.GetChild(i).gameObject.activeSelf == false){

                       continue;

                    }

     

                    Material  mat =transform.GetChild(i).GetComponent<MeshRenderer>.material;

                    transform.GetChild(i).GetComponent<MeshRenderer>.material.color= new Color(mat.color.r,mat.color.g,mat.color.b,alpha)

                }

     

                yield return null;

            }

        }

    }


    ###RotatePillar.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\RotatePillar.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  RotatePillar:MonoBehaviour{

        private void  Update(){

            if(Input.GetMouseButton(0)){

                float y =Input.GetAxis(Mouse X);

                transform.Rotate(Vector3.up,  -Time.deltaTime*180*y);

            }

        }

    }


    ###SectorInfor.cs

    D:\zz_DemoPro()-\小案例002、耳轮跳-HelixJump-\Assets\Project\Scripts\SectorInfo.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  SectorInfo:MonoBehaviour{

        public bool  IsTrap{    get;    set;    }

    }




    #小案例003MVC框架(提升等级案例)

    ++小案例003MVC框架(提升等级案例)

    ++++PlayerMsgController.cs

    ++++PlayerMsgView.cs

    ++++PlayerScript.cs



    ###PlayerMsgController.cs

    C:\000-ylzServ_DemoPro\小案例003\Assets\PlayerMsgController.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //Controller层:

    public  class  PlayerMsgController : MonoBehaviour{

        public  static  PlayerMsgController  controller;

        private int levelUpValue=20;

     

        void Awake(){

            controller = this;

        }

     

        void Start(){

            PlayerScript.GetMod().PlayerLevel = 1;

            PlayerScript.GetMod().PlayerExperience = 0;

            PlayerScript.GetMod().PlayerFullExperience = 100;

            PlayerScript.GetMod().GoldNum = 0;

        }

     

        //提升经验按钮点击事件

        public void OnExperienceUpButtonClick(){

            PlayerScript.GetMod().PlayerExperience += levelUpValue;

     

            if(PlayerScript.GetMod().PlayerExperience >= PlayerScript.GetMod().PlayerFullExperience){

                PlayerScript.GetMod().PlayerLevel +=1;

                PlayerScript.GetMod().PlayerFullExperience += 200*PlayerScript.GetMod().PlayerLevel;

                levelUpValue += 20;

            

                if(PlayerScript.GeMod().PlayerLevel % 3 == 0){

                   PlayerScript.GetMod().GoldNum += 100*PlayerScript.GetMod().PlayerLevel;

                }

            }

        }

    }


    ###PlayerMsgView.cs

    C:\000-ylzServ_DemoPro\小案例003\Assets\PlayerMsgView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    //立钻哥哥:UI视图层

    public  class PlayerMsgView :MonoBehaviour{

        //UI

        public  Text playerLevel;

        public  Text playerExperience;

        public  Text goldNum;

        public  Button  experienceUpButton;

     

        void Start(){

            //委托事件绑定

            PlayerScript.GetMod().OnLevelChange += SetLevel;

            PlayerScript.GetMod().OnExperienceChange += SetExperience;

            PlayerScript.GetMod().OnFullExperienceChange += SetFullExperience;

            PlayerScript.GetMod().OnGlodNumChange += SetGoldNum;

     

            //View绑定按钮控制功能

            //添加观察者:

            experienceUpButton.onClick.AddListener(

            PlayerMsgController.controller.OnExperienceUpButtonClick);

        }

     

        //修改UILevel

        public void SetLevel(int  level){

            playerLevel.text = level.ToString();

        }

     

        //修改UI经验值

        public void SetExperience(int  experience){

            //将字符串以/拆开

            string[]  str = playerExperience.text.Split(newchar[]{/ });

        }

     

        public void SetFullExperience(int  fullExperience){

            string[]  str = playerExperience.text.Split(newchar []{ / });

            playerExperience.text  = str[0] +/ + fullExperience;

        }

     

        public void SetGoldNum(int  goldn){

            goldNum.text = goldn.ToString();

        }

     

    }


    ###PlayerScript.cs

    C:\000-ylzServ_DemoPro\小案例003\Assets\PlayerScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //模型委托(当用户信息发生变化时执行)

    public  delegate void OnValueChange(int  val);

     

    public  class  PlayerScript{

        private int playerLevel; //玩家等级

        private int  playerExperience;  //玩家经验

        private int playerFullExperience;  //玩家升级经验

        private int goldNum;  //金币数量

     

        //声明委托对象

        public OnValueChange OnLevelChange;  //当等级发生变化时,触发的事件

        public OnValueChange OnExperienceChange;  //当经验发生变化时,触发的事件

        public OnValueChange OnFullExperienceChange;  //当升级经验发生变化时

        public OnValueChange OnGoldNumChange; //当金币数量发生变化时

     

        private static  PlayerScript  mod; //单例

        public  static  PlayerScript GetMod(){

            if(mod == null){

                mod = new  PlayerScript();

            }

            return  mod;

        }

        private  PlayerScript(){

        }

     

        //玩家等级属性

        public int  PlayerLevel{

            get{

               return playerLevel;

            }

            set{

                playerLevel = value;

                if(OnLevelChange!= null){

                   //如果委托对象不为空

                   OnLevelChange(playerLevel);  //执行委托

                }

            }

        }

     

        //玩家经验属性

        public int  PlayerExperience{

            get{

                return playerExperience;

            }

           set{

                playerExperience = value;

                if(OnExperienceChange !=null){

                     OnExperienceChange(playerExperience);

                }

            }

        }

     

        //玩家升级经验属性

        public int  PlayerFullExperience{

            get{

                return playerFullExperience;

            }

            set{

                playerFullExperience = value;

                if(OnFullExperienceChange!= null){

                   OnFullExperienceChange(playerFullExperience);

                }

            }

        }

     

        //金币数量属性

        public int  GoldNum{

            get{

                return goldNum;

            }

            set{

                goldNum = value;

                if(OnGoldNumChange != null){

                   OnGoldNumChange(goldNum);

                }

            }

        }

    }



    #小案例004、简单背包案例

    ++小案例004、简单背包案例

    ++++Controller/

    --PlayerBagController.cs

    ++++Model/

    --PlayerModelScript.cs

    --ToolModel.cs

    ++++View/

    --BagView.cs

    --GridView.cs

    --HPView.cs

    --PlayerBagView.cs

    --PlayerInfoView.cs







    ##Controller/

    ++Controller/

    ++++PlayerBagController.cs

    ###PlayerBagController.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\Controller\PlayerBagController.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.EventSystems;

    using System;

    using System.Reflection;

    using UnityEditor;

     

    //实现赋值数据,展示数据,物品拖拽,交换等主要功能

    //    赋值M -- V交互

    public  class  PlayerBagController :MonoBehaviour,IMoveHandle{

        //引入背包视图,相当于将其下的所有子物体脚本都引入

        public BagView  bagView; //背包视图

     

        void Start(){

            MakeData();  //赋值数据

            ShowData(); //展示数据

        }

     

        //测试数据:

        PlayerModelScriptplayer;

        public  Sprite  s1;

        public  Sprite  s2;

        public  Sprite  s3;

        public  Sprite  s4;

        //public Sprite s5;

        //public Sprite s6;

     

        void MakeData(){

            player = new  PlayerModelScript(立钻哥哥,1000,200);

            ToolModel   t1new  ToolModel(道具1,ToolType.HP,2000,s1);

            ToolModel   t2 = new ToolModel(道具2,ToolType.HP,500,s2);

            ToolModel   t3new  ToolModel(道具3,ToolType.ATK,300,s3);

            ToolModel   t4=  new  ToolModel(道具4,ToolType.ATK,100,s4);

     

            //放入指定下标

            player.bagArray[0] = t1;

            player.bagArray[5] = t2;

            player.bagArray[16] = t3;

            player.bagArray[7] =t4;

        }

     

        void ShowData(){

            //背包

            //生成背包格子

            creatGrid(

                player.bagArray,

               bagView.playerBagView.gridGroupView.transform,

               “BagGrid);

      

            //装备

            creatGrid(){

                player.gearArray,

                bagView.playerInfoView.gridGroupView.transform,

                GearGrid

            };

     

            //显示生命值

            bagView.playerInfoView.hpView.HPValue.text=player.HP.ToString();

        }

     

        //1、根据数组元素个数生成

        //2、父物体

        //3、格子tag

        void creatGrid(ToolModel[]  arr, Transform  t, string  gridTag){

            for(int i=0; i <arr.Length; i++){

                //生成格子

                GameObject objInstantiate<GameObject>(

                   Resources.Load<GameObject>(Perfabs/GridView),

                   Vector3.zero,

                   Quaternion.identity

                );

     

                //参数赋值:

                obj.tag = gridTag; //tag值:格子tag赋值给生成的格子

                GridView  gv = obj.GetComponent<GridView>(); //获取脚本组件

                gv.index =i; //设置格子index

                 //走过之一段代码之后controller就为格子的代理,那么其就要执行接口里边的方法

                 gv.moveHandle = this; //设置代理

     

                //给图片赋值

                 if(arr[i]  != null){

                   gv.contentImage.gameObject.SetActive(true);  //激活image

                   gv.contentImage.sprite = arr[i].toolSprite;

                 }

     

                 //添加到父物体

                obj.transform.SetParent(t);

            }

         }

     

        /*

     移动有四种情况:

        --1、背包--->背包

        --2、背包--->装备

        --3、装备--->装备

        --4、装备--->背包

        --5、有--->

        --6、丹药类型点击消失增加属性

        */

        //实现接口方法

        Transform  targetTransform; //目标位置

     

        public void BeginMove(GridView  grid, PointerEventData  pointData){

                if(grid.tag ==  “BagGrid){

                    //判空:如果背包数组没有东西那么不需要移动

                   if(player.bagArray[grid.index] == null){

                       return;

                    }

                }

     

              if(gird.tag ==GearGrid){

                 //判空:装备格子判断

                if(player.gearArray[gird.index] == null){

                   return;

                }

            }

            #warning有数据

     

            //有数据:开始拖拽前记录信息不交换时候让其回到原来位置

             targetTransform = grid.contentImage.transform;

            gird.contentImage.raycastTarget = false; //关闭射线检测(检测后方物体)

            targetTransform.SetParent(targetTransform.root); //脱离父物体

        }

     

        public void Move(GridView  grid,  PointerEventData pointData){

                if(targetTransform == null){

                   //如果目标为空,那么返回原来位置

                   return;

                 }

                targetTransform.position = Input.mousePosition;

        }

     

        //PointerEventData:系统方法

        public void EndMove(GridView  grid,  PointerEventData  pointData){

                if(targetTransform==null){

                   return;

                 }

     

                //pointData.pointerEnter:目标物体

                 GameObject pointerEnter = pointData.pointerEnter; //鼠标松手后最后触碰的物体

     

                //从背包区开始拖拽

                 if(grid.tag == BagGrid){

                     //到背包区

                    if(pointerEnter.tag ==BagGrid){

                        GridView  gv = pointerEnter.GetComponent<GridView>();

            

                          //判断格子中是否有物品

                         //gv:目标格子

                        if(player.bagArray[gv.index] == null){

                           ChangeUINullGrid(grid, gv);  //grid:当前格子

                        }else{

                           ChangeUIFullGrid(grid, gv); //UI

                        }

     

                      //变数据

                    ToolModel tm = player.bagArray[gv.index];

                    player.bagArray[gv.index] = player.bagArray[gird.index];

                    player.bagArray[grid.index] = tm;

                 }

     

                //到装备区

                if(pointerEnter.tag ==GearGrid){

                    //判断拖拽的是否是装备

                     if(player.bagArray[gird.index].type == ToolType.ATK){

                       GridView  gv = pointerEnter.GetComponent<GridView>();//获取脚本组件

            

                        //判断是否有数据

                       if(player.gearArray[gv.index] == null){

                           ChangeUINullGrid(gird,gv); //

                         }else{

                           ChangeUIFullGrid(grid,gv); //

                        }

     

                         //数据交换

                         ToolModel tm = player.bagArray[gird.index];

                          player.bagArray[gird.index] = player.gearArray[gv.index];

                          player.gearArray[gv.index] = tm;

                    }

                }

            }

     

            //从装备区拖拽

            if(grid.tag ==GearGrid){

                //到装备区

                if(pointerEnter.tag ==GearGrid){

                    GridView  gvpointerEnter.GetComponent<GridView>();

                   if(player.gearArray[gv.index] == null){

                       ChangeUINullGrid(grid,gv); //

                    }else{

                       ChangeUIFullGrid(grid,gv);  //不空

                    }

     

                    //交换数据

                   ToolModel tm = player.gearArray[gv.index];

                   player.gearArray[gv.index] = player.gearArray[grid.index];

                   player.gearArray[grid.index] = tm;

                 }

     

                //到背包

                if(pointerEnter.tag == BagGrid){

                    GridView  gv = pointerEnter.GetComponent<GridView>();

                   bool  isChange =true; //判断是否交换

     

                   if(player.bagArray[gv.index] == null){

                        ChangeUINullGrid(gird,gv); //

                    }else{

                          //判断物体的类型

                          //如果不是装备则UI不交换

                       if(player.bagArray[gv.index].type == ToolType.ATK){

                           ChangeUIFullGrid(grid,gv);  //不空

                        }else{

                           isChange =false;

                        }

                    }

     

                    if(isChange){

                       //数据

                      ToolModel  tm = player.bagArray[gv.index];

                     player.bagArray[gv.index] = player.gearArray[grid.index];

                     player.gearArray[grid.index] = tm;

                    }

                }

            }

     

            targetTransform.SetParent(grid.transform); //返回原来的格子

            targetTransform.localPosition = Vector3.zero; //在父物体的位置localPosition0

            targetTransform = null; //0

        }

     

        public void ClickTool(GridView  gridPointerEventData pointData){

            if(player.bagArray[grid.index] != null){

                if(player.bagArray[grid.index].type == ToolType.HP){

                   //数据更新

                   player.HP+= player.bagArray[grid.index].value;

                   player.bagArray[grid.index] = null;

     

                   //UI更新

                   bagView.playerInfoView.hpView.HPValue.text = player.HP.ToString();

                   grid.contentImage.sprite = null;

                  grid.contentImage.gameObject.SetActive(false);

                }

            }

        }

     

        #region 改变UI

     

        //放到没有物品的格子中(destination: 目标格子)

        void ChangeUINullGrid(GridView  origin,  GridView destination){

            destination.contentImage.gameObject.SetActive(true); //目的格子图片激活

        

            //将源格子的图片赋值给目的格子

            destination.contentImage.sprite = origin.contentImage.sprite;

            origin.contentImage.sprite = null;  //将源格子图片清空

            origin.contentImage.gameObject.SetActive(false); //将源格子图片取消激活

        }

     

        //放到有物品的格子中

        void ChangeUIFullGrid(GridView origin,  GridView destination){

            Sprite s = destination.contentImage.sprite;

            destination.contentImage.sprite = origin.contentImage.sprite;

            origin.contentImage.sprite = s;

        }

     

        #endregion

     

    }


    ##Model/

    ++Model/

    ++++PlayerModelScript.cs

    ++++ToolModel.cs

    ###PlayerModelScript.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\Model\PlayerModelScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public class  PlayerModelScript{

        public  string playerName{get;set; }  //姓名

        public int HP{get;set; }  //血量

        public int  ATK{get;set; }  //攻击力

        public ToolModel[]  gearArray;  //装备区

        public  ToolModel[]  bagArray;  //背包

     

        public PlayerModelScript(string  name,int hp,int  atk){

            playerName = name;

            HP = hp;

            ATK = atk;

            gearArray = new ToolModel[8];  //装备

            bagArray = new ToolModel[20];  //背包

        }

    }


    ###ToolModel.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\Model\ToolModel.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public enmu  ToolType{

        HP,

        ATK

    }

     

    //立钻哥哥:道具Model

    public  class  ToolModel{

        public string  toolName{set;get; }  //道具名字

        public ToolType type{set;get; } //道具类别

        public int  value{set;get; } //数值

        public Sprite  toolSprite{set;get; }  //道具图片

     

        //构造方法

        public  ToolModel(string  name, ToolTypett,  int v, Sprite sp){

            toolName = name;

            type = tt;

            value = v;

            toolSprite = sp;

        }

    }


    ##View/

    ++View/

    ++++BagView.cs

    ++++GridView.cs

    ++++HPView.cs

    ++++PlayerBagView.cs

    ++++PlayerInfoView.cs


    ###BagView.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\View\BagView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //挂载在BagView上,目的收集子视图View

    public class BagView :MonoBehaviour{

        public PlayerInfoView  playerInfoView;  //人物界面

        public  PlayerBagView  playerBagView;  //背包界面

    }


    ###GridView.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\View\GridView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

    using UnityEngine.EventSystems;

    //using System.Net.NetworkInformation;

     

    //移动的接口

    public interface IMoveHandle{

        void BeginMove(GridView  grid,  PointerEventData pointData);  //鼠标进入

        void Move(GridView  grid,  PointerEventData pointData); //移动

        void EndMove(GridView  grid,  PointerEventData pointData);  //结束移动

        void ClickTool(GridView  grid,  PointerEventData pointData); //点击的道具

    }

     

    public  class  GridView : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler,IPointerClickHandler{

        public Image  contentImage;

        public int index{set;get; }  //格子创建时的下标,标记它的目的是为了在交换物品或者移动时候和数组元素对应

        public IMoveHandle moveHandle; //将接口定义为视图的字段或者属性

     

        //实现继承过来接口里边的内容

        public void OnBeginDrag(PointerEventData eventData){

            moveHandle.BeginMove(this,eventData);

        }

     

        public void OnDrag(PointerEventData  eventData){

            moveHandle.Move(this,eventData);

        }

     

        public void OnEndDrag(PointerEventData  eventData){

            moveHandle.EndMove(this,eventData);

        }

     

        public void OnPointerClick(PointerEventData  eventData){

            moveHandle.ClickTool(this,eventData);

        }

    }


    ###HPView.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\View\HPView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    //获得它下边的两个文本

    public  class  HPView : MonoBehaviour{

        public  Text HpText;

        public Text HPValue;

    }


    ###PlayerBagView.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\View\PlayerBagView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public  class PlayerBagView: MonoBehaviour{

        public RectTransform gridGroupView;

    }


    ###PlayerInfoView.cs

    C:\000-ylzServ_DemoPro\小案例004\Bag\Assets\Scripts\View\PlayerInfoView.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //任务属性界面脚本(目的:收集其子物体关于View的脚本)

    public  class  PlayerInfoView : MonoBehaviour{

        public  RectTransform  gridGroupView; //格子视图

        public HPView  hpView;

    }




    #小案例005、塔防Demo

    ++小案例005、塔防Demo

    ++++BulletScript.cs

    ++++CameraMoveScript.cs

    ++++EndScript.cs

    ++++GameDataScript.cs

    ++++InitMonsterScript.cs

    ++++InitTowerScript.cs

    ++++MonsterScript.cs

    ++++TowerFireScript.cs




    ###BulletScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\BulletScript.cs

    using UnityEngine;

    using System.Collections;

     

    //该脚本功能是控制子弹的发射和碰撞检测(加到粒子特效上,模拟子弹)

    public class BulletScript :MonoBehaviour{

        public  Transform  target;  //子弹要攻击的目标

        public float bulletSpeed=3; //子弹的飞行速度

        public float damager=100;  //子弹的伤害值

     

        void Update(){

            if(target){

                Vector3 dir =target.position-transform.position;  //得到子弹要飞行的向量

                Transform.position += dir*Time.deltaTime*bulletSpeed; //子弹移动

            }else{

                Destroy(gameObject);  //如果目标是空,把子弹销毁

            }

        }

     

         void  OnTriggerEnter(Collider  other){

            if(other.tag == monster){

                Other.GetComponent<MonsterScript>().health -= damage; //怪物掉血

                Destroy(this.gameObject);  //把子弹销毁掉

            }

        }

    }


    ###CameraMoveScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\CameraMoveScript.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  CameraMoveScript : MonoBehaviour{

        public float  moveSpeed =3;

     

        void Update(){

            float hor  = Input.GetAxis(Horizontal);

            float ver  = Input.GetAxis(Vertical);

            transform.position += new Vector3(hor,0,ver) *Time.deltaTime*moveSpeed;

        }

    }



    ###EndScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\EndScript.cs

    using UnityEngine;

    using System.Collections;

     

    //加在End物体上,功能是当怪物触发后,把怪物销毁

    public  class  EndScript : MonoBehaviour{

        void OnTriggerEnter(Collider other){

            if(other.tag ==  monster){

                Debug.Log(tttt);

                Destroy(other.gameObject);

            }

        }

    }


    ###GameDataScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\GameDataScript.cs

    using UnityEngine;

    using System.Collections;

    using System;

     

    //功能是控制所生成怪物的数量,速度和时间间隔,主要的思路是用一个结构体数组,数组的长度即为波数,每一波对应数组里面的一个元素,读取结构体里面的数据。

    public  class  GameDataScript : MonoBehaviour{

        public  static GameDataScript Instance;

     

        public struct  Data{

            public float waitTime; //等待多长时间产生一波敌人

            public int monsterCount;  //每一波敌人的数量

            public float moveSpeed;  //每一波敌人的移动速度

        }

     

        //刚开始时的默认数据

        float  waitTimeDefault =3;

        int  monsterCountDefault= 3;

        float  moveSpeedDefault =2;

        public Data[] monsterData; //每一波所对应的数据

     

        void  Awake(){

            Instance = this;

        }

     

        void Start(){

            monsterData = new Data[10];

            for(int i =0; i < monsterData.Lengthi++){

                //第一次循环时把默认数据赋值给第一个元素

                monsterData[i].waitTime =waitTimeDefault;

                monsterData[i].monsterCount = monsterCountDefault;

                monsterData[i].moveSpeed =moveSpeedDefault;

     

                //每循环一次数据增加

                waitTimeDefault += 0.5f;

                monsterCountDefault += 1;

                moveSpeedDefault += 0.3f;

            }

        }

    }


    ###InitMonsterScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\InitMonsterScript.cs

    using UnityEngine;

    using System.Collections;

     

    //怪物生成(加到Start空物体上)

    public  class  InitMonsterScript : MonoBehaviour{

        puiblic  GameObject monster; //怪物预设体

        float  timer; //计时器

        int  index = 0; //生成怪物的波数

        bool isInit = false  //当前是否正在生成怪物

        int  monsterCount = 0;  //一波中怪物的数量

        bool isGaming=true; //是否在游戏中

     

        void Update(){

            if(isGaming){

                timer += Time.deltaTime;

     

                //读取Data数组中index中相对应的元素,再找到里面对应的相关数据

                //1、先得到时间间隔

                float timeInterval  = GameDataScript.Instance.monsterData[index].waitTime;

            

                //2、如果计时器达到等待生成怪物的时间,并且没有初始化怪物,则把计时器归0,开始初始化怪物

                if(!isInit && timer > timeInterval){

                   timer = 0;

                   isInit =true;

     

                }else if(isInit){

                     //如果能初始化怪物

                   if(timer > 1){

                        //每隔一秒生成一个怪物

                       timer =0;

                        GameObject  currentMonster = Instantiate(monster,transform.position,Quaternion.identity)  as GameObject; //生成怪物

                         currentMonster.GetComponent<UnityEngine.AI.NavMeshAgent>().speed = GameDataScript.Instance.monsterData[index].moveSpeed;  //把数据组中的速度赋值给导航中的速度

                        monsterCount++;  //怪物数量增加

     

                       if(monsterCount == GameDataScript.Instance.monsterData[index].monsterCount){

                            //如果怪物生成的数量与给定的数量相同

                           monsterCount = 0;  //数据归零

                           index++; //进入下一波

                           isInit = false; //不能再进行初始化了

     

                           if(index >GameDataScript.Instance.monsterData.Length-1){

                                //说明波次已经够了,此时游戏结束

                              isGaming =false;

                            }

                        }

                   }

               }

           }

        }

    }


    ###InitTowerScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\InitTowerScript.cs

    using UnityEngine;

    using System.Collections;

     

    //加到空GameController上,主要的功能是点击鼠标左键,创建炮塔

    public  class InitTowerScript :MonoBehaviour{

        public GameObject  tower;

        RaycastHit hit;

     

        void  Update(){

            //如果按下鼠标左键

            if(Input.GetMouseButtonDown(0)){

                //从摄像机到鼠标点击位置发出一条射线

                if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out  hit)){

                   Debug.Log(hit.collider.name);

                

                    //检测点击到的是否是木箱,如果名字中包含Tower,并且没有子物体

                   if(hit.collider.name.IndexOf(Tower) != -1 && hit.collider.transform.childCount ==0){

                       Vector3  pos =hit.collider.transform.position+Vector3.up* 2.65f;

                       GameObject  gun = Instantiate(tower,pos,Quaternion.identity) as GameObject; //生成大炮

                       gun.transform.SetParent(hit.collider.transform);  //给生成的炮塔设置父物体

                    }

                }

            }

        }

    }


    ###MonsterScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\MonsterScript.cs

    using UnityEngine;

    using System.Collections;

     

    //功能是控制怪物的运动(脚本加到Monster上)

    public  class  MonsterScript :MonoBehaviour{

        public float  health = 100; //生命值

        UnityEngine.AI.NavMeshAgent  nav; //导航组件

        Transform  end;  //终点

        Animation  ani;  //动画组件

     

        void  Awake(){

            nav = GetComponent<UnityEngine.AI.NavMeshAgent>();

            ani = GetComponent<Animation>();

            end = GameObject.FindWithTag(end).transform;

        }

     

        void  Start(){

            nav.destination = end.position;

        }

     

        void  Update(){

            //如果血量小于等于0

            if(health <0){

                GetComponent<CapsuleCollider>().enabled = false;  //关闭碰撞器

                ani.CrossFade(Dead);

                Destroy(gameObject,1); //1秒钟后销毁自己

            }

        }

    }


    ###TowerFireScript.cs

    D:\000-ylzServ_DemoPro\小案例005\Assets\DemoBak\Homework\TowerFireScript.cs

    using UnityEngine;

    using System.Collections;

    using System.Collections.Generic;

     

    public  class  TowerFireScript :MonoBehaviour{

        public  GameObject  bullet;  //生成炮弹

        public float  fireRadius= 7f;  //攻击半径

        public float rotateSpeed=3f;  //炮头转向速度

        public float distance=0.5f;  //炮头与炮身之间的距离

        public float bullectMoveSpeed=5f; //子弹飞行的速度

        public  Transform  fireTarget; //攻击的目标

        public float  fireTimeInterval=0.5f;  //发射子弹的间隔时间

        private float timer=0;  //计时器

        private  Queue<Transform>  monsterQueue;  //怪物的队列

     

        void Awake(){

            monsterQueue = new Queue<Transform>();

        }

     

        void  Start(){

        }

     

        void  Update(){

            //如果攻击目标为空

            if(fireTarget == null){

                if(monsterQueue.Count>0){

                   fireTaget = monsterQueue.Dequeue();

                }

            }else{

                Fire();

            }

        }

     

        //当怪物进入触发器中,把该怪物添加到要攻击的队列中

        void  OnTriggerEnter(Collider  other){

            Debug.Log(enter);

     

            //如果是怪物

            if(other.tag == monster){

                monsterQueue.Enqueue(other.transform);

            }

        }

     

        //离开触发

        void  OnTriggerExit(Collider  other){

            Debug.Log(exit);

            if(other.tag == monster){

                //如果是当前正在攻击的目标

                 if(other.transform == fireTarget){

                   fireTarget= null;  //把攻击目标设置为空

                }else{

                     //如果队列不为空

                    if(monsterQueue.Count>0){

                        monsterQueue.Dequeue();

                     }

                }

            }

        }

     

        void Fire(){

            Vector3 dir =fireTarget.position-transform.position;

            Quaternion rotation = Quaternion.LookRotation(dir);

            transform.rotation =Quaternion.Lerp(transform.rotation,rotation,Time.deltaTime*rotateSpeed);

            Debug.DrawRay(transform.position, dir,Color.red);

            Debug.DrawRay(transform.position, transform.forward * 10,Color.green);

     

            if(Vector3.Angle(dir,transform.forward) <5){

                InitBullet();

             }

        }

     

        void InitBullet(){

            timer += Time.deltaTime;

            if(timer >fireTimeInterval){

                timer = 0;

                Vector3 point = transform.GetChild(0).position+transform.GetChild(0).forward*distance;

                GameObject currentBullet =Instantiate(bullet,point,Quaternion.identity)asGameObject;

                currentBullet.GetComponent<BulletScript>().target = this.fireTarget;

                currentBullet.GetComponent<BulletScript>().bulletSpeed = this.bulletMoveSpeed;

            }

         }

    }




    #小案例006、秘密行动DemoNG进行中)

    ++小案例006、 秘密行动Demo

    ++++AlarmLight.cs

    ++++CameraMovement.cs

    ++++CCTVPlayerDetection.cs

    ++++DoorAnimation.cs

    ++++EnemyAI.cs

    ++++EnemyAnimation.cs

    ++++EnemyShooting.cs

    ++++EnemySight.cs

    ++++HashIDs.cs

    ++++KeyPickup.cs

    ++++LaserController.cs

    ++++LaserSwitchDeactivation.cs

    ++++LastPlayerSighting.cs

    ++++LiftDoorsTracking.cs

    ++++PlayerHealth.cs

    ++++PlayerInventory.cs

    ++++PlayerMovement.cs

    ++++SyncDoor.cs

    ++++Tags.cs





    ++秘密行动思维导图

    ---0、添加Tag脚本

    ---1、添加场景模型

    ---2、创建一个空游戏物体

    ---3、添加英雄char_ethan

    ---4、添加平行光

    ---5、给主摄像机添加脚本,用来控制摄像机的移动

    ---6、在GameController上添加子物体SecondSound

    ---7、给警报喇叭添加标签

    ---8、给GameController添加脚本LastPlayerSighting

    ---9、添加激光灯

    ---10、创建空物体Doors,用来管理自动门

    ---11、创建空物体SwitchUnits来控制激光门的开和关

    ---12、添加钥匙卡

    ---13、添加CCTV摄像机

    ---14、添加电梯外面的开关门

    ---15、添加电梯

    ---16、放置巡逻点

    ---17、小机器人

    ---18、添加手枪

    ---======================---===============---

     

    ++++0、添加Tag脚本,该脚本可以直接取到tag值,不加到任何游戏物体上。

     

    ++++1、添加场景模型

    --1.1、添加 env_stealth_static

    --1.2、添加卡车 prop_battleBus

    --1.3、添加网格碰撞器 env_stealth_collision

     

    ++++2、创建一个空游戏物体

    --2.1、命名GameController

    --2.2、添加声音组件播放背景音乐

        ---playonawake = true,

        ---loop = true,

        ---volume = 1

    --2.3、添加脚本HashID,用来给动画控制设置参数。

    --2.4、添加tagGameController

     

    ++++3、添加英雄 char_ethan

    --3.1、添加胶囊碰撞器

    --3.2、添加刚体,冻结所有的旋转以及y轴方向的位置

    --3.3、添加声音组件,声音片段为脚步声

    --3.4、添加动画控制器PlayerAnimator

    --3.5、添加脚本PlayerHealth,用来控制英雄的少血以及死亡

    --3.6、添加脚本PlayerMove,用来控制英雄的移动

    --3.7、添加tagPlayer

     

    ++++4、添加平行光

    --4.1、做了警报灯,颜色为红色,intensity=0

    --4.2、添加脚本AlarmLight脚本组件,用来控制警报灯由明变暗再由暗变明

    --4.3、添加tagAlarmLight

     

    ++++5、给主摄像机添加脚本,用来控制摄像机的移动

    --5.1Editor/ProjectSetting/Physic/Hit Triggers取消勾选(否则射线会检测触发器,取消后只会检测碰撞器)

    --5.2、添加脚本CameraMove

     

    ++++6、在GameController上添加子物体SecondSound

    --6.1、给子物体添加AudioSource组件

    --6.2、添加声音片段music_panic

    --6.3、设置声音的初始值为0

    --6.4PlayOnAwakeLoop勾选

     

    ++++7、给警报喇叭添加标签

    --7.1、给prop_megaphon添加siren标签

    --7.2、给六个喇叭添加AudioSource组件

    --7.3、添加声音片段alarm_trigger

    --7.4、设置声音的初始值为0

    --7.5PlayOnAwakeLoop勾选

     

    ++++8、给GameController添加脚本LastPlayerSighting

     

    ++++9、添加激光灯

    --9.1、创建空物体Lasers用来管理激光门

    --9.2、把fx_laserFence_lasers插到场景中并放到合适的位置(大小和旋转)

    --9.3、添加AudioSource组件,加上laser_hum声音片段,把LoopPlayOnAwake勾选,音量设置为1

    --9.4、添加点灯源组件,颜色为红色,Range=5Intensity=1.5Bounce=1

    --9.5、添加一个Box触发器,用来进行触发检测

    --9.6、添加脚本LaserController

     

    ++++10、创建空物体Doors,用来管理自动门

    --10.1、把door_generic_slide拖到合适的位置

    --10.2、添加球形触发器,半径为1.5,高为1

           在门的子物体上添加盒形碰撞器,防止没有钥匙的时候,玩家可以直接穿透门

    --10.3、添加AudioSource组件,和door_open声音片段,最小距离1,最大距离为5

    --10.4、添加DoorAnimator动画控制器组件,给自动门添加动画,添加播放声音的事件

    --10.5、添加脚本DoorAnimation

     

    ++++11、创建空物体SwitchUnits来控制激光门的开和关

    --11.1、拖动prop_switchUnit_screen到场景中

    --11.2、在父物体上添加Box碰撞器,在子物体上添加Box触发器,在子物体上添加声音组件

    --11.3、添加脚本 LaserSwitchDeactivation

     

    ++++12、添加钥匙卡

    --12.1、拖动prop_keycard到场景中合适的位置

    --12.2、添加球形触发器

    --12.3、添加点光源,颜色为蓝色

    --12.4、添加动画控制器组件

     

    ++++13、添加CCTV摄像机

    --13.1Y轴旋转180

    --13.2、子物体_body x轴旋转30

    --13.3、给子物体_joint添加帧动画

    --13.4、在_body子物体下添加空物体trigger,沿X轴旋转30度,并添加MeshCollider组件,添加prop_cctvCam_collision,并使其变为触发器

    --13.5、添加Light组件,选择spot的灯光,Range=40, Angle=62intensity=4, bounce=1, cookie选择fx_cameraView_alp

    --13.6、给trigger子物体添加脚本CCTV

     

    ++++14、添加电梯外面的开关门

    --14.1、拖动door_exit_outer到合适的位置,沿y轴旋转-90

    --14.2、添加球形碰撞器

    --14.3、添加声源组件,添加open_door声音片段

    --14.4、添加动画控制器RedDoorAnimator

    --14.5、添加DoorAnimation脚本组件

     

    ++++15、添加电梯

    --15.1、拖动prop_lift_exit到电梯井里面,并沿Y轴旋转-90

    --15.2、添加声源组件,并添加endgame声音片段

    --15.3、给子物体_carriage添加声源组件,添加lift_rise声音片段

    --15.4、给_carriage添加四个box碰撞器:

    ---第一个设置为trigger

    ---第二个center.z=2(其余不变), size.z=0.15(其余不变)

    ---第三个center.z=2(其余不变),size.z=0.15(其余不变)

    ---第四个center.x=1.87,其余为0size.x=0.2

    --15.5、给carriage添加脚本LiftDoor

    --15.6、给子物体door_inner添加脚本SyncDoor

     

    ++++16、放置巡逻点

     

    ++++17、小机器人

    --17.1、添加小机器人的动画控制器EnemyAnimatorController

    --17.2、在hashids里面添加新的动画参数值

    --17.3、添加动画遮罩EnemyShootingMask

    --17.4、设置射击层的过渡条件

    --17.5、设置导航路面

    --17.6、给小机器人添加animator组件,刚体组件,胶囊体碰撞器,球形触发器导航组件

    --17.7、添加EnemySight组件

     

    ++++18、添加手枪

    --18.1、在机器人char_robotGuard_RightHandThumb1下添加子物体prop_sciFiGun_low

    --18.2、在枪的子物体下添加子物体Effect,添加灯光组件以及linerander组件,二者都设置为不可用。

    --18.3、给射击的动画片段添加动画曲线

    --18.4、添加脚本EnemyAnimation

    --18.5、在场景中添加小机器人巡逻的小旗帜

    --18.6、添加脚本EnemyAI

    --18.7、添加脚本EnemyShooting


    ###AlarmLight.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\AlarmLight.cs

    using UnityEngine;

    using System.Collections;

     

    public class AlarmLight:MonoBehaviour{

        public  bool  alarmOn=false;    //是否开启警报

        public float  turnSpeed=3f;    //警报灯切换速度

        private float highIntensity=2f;    //高光强

        private float  lowIntensity=0f;    //低光强

        private float  targetIntensity=0f;    //目标光强

        private  Light  alarmLight;    //警报灯光

     

        void  Awake(){

            alarmLight = GetComponent<Light>();    //获取警报灯

            targetIntensity = highIntensity;    //设置目标光强初始值为高光强

        }

     

        void  Update(){

            //如果警报开启

            if(alarmOn){

                //警报灯切换到目标光强

                alarmLight.intensity =  Mathf.Lerp(alarmLight.intensity,targetIntensity,Time.deltaTime*turnSpeed);

     

                //如果当前光强强度到达了目标光强,需要切换目标

                if(Math.Abs(targetIntensity-alarmLight.intensity) <0.05f){

                   //如果当前目标是高光强

                   if(targetIntensity == highIntensity){

                       targetIntensity = lowIntensity;   //切换目标为低光强

                    }else{

                       targetIntensity =highIntensity;    //否则切换目标为高光强

                    }

                }

            }else{

                 //警报灯渐变到低光强

                alarmLight.intensity  = Mathf.Lerp(alarmLight.intensity,lowIntensity,Time.deltaTime*turnSpeed);

     

                //如果已经到达了低光强

                if(alarmLight.intensity < 0.05f){

                    //直接切换光强为0,减少CPU的计算

                   alarmLight.intensity =lowIntensity;    

                }

            }

        }

    }


    ###CameraMovement.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\CameraMovement.cs

    using UnityEngine;

    using System.Collections;

     

    public  class CameraMovement:MonoBehaviour{

        public float moveSpeed= 3f;    //摄像机移动速度

        public float  turnSpeed=10f;    //摄像机旋转速度

        private  Transform  player;    //玩家

        private  Vector3  direction;    //摄像机与玩家之间的方向向量

        private  RaycastHit  hit;    //射线碰撞检测器

        private float  distance;    //摄像机与玩家的最小距离

        private  Vector3[]  currentPoints;    //当前所有的点

     

        void  Awake(){

            player = GameObject.FindWithTag(Tags.Player).transform;

            currentPoints = new Vector3[5];

         }

     

         void  Start(){

            //计算玩家头顶方向与摄像机的距离

            distance = Vector3.Distance(transform.position,player.position) -0.5f;

     

            //游戏开始时玩家与摄像机之间的方向向量

            direction = player.position-transform.position;

         }

     

        void  Lateupdate(){

            Vector3 startPoint =player.position-direction;    //第一个点

            Vector3 endPoint =player.position+Vector3.up*distance;    //最后一个点

            currentPoint[1] = Vector3.Lerp(startPoint,endPoint,0.25f);    //第二个点

            currentPoint[2] = Vector3.Lerp(startPoint,endPoint,0.5f);    //第三个点

            currentPoint[3] = Vector3.Lerp(startPoint,endPoint,0.75f);    //第四个点

     

            //放到数组中

            currentPoints[0] = startPoint;

            currentPoints[4] = endPoint;

     

             //创建一个点,用来存储选择好可以看到玩家的点

            Vector3 viewPosition =currentPoints[0];

     

            //遍历五点

            for(int i = 0;  i <5;  i++){

                if(CheckView(currentPoints[i])){

                   viewPosition = currentPoints[i];    //更新合适的点

                   break;

                }

            }

     

            //摄像机移动到指定点

            transform.positionVector3.Lerp(transform.position,viewPosition,Time.deltaTime*moveSpeed);

            SmoothRotate();    //执行平滑旋转

        }

     

        //检测是否可以看到玩家

        //return true:看到了,false:没看到

        //param pos:射线发射点

        bool  checkView(Vector3 pos){

             Vector3 dir = player.position -pos; //计算方向向量

        

            //发射射线

            if(Physics.Raycast(pos,dir, out hit)){

                //如果看到了

                if(hit.collider.tag == Tags.Player){

                   return  true;

                }

            }

     

            return  false;

        }

     

        //平滑旋转

        void SmoothRotate(){

            //计算方向向量

            Vector3 dir = player.position + Vector3.up* 0.2f-transform.position;

            Quaternion qua =Quaternion.LookRotation(dir);    //转换为四元数

        

            //平滑移动

            transform.rotation =Quaternion.Lerp(transform.rotation,qua,Time.deltaTime*turnSpeed);

     

            //优化Y轴和Z轴旋转

            transform.eulerAngles = new Vector3(transform.eulerAngles.x,0, 0);

        }

    }


    ###CCTVPlayerDetection.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\CCTVPlayerDetection.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  CCTVPlayerDetection:MonoBehaviour{

        private  LastPlayerSighting  lastPlayerSighting;    //传输警报位置

     

        void  Awake(){

            lastPlayerSighting = GameObject.FindWithTag(Tags.GameController).GetComponent<LastPlayerSighting>();

        }

     

        void OnTriggerEnter(Collider other){

            //如果是玩家,同步警报位置

            if(other.tag == Tags.Player){

                lastPlayerSighting.alarmPositon =other.transform.position;

            }

        }

    }


    ###DoorAnimation.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\DoorAnimation.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  DoorAnimation:MonoBehaviour{

        public  bool  needKey = false;    //当前门是否需要钥匙

        public  AudioClip  refuseAud;    //拒绝开门的声音片段

        private  bool  playerIn=false;    //玩家进入到了大门触发器范围内

        private int  count=0;    //人数

        private Animator  ani;

        private  AudioSource  aud;

        private PlayerInventory  playerInventory;    //玩家是否拥有钥匙的脚本

     

        void Awake(){

            ani = GetComponent<Animator>();

            aud = GetComponent<AudioSource>();

            playerInventory = GameObject.FindWithTag(Tags.Player).GetComponent<PlayerInventory>();

        }

     

        void  OnTriggerEnter(Collider other){

            //如果进来的是玩家或机器人

            if(other.tag ==Tags.Player|| (other.tag ==Tags.Enemy&&other.GetType() ==typeof(CapsuleCollider))){

                count++;    //人数递增

     

                //如果是玩家

                if(other.tag == Tags.Player){

                   playerIn =true;    //设置玩家进入的标志位

                

                    //如果玩家没有钥匙

                   if(!playerInventory.hasKey&&needkey){

                       //播放拒绝声音

                       AudioSource.PlayClipAtPoint(refuseAud,transform.position);

                    }

                }

            }

        }

     

        void  OnTriggerExit(Collider  other){

            //如果进来的是玩家或机器人

            if(other.tag == Tags.Player|| (other.tag ==Tags.Enemy&&other.GetType() == typeof(CapsuleCollider))){

                count--;    //人数递减

            

                //如果是玩家

                if(other.tag ==Tags.Player){

                   playerIn =false;    //设置玩家进入的标志位

                }

            }

        }

     

        void  Update(){

             //不需要钥匙的时候

            if(!needKey){

                 if(count > 0){

                   ani.SetBool(HashIDs.DoorOpen,true);    //门打开

                 }else{

                   ani.SetBool(HashIDs.DoorOpen, false);    //门关闭

                }

            }else{

                //玩家带着钥匙进去

                if(playerIn&&playerInventory.hasKey){

                   ani.SetBool(HashIDs.DoorOpen, true);

                }else{

                   ani.SetBool(HashIDs.DoorOpen, false);

                }

            }

        }

     

        //动画帧事件,播放开关门声音

        public void PlayVoice(){

            if(Time.time > 0.1f){

                aud.Play();    //播放声音

            }

        }

    }


    ###EnemyAI.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\EnemyAI.cs

    using UnityEngine;

    using System.Collections;

     

    public class EnemyAI:MonoBehaviour{

        public Transform[]  wayPoints;    //巡逻点

        public float  chasingSpeed=6f;    //追捕速度

        public float  patrallingSpeed= 2.5f;   //巡逻速度

        public float chasingWaitTime=3f;    //巡视时间

        private float  chasingTimer;    //追捕等待计时器

        private float patrallingTimer;    //巡逻等待计时器

        private EnemySight  enemySight;

        private LastPlayerSighting  lastPlayerSighting;   

        private UnityEngine.AI.NavmeshAgent  nav;

        private int index;   //巡逻目标索引号

        private PlayerHealth  playerHealth;

     

        void  Awake(){

            enemySight = GetComponent<EnemySight>();

            lastPlayerSighting = GameObject.FindWithTag(Tags.GameController).GetComponent<LastPlayerSighting>();

            nav = GetComponent<UnityEngine.AI.NavMeshAgent>();

            playerHealth = GameObject.FindWithTag(Tags.Player).GetComponent<PlayerHealth>();

            index = 0;

        }

     

        void  Update(){

            if(enemySight.playerInSight&&playerHealth.health>0){

                Shooting();    //射击

            }else if(enemySight.personalAlarmPosition!=lastPlayerSighting.normalPosition&&playerHealth.health>0){

                Chasing();    //追捕

            }else{

                Patrolling();    //巡逻

            }

        }

     

        //射击

        void Shooting(){

            nav.Stop();   //导航停止

        }

     

        //追捕

        void Chasing(){

            nav.Resume();    //恢复导航

            nav.speed = chasingSpeed;    //加快速度

            nav.SetDestination(enemySight.personalAlarmpositon);    //设置导航目标

     

            //到达了警报位置

            if(nav.remainingDistance -nav.stoppingDistance<0.5f){

                chasingTimer += Time.deltaTime;    //追捕等待计时器计时

            

                //达到等待时间

                if(chasingTimer > chasingWaitTime){

                   chasingTimer =0;    //重置计时器

     

                    //警报解除

                    lastPlayerSighting.alarmPosition =lastPlayerSighting.normalPosition;

                 }

             }else{

                chasingTimer = 0;    //重置计时器

            }

        }

     

        //巡逻

        void Patrolling(){

            nav.speed = patrallingSpeed;   //巡逻速度

            nav.SetDestination(wayPoints[index].position);    //设置巡逻目标

     

            //达到巡逻点

            if(nav.remainingDistance- nav.stoppingDistance< 0.5f){

                patrallingTimer += Time.deltaTime;    //计时器计时

     

                //计时器完成本次计时

                if(patrallingTimer >chasingWaitTime){

                    //更新下一个巡逻点索引号

                    //index = ++index % wayPoints.Length;

                   index++;

                   index =index%wayPoints.Length;

                   patrallingTimer = 0;    //计时器清零

                 }

              }else{

                 patrallingTimer = 0;    //计时器清零

             }

        }

    }


    ###EnemyAnimation.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\EnemyAnimation.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  EnemyAnimation:MonoBehaviour{

        public float  deadZone=4;    //死角度数

        public float  dampSpeedTime= 0.1f;    //设置动画参数的延迟时间

        public float  dampAngularSpeedTime=0.1f;  

     

        private UnityEngine.AI.NavMeshAgent  nav;

        private EnemySight enemySight;

        private  Transform  player;

        private  Animator  ani;

     

        void  Awake(){

            nav = GetComponent<UnityEngine.AI.NavMeshAgent>();

            enemySight = GetComponent<EnemySight>();

            player = GameObject.FindWithTag(Tags.Player).transform;

            ani = GetComponent<Animator>();

            deadZone *= Mathf.Deg2Rad;    //死角度数转为弧度

        }

     

        void  OnAnimatorMove(){

            nav.velocity = ani.deltaPosition/Time.deltaTime;

            transform.rotation =ani.rootRotation;

        }

     

        void  Update(){

            float speed = 0;

            float angularSpeed =0;

     

            //如果看到了玩家

            if(enemySight.playerInSight){

                speed = 0;    //停下来

                angularSpeed = FindAngle();    //角速度,按导航转向

     

                //如果角度过小,进入死角

                if(Mathf.Abs(angularSpeed) < deadZone){

                   angularSpeed =0;    //停止用动画转身

                   transform.LookAt(player);    //机器人直接看向玩家

                }

            }else{

                //直线速度 =机器人前方的投影向量的模

                speed = Vector3.Project(nav.desiredVelocity,transform.forward).magnitude;

                angularSpeed = FindAngle();    //角速度,按导航转向

            }

     

            //设置动画参数

            ani.SetFloat(HashIDs.Speed,speed,dampSpeedTime,Time.deltaTime);

            ani.SetFloat(HashIDs.AngularSpeed,angularSpeed,dampAngularSpeedTime,Time.deltaTime);

        }

     

         float FindAngle(){

             Vector3 dir = nav.desiredVelocity;    //期望速度

     

             //机器人前方与期望速度形成的夹角

            float angle = Vector3.Angle(dir,transform.forward);    

     

            //计算两向量的法向量

            Vector3 normal = Vector3.Cross(transform.forward,dir);

     

            //如果期望速度在机器人左方,角度为负

            if(normal.y <0){

                angle *= -1;

            }

     

             //将角度转换为弧度

            angle *= Mathf.Deg2Rad;

     

            //如果期望速度为0

            if(dir ==Vector3.zero){

                angle = 0;

            }

     

            return  angle;

        }

    }


    ###EnemyShooting.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\EnemyShooting.cs

    using UnityEngine;

    using System.Collections;

     

    public class  EnemyShooting:MonoBehaviour{

        public float  damage= 10;    //一枪伤害

     

        private Animator  ani;

        private  Light  shootLight;

        private LineRenderer shootLine;

        private  bool  shooting = false;

        private  Transform player;

        private PlayerHealth  playerHealth;

     

        void Awake(){

            ani = GetComponent<Animator>();

            shootLight = GetComponentInChildren<Light>();

            shootLine = GetComponentInChildren<LineRenderer>();

            player = GameObject.FindWithTag(Tags.Player).transform;

            playerHealth = player.GetComponent<PlayerHealth>();

        }

     

        void  Update(){

            //射击开始

            if(ani.GetFloat(HashIDs.shot) > 0.5f && !shooting){

                Shooting();

            }elseif(ani.GetFloat(HashIDs.Shot) < 0.5f){

                shooting = false;

                shootLight.enabled =false;

                shootLine.enabled =false;

            }

        }

     

        //射击

        void Shooting(){

            shootLight.enabled = true;    //打开闪光

        

            //绘制激光线

            shootLine.SetPosition(0, shootLine.transform.parent.position);

            shootLine.SetPosition(1, player.position+Vector3.up*1.5f);

            shootLine.enabled =true;

            shooting = true;    //正在射击

            playerHealth.TakeDamage(damage);    //计算伤害

        }

     

        void OnAnimatorIK(int  layer){

            float weight = ani.GetFloat(HashIDs.AimWeight);    //获取曲线中的权重

            ani.SetIKPositionWeight(AvatarIKGoal.RightHand,weight);    //设置IK权重

        

            //设置IK位置

            ani.SetIKPosition(AvatarIKGoal.RightHand,player.position+Vector3.up*1.5f);

        }

    }


    ###EnemySight.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\EnemySight.cs

    using UnityEngine;

    using System.Collections;

     

    public  class EnemySight:MonoBehaviour{

        public  bool  playerInSight= false;    //能够看到玩家

        public float  fieldOfView= 110f;    //机器人视野夹角

        private float  distanceOfView;    //机器人视野距离

        private  SphereCollider  sph;    //机器人触发器

        public Vector3  personalAlarmPosition;    //私人警报位置

        private  Vector3  previousAlarmPosition;    //上一帧的公共警报位置

        private LastPlayerSighting lastPlayerSighting;    //公共警报脚本

        private  RaycastHit  hit;    //射线碰撞检测器

        private  UnityEngine.AI.NavMeshAgent  nav;    //导航组件

        private PlayerHealth  playerHealth;    //玩家血量脚本

        private  Animator  ani;    //动画组件

     

        void Awake(){

            lastPlayerSighting = GameObject.FindWithTag(Tags.GameController).GetComponent<LastPlayerSighting>();

     

            //获取触发器

            sph = GetComponent<SphereCollider>();

            nav = GetComponent<UnityEngine.AI.NavMeshAgent>();

            playerHealth = GameObject.FindWithTag(Tags.Player).GetComponent<PlayerHealth>();

            ani = GetComponent<Animator>();

        }

     

        void  Start(){

            //私人警报初值为非警报位置

            personalAlarmPosition = lastPlayerSighting.normalPosition;

     

            //上一帧的公共警报位置初值也为非警报位置

            previousAlarmPosition = lastPlayerSighting.normalPosition;

        

            //获取视野距离

            distanceOfView = sph.radius;

        }

     

        void  Update(){

            //公共警报一旦发生变化  --->通知到PersonalAlarmPosition

            //PersonalAlarmPosition  --/-->不能通知给公共警报

     

            //如果上一帧的公共警报位置,与本帧的公共警报位置不一致

            if(previousAlarmPosition != lastPlayerSighting.alarmPosition){

                //将最新的公共警报位置通知到私人警报位置

                personalAlarmPosition = lastPlayerSighting.alarmPosition;

            }

     

            //获取本帧的公共警报位置

            previousAlarmPosition =lastPlayerSighting.alarmPosition;   

     

            //如果玩家血量正常

            if(playerHealth.health > 0){

                ani.SetBool(HashIDs.PlayerInSight,playerInSight);

            }else{

               ani.SetBool(HashIDs.PlayerInSight, false);

            }

        }

     

        void  OnTriggerStay(Collider other){

            //如果是玩家

            if(other.tag ==Tags.Player){

                playerInSight = false;    //重置

     

                //玩家与机器人的距离

                float distanceVector3.Distance(other.transform.position, transform.position);

     

                //计算机器人自身前方与方向向量之间的夹角

                float angular =  Vector3.Angle(dir, transform.forward);

     

                //满足视野范围内核距离范围内

                if(distance <distanceOfView &&angular<fieldOfView/2){

                   if(Physics.Raycast(transform.position+Vector3.up*1.7f, dir,outhit)){

                       if(hit.collider.tag == Tags.Player){

                           playerInSight = true;    //可以看到玩家

     

                            //报警

                           lastPlayerSighting.alarmPosition = other.transform.position;  

                        }

                    }

                }

     

                //听觉:如果机器人与玩家的导航路径在听觉路径范围内

                if(EnemyListening(other.transform.position)){

                    //如果玩家发出了声音

                   if(other.GetComponent<AudioSource>().isPlaying){

                        //赋值私人警报位置

                       personalAlarmPosition =other.transform.position;

                    }

                }

            }

        }

     

        //机器人与玩家的导航距离在视觉范围内

        bool  EnemyListening(Vector3 playerPos){

            UnityEngine.AI.NavMeshPath path = new UnityEngine.AI.NavMeshPath();

     

            //如果导航可以到达玩家位置

            if(nav.CalculatePath(playerPos, path)){

                //用数组获取所有的路径点

                Vector3[]  points =new Vector3[path.corners.Length+2];    

                points[0] = transform.position;    //起点

                points[points.Length-1] = playerPos;    //终点

            

                //赋值中间的拐点

                for(inti =1;  i < points.Length-1;  i++){

                   points[i] = path.corners[i -1];

                }

     

                float  navDistance= 0;    //导航距离

                 //遍历计算距离

                for(int i =0; i < points.Length-1;  i++){

                   navDistance +=Vector3.Distance(points[i],points[i +1]);

                 }

     

                //导航距离在听觉距离范围内

                if(navDistance < distanceOfView){

                    return  true;

                 }

            }

     

             return  false;

         }

    }


    ###HashIDs.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\HashIDs.cs

    using UnityEngine;

    using System.Collections;

     

    public class  HashIDs :MonoBehaviour{

        public  static int  DoorOpen;

        public  static int  Speed;

        public static int  Sneak;

        public static int  AngularSpeed;

        public  static  int Dead;

        public  static int  PlayerInSight;

        public static int  Shot;

        public static int  AimWeight;

        public  static  int  LocomotionState;

     

        void  Awake(){

            DoorOpen = Animator.StringToHash(DoorOpen);

            Speed = Animator.StringToHash(Speed);

            Sneak = Animator.StringToHash(Sneak);

            AngularSpeed = Animator.StringToHash(AngularSpeed);

            Dead = Animator.StringToHash(Dead);

            PlayerInSight = Animator.StringToHash(PlayerInSight);

            Shot = Animator.StringToHash(Shot);

            AimWeight = Animator.StringToHash(AimWeight);

            LocomotionState = Animator.StringToHash(Locomotion);

        }

    }


    ###KeyPickup.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\KeyPickup.cs

    using UnityEngine;

    using System.Collections;

     

    public class  KeyPickup:MonoBehaviour{

        public AudioClip  pickAud;    //拾取到钥匙的声音

        private PlayerInventory  playerInventory;

     

        void Awake(){

            playerInventory = GameObject.FindWithTag(Tags.Player).GetComponent<PlayerInventory>();

        }

     

        void  OnTriggerEnter(Collider  other){

            if(other.tag == Tags.Player){

                playerInventory.hasKey = true;    //更换标志位,玩家获取到了钥匙

                AudioSource.PlayClipAtPoint(pickAudtransform.position);    //播放声音

                Destroy(gameObject);    //销毁自己

            }

        }

    }


    ###LaserController.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\LaserController.cs

    using UnityEngine;

    using System.Collections;

     

    public  class LaserController:MonoBehaviour{

        public  bool  isBlinking=false;    //激光是否是闪动的

        public float  blinkDeltaTime=3f;    //闪动间隔时间

        private float timer=0;    //计时器

        private LastPlayerSighting  lastPlayerSighting;    //玩家警报脚本

     

        void  Awake(){

            //找到玩家警报脚本

            lastPlayerSighting = GameObject.FindWithTag(Tags.GameController).GetComponent<LastPlayerSighting>();

        }

     

        void  Update(){

            timer += Time.deltaTime;    //计时器计时

        

            //到达计时器时间

            if(timer>= blinkDeltaTime && isBlinking){

                timer = 0;    //计时器归零

        

                //控制激光组件的显影

                GetComponent<MeshRenderer>().enabled = !GetComponent<MeshRenderer>().enabled;

                GetComponent<Light>().enabled = !GetComponent<Light>().enabled;

                GetComponent<AudioSource>().enabled = !GetComponent<AudioSource>().enabled;

                GetComponent<BoxCollider>().enabled = !GetComponent<BoxCollider>().enabled;

            }

        }

     

        //玩家触碰到激光

        void  OnTriggerEnter(Collider  other){

            //如果是玩家

            if(other.tag ==Tags.Player){

                //将玩家位置同步到警报位置

                lastPlayerSighting.alarmPosition = other.transform.position;

            }

        }

    }


    ###LaserSwitchDeactivation.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\LaserSwitchDeactivation.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  LaserSwitchDeactivation:MonoBehaviour{

        public  GameObject controlledLaser;    //所控制的激光

        public  Material  unlockMat;    //解锁的屏幕材质

     

        //当玩家进入到电脑控制范围

        void  OnTriggerStay(Collider other){

            //当玩家按下Z

            if(Input.GetKeyDown(KeyCode.Z) && other.tag ==Tags.Player && controlledLaser.activeSelf){

                controlledLaser.SetActive(false);    //关闭激光

                GetComponent<MeshRenderer>().material = unlockMat;    //切换屏幕材质

                GetComponent<AudioSource>().Play();

            }

        }

    }


    ###LastPlayerSighting.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\LastPlayerSighting.cs

    using UnityEngine;

    using System.Collections;

     

    public  class LastPlayerSighting : MonoBehaviour{

        public  Vector3  alarmPosition = new  Vector3(1000,1000,1000);    //警报位置

        public  Vector3  normalPosition = new  Vector3(1000,1000,1000);    //非警报位置

        public float  turnSpeed=3f;    //声音切换速度

        private AlarmLight  alarmLight;    //警报灯脚本

        private  AudioSource  mainAudio;    //主背景音乐

        private  AudioSource  panicAudio;    //警报背景音乐

        private AudioSource[]  alarmAudios;    //警报喇叭声音

     

        void Awake(){

            //找到警报灯脚本

            alarmLight = GameObject.FindWithTag(Tags.AlarmLight).GetComponent<AlarmLight>();

            mainAudio = GetComponent<AudioSource>();    //找到主背景音乐

     

            //找到警报背景音乐

            panicAudio = transform.GetChild(0).GetComponent<AudioSource>();

     

            //先找到所有喇叭对象

            GameObject[]  sirens =GameObject.FindGameObjectsWithTag(Tags.Siren);

            alarmAudios = new AudioSource[sirens.Length];  //初始化AudioSource数组

     

             //获取所有喇叭对象中的AudioSource组件

            for(inti =0;  i< sirens.Length;  i++){

              alarmAudios[i] =sirens[i].GetComponent<AudioSource>();

            }

        }

     

        void  Update(){

            //解除警报

            if(alarmPosition == normalPosition){

                 alarmLight.alarmOn =false;   //关闭警报灯

     

                 //渐渐关闭警报背景音乐

                panicAudio.volume =Mathf.Lerp(panicAudio.volume,0,Time.deltaTime*turnSpeed);

     

                //逐个渐渐关闭警报喇叭声音

                for(inti=0;  i <alarmAudios.Length;  i++){

                   alarmAudios[i].volume = Mathf.Lerp(alarmAudios[i].volume,0,Time.deltaTime*turnSpeed);

                }

     

                //渐渐开启主背景音乐

                mainAudio.volume = Mathf.Lerp(mainAudio.volume,1,Time.deltaTime*turnSpeed);

     

            }else{    //开启警报

                alarmLight.alarmOn =true;    //开启警报灯

     

                 //渐渐关闭主背景音乐

                mainAudio.volume = Mathf.Lerp(mainAudio.volume,0,Time.deltaTime*turnSpeed);

     

                //渐渐开启警报背景音乐

                panicAudio.volume = Mathf.Lerp(panicAudio.volume,1,Time.deltaTime*turnSpeed);

     

               //渐渐开启警报喇叭声音

                for(int i = 0;  i < alarmAudios.Length;  i++){

                     alarmAudios[i].voluem = Mathf.Lerp(alarmAudios[i].volume,1,Time.deltaTime*turnSpeed);

                }

           }

        }

    }


    ###LiftDoorsTracking.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\LiftDoorsTracking.cs

    using UnityEngine;

    using System.Collections;

    using UnityEngine.SceneManagement;

     

    public  class LiftDoorTracking:MonoBehaviour{

        private float  timer;

        public float  waitTime=1f;

        public float  moveTime=2f;

        public float moveSpeed=3f;

     

        private Transform  player;

        private AudioSource liftRaise;

        private AudioSource  endGame;

     

        void Awake(){

            player = GameObject.FindWithTag(Tags.Player).transform;

            liftRaise = GetComponent<AudioSource>();

           endGame = transform.parent.GetComponent<AudioSource>();

        }

     

        void  OnTriggerStay(Collider  other){

            if(other.tag == Tags.Player){

                timer += Time.deltaTime;

            

                //到达上升时间

                if(timer > waitTime){

                    //播放电梯声音

                   if(!liftRaise.isPlaying){

                       liftRaise.Play();

                    }

     

                   //播放结束游戏声音

                    if(!endGame.isPlaying){

                       endGame.Play();

                    }

     

                    //电梯上升

                    transform.root.position += Vector3.up*Time.deltaTime*moveSpeed;

     

                    //人物上升

                    player.position +=Vector3.up*Time.deltaTime*moveSpeed;

     

                    if(timer > waitTime+moveTime){

                          //TODO:重启游戏

                       SceneManager.LoadScene(Yanlz_Demo006_Stealth);

                    }

                }

            }

        }

    }


    ###PlayerHealth.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\PlayerHealth.cs

    using UnityEngine;

    using System.Collections;

    using UnityEngine.SceneManagement;

     

    public  class  PlayerHealth:MonoBehaviour{

        public float health =100;    //玩家血量

        public AudioClip  endGameAud;    //游戏结束声音

        private  Animator  ani;

        private  bool  isdead = false;    //玩家是否死亡

        private  bool  endGame = false;    //游戏结束

     

        void Awake(){

            ani = GetComponent<Animator>();

        }

     

        public void TakeDamage(float  damage){

            health -= damage;

        }

     

        void  Update(){

            //如果血量小于等于0,死亡

            if(health <=0&& !isdead){

                ani.SetTrigger(HashIDs.Dead);

                isdead = true;

            }else if(isdead&& !endGame){

                StartCoroutine(EndGame());    //开启结束游戏协程

                endGame = true;

            }

        }

     

        IEnumerator EndGame(){

            AudioSource.PlayClipAtPoint(endGameAud,transform.position);    //播放结束音效

            yield return new WaitForSeconds(4.4f);    //等待4.4

           SceneManager.LoadScene(Yanlz_Demo003_Stealth);

        }

    }


    ###PlayerInventory.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\PlayerInventory.cs

    using UnityEngine;

    using System.Collections;

     

    public  class PlayerInventory:MonoBehaviour{

        public boolhasKey=false;    //玩家是否拥有钥匙

    }


    ###PlayerMovement.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\PlayerMovement.cs

    using UnityEngine;

    using System.Collections;

     

    //立钻哥哥:玩家控制脚本

    public class PlayerMovement:MonoBehaviour{

        public float turnSpeed=10;    //转身速度

        private float hor,ver;    //操纵键变量

        private  bool  sneak=false;

        private  Animator  ani;    //动画组件

        private  AudioSource  aud;    //声音组件

        private PlayerHealth  playerHealth;

     

        void  Awake(){

            ani = GetComponent<Animator>();

            aud = GetComponent<AudioSource>();

            playerHealth = GetComponent<PlayerHealth>();

        }

     

        void  Update(){

            if(playerHealth.health>0){

                //获取用户的按键情况

                hor = Input.GetAxis(Horizontal);

                ver = Input.GetAxis(Vertical);

            }else{

                hor = 0;

                ver = 0;

            }

     

            if(Input.GetKey(KeyCode.LeftShift)){

                sneak = true;

            }else{

                sneak = false;

            }

     

            //设置潜行参数

            ani.SetBool(HashIDs.Sneak, sneak);

     

            //如果用户按下了方向键

            if(hor!=0 || ver!= 0){

                //动画参数Speed渐变到5.5(奔跑动画)

                ani.SetFloat(HashIDs.Speed,5.5f,0.1f, Time.deltaTime);

                TurnDir(hor, ver);    //玩家转向

            }else{

                ani.SetFloat(HashIDs.Speed,0);    //立刻停下来

            }

     

            FootSteps();    //执行脚本声控制

        }

     

        //玩家转向

        void TurnDir(float hor,  float ver){

            Vector3 dir = new Vector3(hor,0,ver);    //拿到方向向量

     

            //将方向向量转换成四元数(参考Y轴)

            Quaternion qua  = Quaternion.LookRotation(dir);

     

            //玩家转向到该方向

            transform.rotation =Quaternion.Lerp(transform.rotation,qua,Time.deltaTime*turnSpeed);

        }

     

        void FootSteps(){

            //如果当前玩家正在播放Locomotion正常行走的动画

            if(ani.GetCurrentAnimatorStateInfo(0).shortNameHash == HashIDs.LocomotionState){

                //如果脚步声没有播放

                if(!aud.isPlaying){

                   aud.Play();    //播放

                 }

            }else{

                aud.Stop();    //停止播放脚步声

            }

        }

    }


    ###SyncDoor.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\SyncDoor.cs

    using UnityEngine;

    using System.Collections;

     

    public class  SyncDoor:MonoBehaviour{

        public Transform  outterleft;

        public Transform  outterright;

        private  Transform  innerleft;

        private  Transform innerright;

     

        void  Awake(){

            innerleft = transform.GetChild(0);

            innerright = transform.GetChild(1);

        }

     

        void  Update(){

            //左右里门同步左右外门

            innerleft.localPosition = new Vector3(innerleft.localPosition.x,innerleft.localPosition.y,outterleft.localPosition.z);

            innerright.localPosition = new Vector3(innerright.localPosition.x,innerright.localPosition.y,outterright.localPosition.z);

        }

    }


    ###Tags.cs

    D:\zz_DemoPro()-\小案例006、秘密行动Demo\Demo006_StealthActionDemo\Assets\Scripts\Tags.cs

    using UnityEngine;

    using System.Collections;

     

    //立钻哥哥:标签管理

    public class  Tags{

        public const  stringAlarmLight=AlarmLight;

        public  const  stringSiren= Siren;

        public const stringPlayer=Player;

        public  const  string  GameController=GameController;

        public  const  string  Enemy=Enemy;

    }




    #小案例007A_Star

    ++小案例007A_Star

    ++++FindPath.cs

    ++++GridMap.cs

    ++++Node.cs




    ###FindPath.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  FindPath : MonoBehaviour{

        private GridMap _grid;   //整张地图

        public Transform startPoint, endPoint;

     

        private void  Start(){

            _grid = GameObject.FindObjectOfType<GridMap>();

        }

     

        private void  Update(){

            FindingPath(startPoint.position,  endPoint.position);

        }

     

        //立钻哥哥:核心算法:生成路径

        private void FindingPath(Vector3  startPos,Vector3 EndPos){

            //获取起点和终点的格子

            Node startNode = _grid.GetNodeFromPosition(StartPos);

            Node endNode = _grid.GetNodeFromPosition(EndPos);

     

            //创建开启列表和关闭列表

            List<Node> openSet =new List<Node>();

            HashSet<Node>closeSet =new HashSet<Node>();

     

            openSet.Add(startNode);

            while(openSet.Count>0){

                 Node currentNode =openSet[0];    //从开启列表中随便取出一个节点

            

                 //取最小的节点

                 for(int i=0;  i < openSet.Count;  i++){

                    if(openSet[i].fCost < currentNode.fCost){

                       currentNode = openSet[i];

                    }

                  }

     

                 //从开启列表移除,加入关闭列表

                openSet.Remove(currentNode);

                closeSet.Add(currentNode);

     

                //找到终点

                if(currentNode == endNode){

                   GeneratePath(startNode, endNode);    //生成一条路径

                    return;

                }

     

                foreach(var node in _grid.GetNeibourhood(currentode)){

                   if(!node._canWalk||closeSet.Contains(node)){

                   continue;

                }

     

                //计算与相邻格子的距离

                 int  newCost = currentNode.gCost + GetDistance(currentNode,node);

                 if(newCost <node.gCost || !openSet.Contains(node)){

                      node.gCost =newCost;

                       node.hCost = GetDistance(node,endNode);

                       node.parent = currentNode;

     

                       if(!openSet.Contains(node)){

                          openSet.Add(node);

                        }

                    }

                }

            }

        }

     

        //计算两点间的距离

        int GetDistance(Node a, Nodeb){

            int cntX= Mathf.Abs(a._gridX-b._gridX);

            int cntY =Mathf.Abs(a._gridY-b._gridY);

     

            if(cntX>cntY){

                return 14*cntY+10* (cntX-cntY);

            }else{

                return 14*cntX+10* (cntY-cntX);

            }

        }

     

        //生成最终路径

        private void GeneratePath(Node startNode,Node  endNode){

            List<Nodepath =new List<Node>();

            Node temp = endNode;

     

            while(temp !=startNode){

                path.Add(temp);

                temp = temp.parent;

            }

     

            path.Reverse();

            _grid.path=path;

        }

    }


    ###GridMap.cs

    D:\yanlz_DemoPro()-\小案例007AStar\Assets\GridMap.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  GridMap:MonoBehaviour{

        private Node[,]  grid;    //存放所有格子的容器

     

        [Tooltip(地图的尺寸)]

        public Vector2 gridSize;

     

        [Tooltip(每个格子的半径)]

        public float  nodeRadius;

     

        //直径

        private float nodeDiamenter{

            get{    return  nodeRadius*2;  }

        }

     

        [Tooltip(障碍物所在的层)]

        public  LayerMask ObstacleLayer;

     

        private int  gridCntX,gridCntY;    //地图上横纵格子数量

        public List<Node>path = new List<Node>();    //最终路径

     

        private void Start(){

            gridCntX = Mathf.RoundToInt(gridSize.x /nodeDiameter);

            gridCntY = Mathf.RoundToInt(gridSize.y /nodeDiameter);

            grid = newNode[gridCntX,gridCntY];

     

            CreateGrid();

        }

     

        //立钻哥哥:创建节点

        private void CreateGrid(){

            Vector3 startPoint = transform.position-gridSize.x /2 *Vector3.right-Vector3.forward*gridSize.y /2;

     

            for(int i=0;  i < gridCntX;  i++){

                for(intj =0;  j < gridCntY;  j++){

                    //每个格子的世界坐标

                   Vector3  worldPoint = startPoint+ Vector3.right* (i *nodeDiameter+nodeRadius) +Vector3.forward* (j *nodeDiameter+nodeRadius);

                

                    //格子上是否有障碍物

                   bool  canWalk = !Physics.CheckSphere(wordPoint,nodeRadius,ObstacleLayer);

                   grid[i,j] = new Node(canWalk,worldPoint,i,j);

                }

            }

        }

     

        //立钻哥哥:Unity回调

       private void  OnDrawGizmos(){

            if(Application.isPlaying==false){

                return;

            }

     

            if(gird ==null){

                return;

            }

     

            foreach(var node in grid){

                Gizmos.color = node._canWalk?Color.gray:Color.red;    //指定颜色

        

                //绘制图形

                Gizmos.DrawCube(node._wordPos, (nodeDiameter -nodeDiameter*0.1f) *Vector3.one);

            }

     

            if(path !=null){

                foreach(var node  in path){

                   Gizmos.color = Color.green;

                   Gizmos.DrawCube(node._wordPos, (nodeDiameter -nodeDiameter*0.1f) *Vector3.one);

                }

            }

        }

     

        //根据世界位置,得到Node

        public Node GetNodeFromPosition(Vector3 position){

            float percentX = (position.x +gridSize.x /2) / gridSize.x;

            float percentY = (position.z +gridSize.y /2) / gridSize.y;

     

            percentX = Mathf.Clamp01(percentX);

            percentY = Mathf.Clamp01(percentY);

     

            int x = Mathf.RoundToInt((gridCntX-1) *percentX);

            int y = Mathf.RoundToInt((gridCntY-1) *percentY);

     

            return grid[x,y];

        }

     

        //获取一个格子周围的8个格子

        public List<NodeGetNeibourhood(Node  node){

            List<Node>  neibourhood=  new List<Node>();

        

            for(inti = -1;  i <=1;  i++){

                for(int j = -1;  j <= 1;  j++){

                   if(i ==0&& j==0){

                       continue;

                    }

     

                    int tempX= node._gridX+i;

                    int  tempY= node._gridY+j;

                    if(tempX < gridCntX && tempX > 0 && tempY> 0 &&tempY<gridCntY){

                       neibourhood.Add(grid[tempX,tempY]);

                    }

                }

            }

     

            return  neibourhood;

        }

    }


    ###Node.cs

    D:\yanlz_DemoPro()-\小案例007AStar\Assets\Node.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    //立钻哥哥:格子数据结构

    //Node: 一个小格子

    //GridMap: 整张地图

    //FindPath: 根据A*算法,生成的路径

    public class Node{

        public int  gCost;

        public int  hCost;

     

        public int fCost{

            get{    return  gCost+hCost;    }

        }

     

        public Node  parent;    //指向父格子的指针

        public int  _gridX,_gridY;    //格子序号

        public  bool _canWalk;    //格子上方是否有障碍物

        public  Vector3 _worldPos;    //格子所在的世界坐标

     

        public Node(bool  Canwalk,  Vector3  position,  int  x,  int  y){

            _canWalk = Canwalk;

            _worldPos = position;

            _gridX = x;

            _gridY = y;

        }

    }





    #小案例008、血条LiftBar跟随

    ++小案例008、血条LiftBar跟随

    ++++FaceToCamera.cs

    ++++HeadHP.cs

    ++++HPTest.cs

    ++++PlayerMove.cs




    ###FaceToCamera.cs

    D:\yanlz_DemoPro()-\小案例008、血条LiftBar跟随\Assets\FaceToCamera.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public  class  FaceToCamera :MonoBehaviour{

        private  Camera  camera;

     

        void  Start(){

            camera = Camera.main;

        }

     

        //立钻哥哥:Update is called once per frame

        void  Update(){

            Vector3 pos= camera.transform.position-transform.position;

            pos.x = pos.z = 0;

            transform.LookAt(camera.transform.position-pos);

            transform.Rotate(0,180,0);

        }

    }


    ###HeadHP.cs

    D:\yanlz_DemoPro()-\小案例008、血条LiftBar跟随\Assets\HeadHP.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public class HeadHP:MonoBehaviour{

        private  Image image;

        private int  hp=150;

        private int maxhp;

     

        void  Start(){

            image = GetComponent<Image>();

            maxhp = hp;

        }

     

        void Update(){

            if(Input.GetKeyDown(KeyCode.Space)){

                hp -= 10;

                image.fillAmout = (float)hp/maxhp;

            }

        }

    }


    ###HPTest.cs

    D:\yanlz_DemoPro()-\小案例008、血条LiftBar跟随\Assets\HPTest.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public  class  HPTest:MonoBehaviour{

        private  RectTransform  rectTrans;

        public  Transform target;

        public Vector2 offsetPos;

     

        void  Start(){

            rectTrans = GetComponent<RectTransform>();

        }

     

        void  Update(){

            Vector3   postar =target.transform.position;

            Vector2   pos=RectTransformUtility.WorldToScreenPoint(Camera.main,postar);

     

            rectTrans.position =pos+offsetPos;

        }

    }


    ###PlayerMove.cs

    D:\yanlz_DemoPro()-\小案例008、血条LiftBar跟随\Assets\PlayerMove.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.AI;

     

    public class PlayerMove:MonoBehaviour{

        private  NavMeshAgent  nav;

     

        void  Start(){

            nav = GetComponent<NavMeshAgent>();

        }

     

        void  Update(){

            if(Input.GetMouseButtonDown(0)){

                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

                Raycasthit  hit;

            

                if(Physics.Raycast(ray,  out hit)){

                   nav.SetDestination(hit.point);

                }

            }

        }

    }





    #小案例009、见缝插针StickPin

    #小案例009、见缝插针StickPin

    ++++GameManager.cs

    ++++Pin.cs

    ++++PinHead.cs

    ++++RotateSelf.cs



    ###GameManager.cs

    D:\yanlz_DemoPro()-\小案例009、见缝插针StickPin\Assets\Scripts\GameManager.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

    using UnityEngine.SceneManagement;

     

    public class GameManager:MonoBehaviour{

        private  Transform  startPoint;

        private  Transform  spawnPoint;

        private Pin currentPin;

        private  bool  isGameOver=false;

        private int  score =0;

        private Camera  mainCamera;

     

        public  Text  scoreText;

        public  GameObject  pinPrefab;

        public float  speed =3;

     

        void  Start(){

            startPoint  = GameObject.Find(StartPoint).transform;

            spawnpoint  = GameObject.Find(SpawnPoint).transform;

            mainCamera = Camera.main;

     

            SpawnPin();

        }

     

        private void  Update(){

            if(isGameOver){

                return;

            }

     

            if(Input.GetMouseButtonDown(0)){

                score++;

                scoreText.text = score.ToString();

                currentPin.StartFly();

     

                SpawnPin();

            }

        }

     

        void SpawnPin(){

            currentPin = GameObject.Instantiate(pinPrefab,spawnPoint.position,pinPrefab.transform.rotation).GetComponent<Pin>();

        }

     

        public void GameOver(){

            if(isGameOver){

                return;

            }

     

            GameObject.Find(Circle).GetComponent<RotateSelf>().enabled = false;

     

            StartCoroutine(GameOverAnimation());

     

            isGameOver = true;

        }

     

        IEnumerator GameOverAnimation(){

            while(true){

                mainCamera.backgroundColor = Color.Lerp(mainCamera.backgroundColor,Color.red,  speed* Time.deltaTime);

                mainCamera.orthographicSize=Mathf.Lerp(mainCamera.orthographicSize,  4,  speed*Time.deltaTime);

            

                if(Mathf.Abs(mainCamera.orthographicSize-4) <0.01f){

                   break;

                }

     

                yield return  0;

            }

     

            yield return new WaitForSeconds(0.2f);

     

            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

        }

    }



    ###Pin.cs

    D:\yanlz_DemoPro()-\小案例009、见缝插针StickPin\Assets\Scripts\Pin.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public class Pin:MonoBehaviour{

        public float  speed= 5;

        private bool  isFly =false;

        private bool  isReach =false;

     

        private Transform  startPoint;

        private  Vector3 targetCirclePos;

        private  Transform  circle;

     

        void  Start(){

            startPoint = GameObject.Find(StartPoint).transform;

     

            //circle = GameObject.Find(Circle).transform;

            circle = GameObject.FindGameObjectWithTag(Circle).transform;

            targetCirclePos = circle.position;

            targetCirclePos.y -= 1.55f;

        }

     

        void  Update(){

            if(isFly ==false){

                if(isReach==false){

                   transform.position = Vector3.MoveTowards(transform.position,  startPoint.position,  speed*Time.deltaTime);

                    if(Vector3.Distance(transform.position,  startPoint.position) <0.05f){

                       transform.positiontargetCirclePos;

                       transform.parent =circle;

                       isFly =false;

                    }

                }

            }

        }

     

        public void StartFly(){

                isFly = true;

                isReach = true;

        }

    }


    ###PinHead.cs

    D:\yanlz_DemoPro()-\小案例009、见缝插针StickPin\Assets\Scripts\PinHead.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public class  PinHead:MonoBehaviour{

        private void  OnTriggerEnter2D(Collider2D  collision){

            if(collision.tag ==PinHead){

                GameObject.Find(GameManger).GetComponent<GameManager>().GameOver();

            }

        }

    }


    ###RotateSelf.cs

    D:\yanlz_DemoPro()-\小案例009、见缝插针StickPin\Assets\Scripts\RotateSelf.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    public  class  RotateSelf:MonoBehaviour{

        public float  speed=90;

     

        void  Update(){

            transform.Rotate(new Vector3(0,0, -speed* Time.deltaTime));

        }

    }




    #小案例010UnityNetDemo

    #小案例010UnityNetDemo

    ++++Player.cs



    ###Player.cs

    D:\yanlz_DemoPro()-\小案例010UnityNetDemo\Assets\Player.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.Networking;

     

    public  class Player :NetworkBehaviour{

        public float  rotSpeed=150f;

        public float  movSpeed= 3.0f;

        private float  hor,ver;

        publicGameObject  bulletPrefab;

        publicTransform  bulletSpawn;

     

        voidUpdate(){

            if(!isLocalPlayer){

                return;

            }

     

            PlayerMove();

     

            if(Input.GetKeyDown(KeyCode.Space)){

                CmdFire();

            }

        }

     

        [Command]

        void CmdFire(){

            GameObject bullect =Instantiate<GameObject>(bulletPrefab,bulletSpawn.position,bullectSpawn.rotation);

            bullect.GetComponent<Rigidbody>().velocity = bullet.transform.forward*6;

            NetworkServer.Spawn(bullect);

            Destroy(bullet,2f);

        }

     

        void PlayerMove(){

            hor = Input.GetAxis(Horizontal) * Time.deltaTime*rotSpeed;

            ver = Input.GetAxis(Vertical) * Time.deltaTime*movSpeed;

            transform.Rotate(0, hor, 0);

            transform.Translate(0,0, ver);

        }

     

        public override  void  OnStartLocalPlayer(){

            GetComponent<MeshRenderer>().material.color= Color.green;

        }

    }




    #小案例011SocketFileRecv

    #小案例011SocketFileRecv

    ++++Server\Program.cs

    ++++Client\Program.cs


    ###Server\Program.cs

    D:\yanlz_DemoPro()-\小案例011socketFileRecv\Server\ConsoleApp1\Program.cs

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Net;

    using System.Net.Sockets;

    using System.Text;

    using System.Threading;

    using System.Threading.Tasks;

     

    namespace Server{

        class Program{

            static void Main(string[]  args){

                Myserver server = newMyserver();

                server.Start();

            }

        }

     

        class Myserver{

            Socket serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

            IPEndPoint point = new IPEndPoint(IPAddress.Any,12345);

     

            public void Start(){

                serverSocket.Bind(point);

                serverSocket.Listen(10);

                Console.WriteLine(立钻哥哥Print:服务器启动成功);

     

                Thread acceptThread = new Thread(Accept);

                acceptThread.IsBackground =true;

                acceptThread.Start();

     

                Console.ReadKey();

            }

     

            void Accept(){

                Socket client = serverSocket.Accept();

                IPEndPoint point = client.RemoteEndPointas IPEndPoint;

                Console.WriteLine(point.Address +[ + point.Port +]连接成功);

     

                Thread receiveThread = new Thread(Receive);

                receiveThread.IsBackground= true;

                receiveThread.Start(client);

     

                Accept();

            }

     

            public void Receive(objectobj){

                Socket client = objas Socket;

                IPEndPoint point= client.RemoteEndPointas IPEndPoint;

                byte[]msg =newbyte[1024];

                int length= client.Receive(msg);

                Console.WriteLine(point.Address +[ + point.Port +] + Encoding.UTF8.GetString(msg, 0, length));

        

                Receive(client);

            }

        }

    }


    ###Client\Program.cs

    D:\yanlz_DemoPro()-\小案例011socketFileRecv\Client\ConsoleApp2\Program.cs

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Net.Sockets;

    using System.Text;

    using System.Threading.Tasks;

     

    namespace  Client{

        class  Program{

            static void Main(string[]  args){

                MyClient client = newMyClient();

                client.Connect(127.0.0.1,12345);

                Console.WriteLine(立钻哥哥Print:请输入内容);

           

                string msg = Console.ReadLine();

                while(msg!= q){

                   client.Send(msg);

                   msg =Console.ReadLine();

                }

            }

     

            class MyClient{

                Socket clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

        

                public void Connect(stringip,int port){

                   clientSocket.Connect(ip,port);

                    Console.WriteLine(立钻哥哥Print:连接成功);

                }

     

                public void  Send(string msg){

                   clientSocket.Send(Encoding.UTF8.GetBytes(msg));

                }

            }

        }

    }




    #小案例012、切水果CutFruitDemo

    #小案例012、切水果CutFruitDemo

    ++++MouseControl.cs

    ++++DestroyOnTime.cs

    ++++ObjectControl.cs

    ++++Spawner.cs

    ++++UIOver.cs

    ++++UIScore.cs

    ++++UIStart.cs




    ###MouseControl.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\MouseControl.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public  class  MouseControl:MonoBehaviour{

        LineRenderer  lineRenderer;

        Vector3[]  positions=new Vector3[10];

        bool  firstMouse;

        bool  MouseDown;

     

        Vector3  head;

        Vector3  last;

     

        int posCount;

     

        private voidStart(){

            lineRenderer = GetComponent<LineRenderer>();

        }

     

        private void  Update(){

            if(Input.GetMouseButtonDown(0)){

                firstMouse = true;

                MouseDown = true;

            }

     

            if(Input.GetMouseButtonUp(0)){

                MouseDown = false;

            }

     

            OnDrawLine();

            firstMouse=false;

        }

     

        private void OnDrawLine(){

            if(firstMouse){

                posCount = 0;

                head = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePositon.x,Input.mousePosition.y,12.9f));

                last = head;

            }

     

            if(MouseDown){

                head = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,Input.mousePosition.y,12.9f));

                if(Vector3.Distance(head,last) > 0.01f){

                   SavePosition(head);

                   posCount++;

                   OnRayCast(head);

                }

                last=head;

            }else{

               positions = new Vector3[10];

            }

     

            ChangePositions(positions);

        }

     

        void SavePosition(Vector3 pos){

            if(posCount <= 9){

                for(inti =posCount;  i <=9;  i++){

                   positions[i] =pos;

                }

            }else{

                for(int i =0;  i<9;  i++){

                   positions[i] =positions[i +1];

                   positions[9] =pos;

                }

            }

        }

     

        void ChangePositions(Vector3[ ]  positions){

            linerRenderer.SetPositions(positions);

        }

     

        void OnRayCast(){

            Vector3 screenPosition = Camera.main.WorldToScreenPoint(pos);

            Ray ray = Camera.main.ScreenPointToRay(screenPosition);

            RaycastHit[]hits =Physics.RaycastAll(ray);

     

            for(int i =0;  i <hits.Length;  i++){

                hits[i].collider.gameObject.SendMessage(OnCut,SendMessageOptions.DontRquireReceiver);

            }

        }

    }


    ###DestroyOnTime.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\DestroyOnTime.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //立钻哥哥:按照时间销毁

    public class  DestroyOnTime:MonoBehaviour{

        public float  desTime=2f;

     

        void  Start(){

            Invoke(Dead, desTime);

        }

     

        void Dead(){

            Destroy(gameObject);

        }

    }


    ###ObjectControl.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\ObjectControl.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //立钻哥哥:物体控制脚本

    public  class  ObjectControl:MonoBehaviour{

        public GameObject  halfFruit;  //一半的水果

        public  GameObject  Splash;

        public  GameObject SplashFlat;

        public GameObject  Firework;

        private bool  dead=false;

        public  AudioClip  ac;

     

        //被切割的时候调用

        public void OnCut(){

            //防止重复调用

            if(dead){

                return;

            }

     

            if(gameObject.name.Contains(Bomb)){

                //生成特效

                Instantiate(Firework,transform.position,Quaternion.identity)

                UIScore.Instance.Remove(20);    //如果是炸弹,就需要扣分

            }else{

                //先生成被切割的水果

                for(inti = 0;  i <2;  i++){

                   GameObject  go= Instantiate<GameObject>(halfFruit,transform.position,Random.rotation);

                   go.GetComponent<Rigidbody>().AddForce(Random.onUnitSphere*5f,ForceMode.Impulse);

                }

     

                 //生成特效

                Instantiate(Splash,transform.position,Quaternion.identity);

                Instantiate(SplashFlat,transform.position,Quaternion.identity);

                UIScore.Instance.Add(10); //如果是水果,就加分

            }

     

            AudioSource.PlayClipAtPoint(ac,transform.position);

     

            Destroy(gameObject); //销毁自身

            dead = true;

        }

    }


    ###Spawner.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\Spawner.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

     

    //立钻哥哥:用来产生水果、炸弹等(也让它能控制销毁)

    public  class  Spawner:MonoBehaviour{

        [Header(水果的预设)]

        public GameObject[]  Fruits;

     

        [Header(炸弹的预设)]

        public GameObject  Bomb;

     

        public AudioSource  audioSource;    //播放声音的组件

        float  spawnTime = 3f;    //产生时间

        bool isPlaying = true;    //是否在玩游戏

     

        void  Update(){

            if(!isPlaying){

                return;

            }

     

            spawnTime-= Time.deltaTime;

     

            if(0 >spawnTime){

                //到时间了就开始产生水果

                int fruitCount= Random.Range(1,5);    

                for(inti=0;  i <fruitCount;  i++){

                   onSpawn(true);

                }

     

                //随机产生炸弹

                int bombNum = Random.Range(0,100);

                if(bombNum>10){

                   onSpawn(false);

                }

     

                spawnTime=3f;

            }

        }

     

        private  int  tmpZ=0;    //临时存储当前水果的z坐标

     

        //产生水果和炸弹

        //param isFruit:是否是水果

        private void onSpawn(bool  isFruit){

            this.audioSource.Play();    //播放音乐

     

            //x范围:-8.4~8.4

            //y范围:transform.pos.y

            //得知坐标范围

            float x =Random.Range(-8.4f, 8.4f);

            float y = transform.position.y;

            float z =tmpZ;

     

            //tmpZ -= 2;

            tmpZ = tmpZ-2;    //使水果不在一个平面上

            if(tmpZ<= -10){

                tmpZ = 0;

            }

     

            //实例化水果

            int fruitIndex =Random.Range(0, Fruits.Length);

            GameObject  go;

            if(isFruit){

                go = Instantiate<GameObject>(Fruits[fruitIndex],new Vector3(x,y,z),Random.rotation);

            }else{

                go = Instantiate<GameObject>(Bomb,new Vector3(x,y,z),Random.rotation)

            }

     

            //水果的速度

            Vector3  velocity  =new Vector3(-x *Random.Range(0.2f,0.8f), -Physics.gravity.y *Random.Range(1.2f,1.5f),0);

     

            //Rigidbody rigidbody = transform.GetComponent<Rigibody>();

            Rigidbody  rigidbody = go.GetComponent<Rigidbody>();

            rigidbody.velocity= velocity;

        }

     

        //有物体碰撞的时候调用

        private  void OnCollisionEnter(Collision  other){

            Destroy(other.gameObject);

        }

    }


    ###UIOver.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\UIOver.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

    using UnityEngine.Events;

     

    public  class UIOver :MonoBehaviour{

        public  UnityEvent  events;

     

        public void OnClick(){

            UnityEngine.SceneManagement.SceneManager.LoadScene(0);

        }

    }


    ###UIScore.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\UIScore.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public  class  UIScore:MonoBehaviour{

        public  static  UIScore Instance=null;    //立钻哥哥:单例对象

     

        void  Awake(){

            Instance = this;

        }

     

        [SerializeField]

        private  Text txtScore;

        private int score = 0;    //当前多少分

     

        //加分

        public void Add(int  score){

            this.score +=  score;

            textScore.textthis.score.ToString();

        }

     

        //扣分

        public void Remove(int  score){

            this.score -=  score;

     

            //如果分数小于0,那么游戏结束

            if(this.score <= 0){

                UnityEngine.SceneManagement.SceneManager.LoadScene(over);

                return;

            }

     

            textScore.text =this.score.ToString();

        }

    }


    ###UIStart.cs

    D:\yanlz_DemoPro()-\小案例012、切水果CutFruitDemo\Assets\Scripts\UIStart.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

    using UnityEngine.SceneManagement;

     

    public  class  UIStart:MonoBehaviour{

        private  Button btnPlay;    //开始按钮

        private  Button  btnSound;    //声音按钮

        private  AudioSource audioSourceBG; //背景音乐播放器

        private  Image  imgSound;    //声音的图片

        public  Sprite[]  soundSprites;    //声音的图片

     

        void  Start(){

            getCompnents();

     

            btnPlay.onClick.AddListener(onPlayClick);

            bthSound.onClick.AddListener(onSoundClick);

        }

     

        void  OnDestroy(){

            btnPlay.onClick.RemoveListener(onPlayClick);

            btnPlay.onClick.RemoveListener(onSoundClick);

        }

     

        //寻找组件

        private void getComponents(){

            btnPlay = transform.Find(btnPlay).GetComponent<Button>();

            btnSound = transform.Find(btnSound).GetComponent<Button>();

            audioSourceBG = transform.Find(btnSound).GetComponent<AudioSource>();

            imgSound = transform.Find(btnSound).GetComponent<Image>();

        }

     

        //当开始按钮按下的点击事件

        void onPlayClick(){

            SceneManager.LoadScene(play,LoadSceneMode.Single);

        }

     

        //当声音按钮点击时候调用

        void onSoundClick(){

            if(audioSourceBG.isPlaying){

                //正在播放

                audioSourceBG.Pause();

                imgSound.sprite=soundSprites[1];

            }else{

                //停止播放

                audioSourceBG.Play();

                imgSound.sprite=soundSprites[0];

            }

        }

    }




    #小案例013、吃鸡_友军方位UV

    #小案例013、吃鸡_友军方位UV

    ++++CoordScript.cs

    ++++FriendMoveScript.cs

    ++++CameraScript.cs



    ###CoordScript.cs

    D:\yanlz_DemoPro()-\小案例013、吃鸡_友军方位UV\FriendCoordTest\Assets\CoordScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

    using UnityEngine.UI;

     

    public  class CoordScript:MonoBehaviour{

        RawImage  rawImage;

        public Transform  friendTrans;    //友军

        public  Transform  friendImg;    //友军Image

        float  width;

     

        private void  Start(){

            rawImage = GetComponent<RawImage>();

            width = transform.GetComponent<RectTransform>().rect.width;

        }

     

        private void  Update(){

            Rect  tmpRect  = new Rect(GetY(Camera.main.transform.eulerAngles.y),0.38f,1,1);

            rawImage.uvRect =tmpRect;

     

            //相机的投影前方

            Vector3 cameraForward =new Vector3(Camera.main.transform.forward.x,0,Camera.main.transform.forward.z);

     

            //计算与友军的夹角

            Vector3 dir = friendTrans.position-Camera.main.transform.position;

            dir = new Vector3(dir.x, 0, dir.z);

            float angle= Vector3.Angle(cameraForward,dir);

     

            //计算友军左右

            Vector3 normal =Vector3.Cross(cameraForward,dir);

            angle = normal.y<0 ?360-angle : angle;    //计算最终夹角

            float percent =GetYY(angle);    //根据角度(0-1)的percent

            float x =percent* width - width/2;    //变换

            friendImg.transform.localPosition =new Vector3(x, -30,0);

        }

     

        private float GetY(float  x){

            return (1 /360.0f) * (x %360) + 0.5f;

        }

     

        private float GetYY(float  x){

            return ((1 /180.0f) *x /2 +0.5f) %1;

        }

    }


    ###FriendMoveScript.cs

    D:\yanlz_DemoPro()-\小案例013、吃鸡_友军方位UV\FriendCoordTest\Assets\FriendMoveScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public class  FriendMoveScript:MonoBehaviour{

        private void  Update(){

            transform.RotateAround(Vector3.zero,Vector3.up, Time.deltaTime*90f);

        }

    }


    ###CameraScript.cs

    D:\yanlz_DemoPro()-\小案例013、吃鸡_友军方位UV\FriendCoordTest\Assets\Scripts\Application\CameraScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System;

     

    public class  CameraScript:MonoBehaviour{

        public Transform  y_Axis;

        public Transform  x_Axis;

        public Transform  z_Axis;

        public Transform  zoom_Axis;

        public Transform  player;

     

        float hor,ver,scrollWheel;

        public float  roSpeed=180;

        public float  scSpeed=5f;

        float  upLimitAngle=60f;

        float downLimitAngle=0;

     

        public  bool followFlag=true;

        float x = 0;

        floatsc= 8,minDis= 1,maxDis=12;

     

        void  LateUpdate(){

            hor = Input.GetAxis(Mouse X);

            ver = Input.GetAxis(Mouse Y);

            scrollWheel = Input.GetAxis(Mouse ScrollWheel);

     

            //水平旋转

            if(hor != 0){

                y_Axis.Rotate(Vector3.up*roSpeed* hor *Time.deltaTime);

            }

     

            //垂直旋转

            if(ver!= 0){

                x -= ver*Time.deltaTime*roSpeed;

                x = Mathf.Clamp(x, -downLimitAngle,upLimitAngle);

                Quaternion q =Quaternion.identity;

                q = Quaternion.Euler(new Vector3(x,x_Axis.eulerAngles.y,x_Axis.eulerAngles.z));

                x_Axis.rotation=q;

            }

     

            //缩放

            if(scrollWheel  !=  0){

                sc -= scrollWheel*Time.deltaTime*scSpeed;

                zoom_Axis.transform.localPosition = new Vector3(0,0,Mathf.Clamp(-sc, -maxDis, -minDis));

            }

     

            //跟随玩家

            if(followFlag){

                y_Axis.position = player.position + Vector3.up*1.7f;

            }

     

            //控制玩家旋转

            //player.forward = new Vector3(transform.forward.x, 0, transform.forward.z);

        }

    }




    #小案例014、数据库背包SqliteEZ_Bag

    #小案例014、数据库背包SqliteEZ_Bag

    ++++DataBaseController.cs

    ++++HeroMessage.cs

    ++++SqliteDataScripts.cs

    ++++StoreWeapon.cs

    ++++WeaponBox.cs




    ###DataBaseController.cs

    D:\yanlz_DemoPro()-\小案例014SqliteEZ_Bag\Assets\DataBaseController.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using Mono.Data.Sqlite;

     

    //立钻哥哥:封装数据库

    public  class  DataBaseController:MonoBehaviour{

        public static  DataBaseController  instance;   //单例脚本对象

        private string  sqlitePath;    //数据库地址

        private  SqliteConnection  con;    //连接

        private  SqliteCommand  command;

        private SqliteDataReader  reader;

     

        void  Awake(){

            instance = this;

        }

     

        //连接数据库

        //param databaseName:数据库名称

        public void ConnectToSqlite(string  databaseName){

            string connectDatabaseName  = databaseName;    //获取数据库名称

        

            //判断数据库名称中是否包含.sqlite

            if(!connectDatabaseName.Contains(.sqlite)){

                connectDatabaseName +=.sqlite;    //如果不包含就添加

            }

     

            //拼接数据库连接路径

            sqlitePath =Data Source=  +Application.streamingAssetsPath+/ +connectDatabaseName;

            con = new SqliteConnection(sqlitePath);    //实例化数据库连接对象

            command = con.CreateCommand();    //创建数据库指令对象

            try{

                con.Open();    //打开数据库

                print(立钻哥哥Print:数据库打开成功);

            }catch(SqliteException  ex){

                //抛出异常

                Debug.Log(立钻哥哥Print:----异常: + ex);    

            }

        }

     

        //关闭数据库

        public void CloseSqliteConnection(){

            try{

                //如果连接对象不为空

                if(con != null){

                   con.Close();    //关闭数据库

                }

            }catch(SqliteExceptionex){

                Debug.Log(---- + exsss);

            }

        }

     

        //查询属性信息

        //param isHero:查询的是否是人物的属性

        //param name:人物名称或者装备名称

        public float[]SelectHeroMsg(bool isHero,string  name){

            try{

                float[]  result=newfloat[4];    //result:用于存储结果

                string selectQuery;    //查询

            

                //如果查询的是人物的属性

                if(isHero){

                   selectQuery =select AD,AP,AR,MP from hero where HeroName =‘”+name+”’”;

                }else{

                   selectQuery =select AD,AP,AR,MP from Equip where EquipName =‘”+name+”’”

                }

     

                command.CommandText =selectQuery;

     

                //执行sql语句

                reader= command.ExecuteReader();

     

                //读取第一行数据

                while(reader.Read()){

                    //遍历获取的结果

                    //根据字段的个数进行遍历

                   for(int i =0;  i <reader.FieldCount;  i++){

                       result[i] =System.Convert.ToSingle(reader.GetValue(i));

                    }

                }

                reader.Close();    //关闭连接

     

                return  result;    //返回结果

            }catch(SqliteException ex){

                Debug.Log(立钻哥哥Print:出错了~~~ + ex);

                return null;

            }

        }

     

        //添加或者移除装备

        public float[] AddOrRemoveProperty(boolisAdd,  float[] heroProperty,  float[]  equipProperty){

            try{

                if(heroProperty.Length==4 &&equipProperty.Length==4){

                   float[]  result =new float[4];    //创建结果数组,保存结果

                

                    //如果是添加装备

                   if(isAdd){

                        //遍历添加赋值

                       for(int i =0;  i <result.Length;  i++){

                           result[i] =heroProperty[i] +equipProperty[i];

                        }

                    }else{

                       //遍历移除赋值

                       for(inti =0;  i<result.Length;  i++){

                           result[i] =heroProperty[i] -equipProperty[i];

                        }

                    }

     

                    return result;    //将结果返回

                }else{

                    Debug.Log(立钻哥哥Print:出错了,属性个数不匹配);

                   return  null;

                }

            }catch(SqliteException  ex){

                Debug.Log(----异常: + ex);

                return null;

            }

        }

     

        //更新数据库中英雄的属性信息

        //param newHeroProperty:新的人物属性信息

        //param heroName:人物名称

        public void UpdateHeroProperty(float[] newHeroProperty,  string  heroName){

            try{

                //更新人物属性信息sql语句

                string updateQuery =update hero set ad= + newHeroProperty[0]

                    +,ap= +newHeroProperty[1]

                    +,ar= +newHeroProperty[2]

                    +,mp +newHeroProperty[3]

                    + where heroname=’”+heroName+”’”

     

                command.CommandText = updateQuery;    //赋值给指令对象

                command.ExecuteNonQuery();    //执行sql语句:增删改操作

            }catch(SqliteException  ex){

                Debug.Log(----出错了: + ex);

            }

        }

     

        //直接通过SQL语句去查询一个结果

        //returns:查询到的单个数据

        //param querySQL语句

        public  object  SelectSingle(string  query){

           try{

                command.CommandText =query;    //赋值SQL语句

                object obj =command.ExecuteScalar();    //执行查询语句

                return obj;    //返回结果

            }catch(SqliteExceptionex){

                Debug.Log(立钻哥哥Print: ----异常: + ex);

                return null;

            }

        }

     

        //查询更多数据

        //returns:数据结果

        //param query: SQL语句

        public List<ArrayList>  SelectMore(string query){

            try{

                List<ArrayList> result =new List<ArrayList>();    //创建结果数组

     

                command.CommandText= query;    //赋值SQL语句

                reader = command.ExecuteReader();    //执行

                while(reader.Read()){

                   ArrayList  temp =new ArrayList();    //实例化临时集合

                   for(int i =0; i <reader.FieldCount;  i++){

                       temp.Add(reader.GetValue(i));    //将结果添加到集合中

                    }

                    result.Add(temp);    //将临时集合添加到泛型集合(result)中

                }

     

                return  result;    //返回最终结果

     

            }catch(SqliteException  ex){

                Debug.Log(立钻哥哥Print:异常: + ex);

                return null;

            }

        }

    }


    ###HeroMessage.cs

    D:\yanlz_DemoPro()-\小案例014SqliteEZ_Bag\Assets\HeroMessage.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    //立钻哥哥:展示人物基础属性

    public class  HeroMessage:MonoBehaviour{

        private  Text uiText;

     

        void  Awake(){

            uiText = transfrom.GetChild(0).GetComponent<Text>();

        }

     

        //更新人物UI的信息

        //parma msg:人物信息数组

        public void UpdateUIMessage(float[]  msg){

            //UIText赋值

            uiText.text  = 攻击力 +msg[0] +\n +

                法强: +msg[1] +\n +

                护甲: +msg[2] +\n +

                魔抗 +msg[3];

        }

     

        void  Start(){

            DataBaseController.instance.ConnectToSqlite(LOL);    //连接数据库

     

            //查询数据

            float[]  heroMsg= DataBaseController.instance.SelectHeroMsg(true, EZ);

            UpdateUIMessage(heroMsg);    //展示

     

            DataBaseController.instance.CloseSqliteConnection();    //关闭数据库

        }

    }


    ###SqliteDataScripts.cs

    D:\yanlz_DemoPro()-\小案例014SqliteEZ_Bag\Assets\SqliteDataScript.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using System.Data;

    using Mono.Data.Sqlite;

     

    public class  SqliteDataScript:MonoBehaviour{

        private string path;    //指定路径

     

        void  Start(){

            path = Application.dataPath +/weapon.sqlite;    //1、数据存储的路径

        

            //2、创建数据库连接(Data Source:数据源)

            SqliteConnection connection =new SqliteConnection(Data Source= +path);

            connection.Open();    //3、打开数据库

     

            //4、创建指令对象(真正执行sql语句)

            SqliteCommand command =connection.CreateCommand();    

     

            //5、将sql语句设置给指令对象

            //string InsertStr =insert into hero values(立钻哥哥,10,8,100);    //插入

            //string InsertStr =insert into hero values(亦菲妹妹,10,8,100);

            //string InsertStr =insert into hero(heroname,ap,ad,level)values(大哥哥,10,8,100);

            //string DeleStr =delete from hero where level <5;    //删除

            //string UpdateStr =update hero set AP=1000 where rowid=2;    //修改

     

            string SleStr =select * from hero;    //查询

            command.CommandText =SleStr;

     

            //6、让指令对象去执行sql语句

            //ExecuteNonQuery:只作为增,删,改操作,不做查询

            command.ExecuteNonQuery();   

     

            //查询方法1ExecuteScalar

            //command.ExecuteScalar();    //返回所有结果中的第一个查询到的值

        

            //查询方法2ExecuteReader

            //SqliteDataReader:查询到的所有值都会存储到SqliteDataReader

            SqliteDataReader reader= command.ExecuteReader();

     

            //Read: 处理结果集(只要执行一次就会读取结果中的一行数据)

            while(reader.Read()){

                string name1 =reader.GetString(0);    //取出字段值

                int ap1= reader.GetInt16(1);

                int ad1 =reader.GetInt16(2);

                int level1 =reader.GetInt16(3);

            

                print(string.Format(name:{0},ap{1},ad{2},level:{3},name1,ap1,ad1,level1));

            }

     

            connection.Close();    //7、关闭数据库

        }

    }


    ###StoreWeapon.cs

    D:\yanlz_DemoPro()-\小案例014SqliteEZ_Bag\Assets\StoreWeapon.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public  class StoreWeapon:MonoBehaviour{

        private  WeaponBox box;

        private  HeroMessage  msg;

     

        void  Start(){

            box = GameObject.FindWithTag(WeaponB).GetComponent<WeaponBox>();

            msg = GameObject.FindWithTag(HeroMsg).GetComponent<HeroMessage>();

        }

     

        //立钻哥哥:添加装备的按钮

        //param equip:装备对象

        public void OnAddEquipButtonClick(GameObject  equip){

            int index= box.CanAddEquip();    //查看装备栏中能否添加装备

        

            //index != -1证明可以添加装备

            if(index!= -1){

                //拿到装备图片

                Sprite equipImage = equip.GetComponent<Image>().sprite;    

     

                //将装备图片放置到装备栏中

                box.transform.GetChild(index).GetComponent<Image>().sprite = equipImage;

            

                string equipName = equip.name;    //获取装备名称

        

                //通过数据库查询到指定装备数据

                DataBaseController.instance.ConnectToSqlite(LOL);    //打开数据库

            

                //查询并获得装备属性

                float[]  equipProperty = DataBaseController.instance.SelectHeroMsg(false,equipName);

     

                //拿到人物属性

                float[]  heroProperty =DataBaseController.instance.SelectHeroMsg(true,EZ);

          

                //生成新的人物属性

                float[]  newHeroProperty = DataBaseController.instance.AddOrRemoveProperty(true,heroProperty,equipProperty);

     

                //将新的人物属性同步到数据库中

                DataBaseController.instance.UpdateHeroProperty(newHeroProperty,EZ);

     

                msg.UpdateUIMessage(newHeroProperty);    //同步UI

     

                DataBaseController.instance.closeSqliteConnection();    //关闭数据库

     

                //将当前装备栏中的装备名称,存储到PlayerPrefs

                PlayerPrefs.SetString(Weapon +index,equip.name);

            }

        }

    }


    ###WeaponBox.cs

    D:\yanlz_DemoPro()-\小案例014SqliteEZ_Bag\Assets\WeaponBox.cs

    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;

    using UnityEngine.UI;

     

    public  class  WeaponBox:MonoBehaviour{

        public  Sprite  defaultPicture;    //装备栏的默认图片

        private HeroMessage  msg;  

        public  Sprite[]  equipPicture;    //所有装备图片的数组

     

        void  Awake(){

            msg = GameObject.FindWithTag(HeroMsg).GetComponent<HeroMessage>();

        }

     

        void  Start(){

            //获得两个Weapon

            string weapon0 = PlayerPrefs.GetString(Weapon0);

            stirng weapon1= PlayerPrefs.GetString(Weapon1);

     

            if(weapon!=Empty){

                //遍历图片库

                foreach(Sprite  item  in  equipPicture){

                    //如果图片库中的图片名称和PlayerPrefs的名称一样

                   if(item.name== weapon0){

                       //将图片库中的这张图片显示到装备栏中

                       transform.GetChild(0).GetComponent<Image>().sprete=item;

                    }

                }

            }

     

            if(weapon1!=Empty){

                //遍历图片库

                foreach(Sprite  item in  equipPicture){

                   if(item.name == weapon1){

                       transform.GetChild(1).GetComponent<Image>().sprite=item;

                    }

                }

            }

        }

     

        //能否添加装备

        public int CanAddEquip(){

            //获取两个装备栏中的图片名称

            string box01= transform.GetChild(0).GetComponent<Image>().sprite.name;

            string box02 = transform.GetChild(1).GetComponent<Image>().sprite.name;

            string defaultName =InputFieldBackground;    //装备栏默认图片的名称

        

            //如果装备栏中没有装备

            if(box01 == defaultName){

                return 0;

            }else if(box02 == defaultName){

                return 1;

            }else{

                return -1;

            }

        }

     

        //移除装备按钮

        //param equip:装备

        public void OnRemoveEquipButtonClick(GameObject  equip){

            string defaultName= InputFieldBackground;    //装备栏默认图片名

     

            if(equip.GetComponent<Image>().sprite.name!=defaultName){

                //获取当前装备栏的装备名称

                string equipName =equip.GetComponent<Image>().sprite.name;

     

                //将装备栏图片设置为默认图片

                equip.GetComponent<Image>().sprite = defaultPicture;

        

                DataBaseController.instance.ConnectToSqlite(LOL);    //打开数据库

     

                //查询数据库获取当前装备栏装备的属性

                float[]  equipProperty =DataBaseController.instance.SelectHeroMsg(false,equipName);

     

                //人物的属性减去装备属性,获取新的属性,再去刷新UI

                float[]  heroProperty= DataBaseController.instance.SelectHeroMsg(true,EZ);

     

                //得到一个新的属性

                float[]  newHeroProperty =DataBaseController.instance.AddOrRemoveProperty(false,heroProperty,equipProperty);

     

                //更新属性

                DataBaseController.instance.UpdateHeroProperty(newHeroProperty, EZ);

     

                msg.UpdateUIMessage(newHeroProperty);    //刷新UI

     

                DataBaseController.instance.CloseSqliteConnection();    //关闭数据库

     

                int index =0;

                for(inti =0;  i< transform.childCount;  i++){

                    //如果该子对象就是自己本身

                   if(equip.transform == transform.GetChild(i)){

                       index =i;    //获取位置

                        Debug.Log(equip.ToString() + | + transform.GetChild(i).ToString());

                    }

                }

     

                PlayerPrefs.SetString(Weapon +index,Empty);

            }

        }

    }




    #小案例015Json数据存储

    #小案例015Json数据存储

    ++++CubeItem.cs

    ++++CubeManager.cs

    ++++CubeTest.cs

    ++++JsonDemo.cs

    ++++Person.cs


    ###CubeItem.cs

    D:\yanlz_DemoPro()-\小案例015Json数据存储\Assets\Scripts\CubeItem.cs

    using UnityEngine;

    using System.Collections;

     

    public  class CubeItem{

        public string PosX{    get;    set;    };

        public string PosY{    get;    set;    }

        public string PosZ{    get;    set;    }

     

        public CubeItem(){

        }

     

        public CubeItem(string x,stringy,string z){

            this.PosX = x;

            this.PosY = y;

            this.PosZ = z;

        }

     

        public override  string  ToString(){

            return string.Format(X: +PosX+ Y: +PosY+ Z: +PosZ);

        }

    }


    ###CubeManager.cs

    D:\yanlz_DemoPro()-\小案例015Json数据存储\Assets\Scripts\CubeManager.cs

    using UnityEngine;

    using System.Collections;

    using LitJson;

    using System.Collections.Generic;

    using System;

    using System.IO;

     

    public class  CubeManager:MonoBehaviour{

        private  Transform  m_Transform;    //父物体的Transform

        private Transform[]  allCubeTrans;    //所有子物体的Transform

        private  List<CubeItemcubeList;    //Cube对象

        private List<CubeItemposList;    //json数据里的对象

        private string  jsonPath= null;

        private GameObject  cubePrefab;

     

        void  Start(){

            m_Transform = GetComponent<Transform>();

            cubeList = new List<CubeItem>();

            posList = new List<CubeItem>();

            josnPath = Application.dataPath+/Resources/json.txt;

            cubePrefab = Resources.Load<GameObject>(Prefabs/Cube);

        }

     

        void Update(){

            if(Input.GetKeyDown(KeyCode.A)){

                ObjectToJson();

            }

     

            if(Input.GetKeyDown(KeyCode.B)){

                JsonToObject();

            }

        }

     

        //立钻哥哥:对象转Json字符串数据

        void ObjectToJson(){

            cubeList.Clear();

            allCubeTrans = m_Transform.GetComponentsInChildren<Transform>();

     

            for(int i =1;  i < allCubeTrans.Length;  i++){

                print(allCubeTrans[i].position);

     

                Vector3 pos = allCubeTrans[i].position;

                CubeItem item = new CubeItem(Math.Round(pos.x,2).ToString(),Math.Round(pos.y,2).ToString(),Math.Round(pos.z,2).ToString());

                cubeList.Add(item);

            }

     

            string  str =JsonMapper.ToJson(cubeList);

            print(str);

     

            //IO持久化json数据,把它以文本的形式存储在本地中

            StreamWriter  sw =new StreamWriter(josnPath);

            sw.Write(str);

            sw.Close();

        }

     

        //Json数据转对象

        void JsonToObject(){

            //读取json数据信息

            TextAsset  textAsset =Resource.Load<TextAsset>(json);

            print(textAsset.text);

     

            //把数据转化为对象

            JsonData data =JsonMapper.ToObject(textAsset.text);

            for(inti =0;  i<data.Count;  i++){

                print(data[i].ToJson());

     

                //指定对象接收数据

                CubeItem item=JsonMapper.ToObject<CubeItem>(data[i].ToJson());

                posList.Add(item);

            }

     

            for(inti =0;  i<posList.Count;  i++){

                print(posList[i].ToString());

     

                Vector3 pos=new Vector3(float.Parse(posList[i].PosX),float.Parse(posList[i].PosY),float.Parse(posList[i].PosZ));

                GameObject.Instantiate(cubePrefab,pos,Quaternion.identity,m_Transform);

            }

        }

    }


    ###CubeTest.cs

    D:\yanlz_DemoPro()-\小案例015Json数据存储\Assets\Scripts\CubeTest.cs

    using UnityEngine;

    using System.Collections;

    using LitJson;

     

    public  class  CubeTest:MonoBehaviour{

        private Transform  m_Transform;

     

        void  Start(){

            m_Transform = GetComponent<Transform>();

            Vector3 pos =m_Transform.position;

     

            string str = JsonMapper.ToJson(pos);

            print(str);

        

            //LitJosn不支持float

            CubeItem item  =  newCubeItem(pos.x,pos.y,pos.z);

            string str  =  JsonMapper.ToJson(item);

            print(str);

        }

    }


    ###JsonDemo.cs

    D:\yanlz_DemoPro()-\小案例015Json数据存储\Assets\Scripts\JsonDemo.cs

    using UnityEngine;

    using System.Collections;

    using LitJson;

    using System.Collections.Generic;

     

    public  class  JsonDemo:MonoBehaviour{

        private  List<Personpersons;    //Person对象

        private  List<PersonpersonsOne;    //Json数据里的对象

     

        void  Start(){

            //单个对象转Json

            //Person p1 = new Person(aaa, 18,bbb);

            //string str = JsonMapper.ToJson(p1);

            //print(str);

     

            //Json转单个对象

            //Person p2 = JsonMapper.ToObject<Person>(str);

            //print(p2.ToString());

     

            //多个对象转Json

            persons = new List<Person>();

            Person p1 = newPerson(aaa,18,bbb);

            Person p2= newPerson(ccc,20,ddd);

            persons.Add(p1);

            persons.Add(p2);

            string str=JsonMapper.ToJson(persons);

            print(str);

     

            //Json转多个对象

            personOne = new List<Person>();

            JsonData data = JsonMapper.ToObject(str);

            for(inti = 0; i < data.Count;  i++){

                print(data.ToJson());

     

                Person item =JsonMapper.ToObject<Person>(data[i].ToJson());

                personsOne.Add(item);

            }

     

            for(int i = 0;  i < personsOne.Count;  i++){

                print(personsOne[i].ToString());

            }

        }

    }


    ###Person.cs

    D:\yanlz_DemoPro()-\小案例015Json数据存储\Assets\Scripts\Person.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  Person{

        public string Name{    get;    set;    }

        public int Age{    get;    set;    }

        public string  Address{    get;    set;    }

     

        public Person(){

        }

     

        public Person(string  name,int age,string  address){

            this.Name  = name;

            this.Age = age;

            this.Address = address;

        }

     

        public override  string  ToString(){

            return string.Format(名字: +Name+ 年龄: +Age+ 住址: +Address);

        }

    }




    #小案例016、关卡系统LevelSystem

    #小案例016、关卡系统LevelSystem

    ++++LevelData.cs

    ++++LevelSelected.cs

    ++++MainGUI.cs


    ###LevelData.cs

    D:\yanlz_DemoPro()-\小案例016、关卡系统LevelSystem\Assets\Script\LevelData.cs

    using UnityEngine;

    using System.Collections;

    using System.Collections.Generic;

     

    public  class  LevelData{

        public  static int _maxLevels =PlayerPrefs.GetInt(MaxLevels);

        public  static int _unLockLevels = PlayerPrefs.GetInt(UnLockedLevels);

        static string  unLock= unLock;

        static string  Locked=Locked;

        public  static List<stringTotalLevels;

     

        public static List<stringaddLevels(){

            TotalLevels = new List<string>();

            for(int i =0;  i< PlayerPrefs.GetInt(UnLockedLevels);  i++){

                TotalLevels.Add(unLock);

            }

     

            for(int i =0;  i < (PlayerPrefs.GetInt(MaxLevels) - PlayerPrefs.GetInt(UnLockedLevels));i++){

                TotalLevels.Add(Locked);

            }

     

            return  TotalLevels;

        }

     

        public static  void SaveData(){

            //初始化

            if(_maxLevels ==0&&_unLockLevels==0){

                _maxLevels = 11;

                _unLockLevels =1;

            }

     

            PlayerPrefs.SetInt(MaxLevels,_maxLevels);

            PlayerPrefs.SetInt(UnLockedLevels,_unLockLevels);

        }

    }


    ###LevelSelected.cs

    D:\yanlz_DemoPro()-\小案例016、关卡系统LevelSystem\Assets\Script\LevelSelected.cs

    using UnityEngine;

    using System.Collections;

     

    public  class  LevelSelected:MonoBehaviour{

        public GUIStyle  fontStyle;

     

        void  OnGUI(){

            if(GUI.Button(new Rect(10,10,100,100),PlayerPrefs.GetInt(LevelId).ToString(),fontStyle)){

                if(PlayerPrefs.GetInt(levelId) == LevelData._unLockLevels){

                   LevelData._unLockLevels++;

                }

     

                LevelData.SaveData();

                Application.LoadLevel(0);

            }

        }

    }


    ###MainGUI.cs

    D:\yanlz_DemoPro()-\小案例016、关卡系统LevelSystem\Assets\Script\MainGUI.cs

    using UnityEngine;

    using System.Collecitons;

    using System.Collecitons.Generic;

     

    public class  MainGUI:MonoBehaviour{

        int  MaxLevel;

        LevelData  ld;

     

        void  Start(){

            LevelData.SaveData();

            MaxLevel = PlayerPrefs.GetInt(MaxLevels);

        }

     

        void  OnGUI(){

            for(inti=0;  i <MaxLevel;  i++){

                if(GUI.Button(new Rect(70*i,10,65,65),LevelData.addLevels()[i])){

                   if(LevelData.addLevel()[i] == unLock){

                       PlayerPrefs.SetInt(LevelId,i+1);

                       Application.LoadLevel(1);

                    }

                }

            }

     

            GUI.Label(new Rect(100,100,200,100),PlayerPrefs.GetInt(MaxLevels).ToString() + PlayerPrefs.GetInt(UnLockedLevels).ToString());

        }

    }




    #小案例017






    #立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

    ++立钻哥哥推荐的拓展学习链接(Link_Url

    ++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

    ++++设计模式简单整理https://blog.csdn.net/vrunsoftyanlz/article/details/79839641

    ++++U3D小项目参考https://blog.csdn.net/vrunsoftyanlz/article/details/80141811

    ++++UML类图https://blog.csdn.net/vrunsoftyanlz/article/details/80289461

    ++++Unity知识点0001https://blog.csdn.net/vrunsoftyanlz/article/details/80302012

    ++++U3D_Shader编程(第一篇:快速入门篇)https://blog.csdn.net/vrunsoftyanlz/article/details/80372071

    ++++U3D_Shader编程(第二篇:基础夯实篇)https://blog.csdn.net/vrunsoftyanlz/article/details/80372628

    ++++Unity引擎基础https://blog.csdn.net/vrunsoftyanlz/article/details/78881685

    ++++Unity面向组件开发https://blog.csdn.net/vrunsoftyanlz/article/details/78881752

    ++++Unity物理系统https://blog.csdn.net/vrunsoftyanlz/article/details/78881879

    ++++Unity2D平台开发https://blog.csdn.net/vrunsoftyanlz/article/details/78882034

    ++++UGUI基础https://blog.csdn.net/vrunsoftyanlz/article/details/78884693

    ++++UGUI进阶https://blog.csdn.net/vrunsoftyanlz/article/details/78884882

    ++++UGUI综合https://blog.csdn.net/vrunsoftyanlz/article/details/78885013

    ++++Unity动画系统基础https://blog.csdn.net/vrunsoftyanlz/article/details/78886068

    ++++Unity动画系统进阶https://blog.csdn.net/vrunsoftyanlz/article/details/78886198

    ++++Navigation导航系统https://blog.csdn.net/vrunsoftyanlz/article/details/78886281

    ++++Unity特效渲染https://blog.csdn.net/vrunsoftyanlz/article/details/78886403

    ++++Unity数据存储https://blog.csdn.net/vrunsoftyanlz/article/details/79251273

    ++++Unity中Sqlite数据库https://blog.csdn.net/vrunsoftyanlz/article/details/79254162

    ++++WWW类和协程https://blog.csdn.net/vrunsoftyanlz/article/details/79254559

    ++++Unity网络https://blog.csdn.net/vrunsoftyanlz/article/details/79254902

    ++++C#事件https://blog.csdn.net/vrunsoftyanlz/article/details/78631267

    ++++C#委托https://blog.csdn.net/vrunsoftyanlz/article/details/78631183

    ++++C#集合https://blog.csdn.net/vrunsoftyanlz/article/details/78631175

    ++++C#泛型https://blog.csdn.net/vrunsoftyanlz/article/details/78631141

    ++++C#接口https://blog.csdn.net/vrunsoftyanlz/article/details/78631122

    ++++C#静态类https://blog.csdn.net/vrunsoftyanlz/article/details/78630979

    ++++C#中System.String类https://blog.csdn.net/vrunsoftyanlz/article/details/78630945

    ++++C#数据类型https://blog.csdn.net/vrunsoftyanlz/article/details/78630913

    ++++Unity3D默认的快捷键https://blog.csdn.net/vrunsoftyanlz/article/details/78630838

    ++++游戏相关缩写https://blog.csdn.net/vrunsoftyanlz/article/details/78630687

    ++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/


    --_--VRunSoft : lovezuanzuan--_--

    展开全文
  • U3D-常用的插件整理

    2019-06-11 18:25:20
    NGUI是严格遵循KISS原则并用C#编写的Unity(适用于专业版和免费版)插件,提供强大的UI系统和事件通知框架。其代码简洁,多数类少于200行代码。这意味着程序员可以很容易地扩展NGUI的功能或调节已有功能。对所有其他...

    unity 3d常用的插件介绍:

    1.NGUI

    NGUI是严格遵循KISS原则并用C#编写的Unity(适用于专业版和免费版)插件,提供强大的UI系统和事件通知框架。其代码简洁,多数类少于200行代码。这意味着程序员可以很容易地扩展NGUI的功能或调节已有功能。对所有其他用户而言,这意味着更高的性能、更低的学习难度和更加有趣。完全集成到Inspector面板中。 不需要点击Play按钮就能查看结果。 在场景视图中看到的就是在游戏视图中得到的(所见即所得)。 基于组件的、模块化的特性:要让你的界面控件做什么,只需为其附加