U3D小項目參考

U3D項目參考

++U3D小案例簡述node

++++這裏是立鑽哥哥彙總的幾個U3D小案例,經過案例學習U3D的基本編程和技巧。ios

++++小案例會不斷更新補充,經過學習掌握U3D的編程和思想。算法

++小案例目錄:sql

++++小案例001、貪吃蛇Demo數據庫

++++小案例002、飛機大戰Demo編程

++++小案例003MVC框架(提高等級案例)json

++++小案例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(){

        //讀取

相關文章
相關標籤/搜索