在unity中,我对一个物体的操作往往是直接性的操作,比方说移动。在有些时候直接性的操作会导致一些问题,比方说在操作完后,返回时可能要做很多的工作,这样就麻烦而且效率下降。在这里分享下自己学到的经验,可能这个方法对于老手来说很常用,我也是这样学的,先说下大体思路:方法是始终操作替身,就是用鼠标拖动A物体向前10个单位,在选中点击A时,先Clone一个A,并且把A物体隐藏(Collider有必要false),操作的AClone拖动到10个单位后,A物体在此位置显示出来,接着把AClone删除。
下面是分享的一个实例,实例中就是用的itween插件与替身的方法进行操作。如果有不当之处请多多提出,多多指教。。。。
对于itween的学习在这里不多说了,在官方上说的很详细。
代码:
View Code
1 using UnityEngine; 2 using System.Collections; 3 using System.Collections.Generic; 4 using Public.Tools; 5 6 public class MoveShowOneObj : MonoBehaviour { 7 //模拟的数据,正常情况下,一个项目会读取数据库,根据这个字符串用JSON解析读取里面的信息 8 string DBstr = "{\"Floor\":{\"1\":{\"id\":\"1\",\"model\":\"LC01_ZHULOU\"},\"2\":{\"id\":\"2\",\"model\":\"LC02_ZHULOU\"},\"3\":{\"id\":\"3\",\"model\":\"LC03_ZHULOU\"}}}"; 9 bool floorMoveState = false;//记录层是否在展开状态。 10 bool op = false; //仅控制按钮操作 11 bool isMoving = false; //记录是否在移动中 12 13 void OnGUI() 14 { 15 if (GUI.Button(new Rect(20, 60, 60, 30), "展开")) 16 { 17 op = !op; 18 ShowFloorFunc(op);//展示的方法 19 } 20 } 21 22 void reset() 23 { 24 op = false; 25 isMoving = false; 26 floorMoveState = false; 27 } 28 29 void ShowFloorFunc(bool OP) 30 { 31 if (OP) 32 { 33 if (floorMoveState == false) 34 { 35 InstantiateFloorFunc(); 36 } 37 isMoving = true; 38 39 MoveFloorObj(floorObjList[0], GameObject.Find(floorObjList[0].name.Replace("(Clone)", "")).transform.TransformPoint(new Vector3(0, -30,0)), "easeInQuart", 3f, "MoveComplateTo", gameObject); 40 MoveFloorObj(floorObjList[2], GameObject.Find(floorObjList[2].name.Replace("(Clone)", "")).transform.TransformPoint(new Vector3(0, 30, 0)), "easeInQuart", 3f); 41 } 42 else 43 { 44 if (floorMoveState == true) 45 { 46 isMoving = true; 47 MoveFloorObj(floorObjList[0], GameObject.Find(floorObjList[0].name.Replace("(Clone)", "")).transform.position, "easeInOutQuart", 3.5f, "MoveComplate", gameObject); 48 MoveFloorObj(floorObjList[2], GameObject.Find(floorObjList[2].name.Replace("(Clone)", "")).transform.position, "easeInOutQuart", 3.5f, "DeleteCloneFloorObj", gameObject); 49 } 50 } 51 } 52 53 List<GameObject> floorObjList = new List<GameObject>();//存储被操作的楼层 54 void MoveComplate() 55 { 56 isMoving = false; 57 } 58 59 void MoveComplateTo() 60 { 61 Helper.MoveFloorObj(floorObjList[0], floorObjList[0].transform.TransformPoint(new Vector3(200, 0, 0)), "easeOutQuart", 2.5f); 62 Helper.MoveFloorObj(floorObjList[2], floorObjList[2].transform.TransformPoint(new Vector3(-200, 0, 0)), "easeOutQuart", 2.5f, "MoveComplate", gameObject); 63 } 64 65 //Clone你要操作的对象。 66 void InstantiateFloorFunc() 67 { 68 //用JSON解析为hashtable 69 Hashtable floorInfo = (Hashtable)JSON.JsonDecode(DBstr); 70 floorInfo = (Hashtable)floorInfo["Floor"]; 71 foreach (DictionaryEntry item in floorInfo) 72 { 73 Hashtable info = (Hashtable)item.Value; 74 if (info != null && ((string)info["model"] != null || (string)info["model"] != "")) 75 { 76 GameObject origeFloor = GameObject.Find((string)info["model"]);//注意的是当Clone一个物体对象时,它的子物体也会被Clone 77 GameObject floorObjClone = (GameObject)Instantiate(origeFloor, origeFloor.transform.position, origeFloor.transform.rotation); 78 floorObjList.Add(floorObjClone); 79 floorObjClone.transform.parent = GameObject.Find((string)info["model"]).transform.parent; 80 } 81 } 82 HideOrigeFloorObj(false); 83 floorMoveState = true; 84 } 85 86 //隐藏被操作的物体对象。 87 void HideOrigeFloorObj(bool op) 88 { 89 foreach (GameObject item in floorObjList) 90 { 91 Transform[] obj = GameObject.Find(item.name.Replace("(Clone)", "")).GetComponentsInChildren<Transform>(); 92 foreach (Transform itemObj in obj) 93 { 94 if (itemObj.renderer != null) itemObj.renderer.enabled = op; 95 if (itemObj.collider != null) itemObj.collider.enabled = op; 96 } 97 } 98 } 99 100 //在操作完成后删除Clone 101 void DeleteCloneFloorObj() 102 { 103 if (floorObjList == null || floorObjList.Count == 0) return; 104 HideOrigeFloorObj(true); 105 foreach (GameObject item in floorObjList) 106 { 107 GameObject.Destroy(item); 108 } 109 floorObjList.Clear(); 110 floorMoveState = false; 111 reset();//在完成后记得及时的清理干净 112 } 113 114 #region 运用itween的移动效果,具体itween的学习建议去官方学习。 115 void MoveFloorObj(GameObject floorObj, Vector3 floorObjPos, string flyType, float flyTime) 116 { 117 //主要用的是MoveTo方法 118 iTween.MoveTo(floorObj, iTween.Hash("position", floorObjPos, "easeType", flyType, "loopType", "none", "time", flyTime)); 119 } 120 121 void MoveFloorObj(GameObject floorObj, Vector3 floorObjPos, string flyType, float flyTime, string oncomplete, GameObject obj) 122 { 123 iTween.MoveTo(floorObj, iTween.Hash("position", floorObjPos, "easeType", flyType, "loopType", "none", "time", flyTime, "oncomplete", oncomplete, "oncompletetarget", obj)); 124 } 125 #endregion 126 }
这种方法是是避免破坏原始的操作,如果一个独立功能,在整个逻辑中只是展示或者移动,用替身的方法可以减少工作量,提高工作效率。