using FairyGUI; using System; using System.Collections; using System.Collections.Generic; using UI.DressUp; using UnityEngine; using UnityEngine.EventSystems; namespace GFGGame { public class PhotographView : BaseView { private UI_PhotographUI _ui; private GameObject _scenePrefab; private GameObject _sceneObject; private DressUpObjDataCache equipDataCache; private const string MOVE = "MOVE"; private const string SCALE = "SCALE"; private const string ROTATION = "ROTATION"; private const float MaxScale = 2; private const float MinScale = 0.1f; private GameObject bodyParent; private GameObject bgParent; private GameObject npcParent; private GameObject borderParent; private GameObject sceneParent; private List _listData = null;//当前选择的资源数据 private List _equipRoleData = new List();//当前穿戴的角色数据 private Dictionary> _equipSceneData = new Dictionary>();//当前穿戴的场景数据 private Dictionary _equipPos = new Dictionary(); private Dictionary _mousePos = new Dictionary(); private Dictionary _equipDistance = new Dictionary(); // private GameObject hitGameObj;//当前选中的物体 private GameObject hitParentGameObj;//当前选中的父物体(需要进行移动缩放旋转的物体) private GameObject memoryHitParentGameObj;//当前选中的父物体(需要进行移动缩放旋转的物体) private Vector3 distance = Vector3.zero;//点击位置和点击物体原点的距离,用于 private Vector2 lastPos = Vector2.zero;//上一次移动后从物体中心到鼠标位置的方向 private float _startDistance;//从物体中心到缩放按钮的距离 private SwipeGesture swipeGesture; private PinchGesture pinchGesture; private RotationGesture rotationGesture; private bool isTouchUI = false;//点击在m_comSelectBox按钮上 private bool isTwoTouchPoint = false; private int maxLayer = int.MinValue;//最上层的层级数 protected override void OnInit() { base.OnInit(); packageName = UI_PhotographUI.PACKAGE_NAME; _ui = UI_PhotographUI.Create(); viewCom = _ui.target; isfullScreen = true; _ui.m_btnBg.onClick.Add(OnClickBtnBg); _ui.m_btnChoose.onClick.Add(OnClickBtnChoose); _ui.m_btnBack.onClick.Add(OnClickBtnBack); _ui.m_btnPhotograph.onClick.Add(OnClickBtnPhotograph); _ui.m_ComSelectRes.m_list.itemRenderer = RenderListItem; _ui.m_ComSelectRes.m_list.onClickItem.Add(OnListItemClick); _ui.m_ComSelectRes.m_comBtnTab.m_c1.onChanged.Add(OnContorllerChanged); _scenePrefab = GFGAsset.Load(ResPathUtil.GetPrefabPath("ScenePhotograph")); _ui.target.onTouchBegin.Add(OnTouchUIBegin); _ui.target.onTouchMove.Add(OnTouchUIMove); _ui.target.onTouchEnd.Add(OnTouchUIEnd); _ui.m_comSelectBox.m_btnSize.onTouchBegin.Add(OnTouchBtnSizeBegin); _ui.m_comSelectBox.m_btnSize.onTouchMove.Add(OnTouchBtnSizeMove); _ui.m_comSelectBox.m_btnSize.onTouchEnd.Add(OnTouchBtnSizeEnd); _ui.m_comSelectBox.m_btnFlip.onTouchBegin.Add(OnTouchBtnFlipBegin); _ui.m_comSelectBox.m_btnFlip.onTouchEnd.Add(OnTouchBtnFlipEnd); _ui.m_comSelectBox.m_btnDelete.onTouchBegin.Add(OnTouchBtnDeleteBegin); _ui.m_comSelectBox.m_btnDelete.onTouchEnd.Add(OnTouchBtnDeleteEnd); } protected override void OnShown() { base.OnShown(); Input.multiTouchEnabled = true; equipDataCache = EquipDataCache.cacher; if (_sceneObject == null) { _sceneObject = GameObject.Instantiate(_scenePrefab); EquipDataCache.cacher.setSceneObj(_sceneObject); bgParent = _sceneObject.transform.Find("Bg").gameObject; bodyParent = _sceneObject.transform.Find("Scene/Role").gameObject; sceneParent = _sceneObject.transform.Find("Scene").gameObject; npcParent = _sceneObject.transform.Find("Scene/Npc").gameObject; borderParent = _sceneObject.transform.Find("Border").gameObject; } pinchGesture = new PinchGesture(_ui.target); pinchGesture.onAction.Add(OnPinch); rotationGesture = new RotationGesture(_ui.target); rotationGesture.onAction.Add(OnRotate); _ui.m_ComSelectRes.m_comBtnTab.m_c1.selectedIndex = 0; OnClickBtnChoose(); RefreshList(EnumPhotographType.BG); DisposeEquipData(); SceneController.UpdatePhotographBgOrNpcOrBorder(_sceneObject, EnumPhotographType.BG, equipDataCache.bgId, maxLayer, out maxLayer); UpdateBody(); UpdateScene(); } /************************************************************UI界面*********************************************************/ private void OnContorllerChanged(EventContext context) { int index = _ui.m_ComSelectRes.m_comBtnTab.m_c1.selectedIndex; RefreshList((EnumPhotographType)index); } private void RefreshList(EnumPhotographType index) { _ui.m_ComSelectRes.m_list.numItems = 0; switch (index) { case EnumPhotographType.BG: _listData = PhotographDataManager.Instance.listBgData; break; case EnumPhotographType.NPC: _listData = PhotographDataManager.Instance.listNpcData; break; case EnumPhotographType.SCENE: _listData = PhotographDataManager.Instance.listSceneData; break; case EnumPhotographType.BORDER: _listData = PhotographDataManager.Instance.listBorderData; break; case EnumPhotographType.EFFECT: _listData = PhotographDataManager.Instance.listEffectData; break; } _ui.m_ComSelectRes.m_list.numItems = _listData.Count; } private void RenderListItem(int index, GObject obj) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(_listData[index]); string resPath = ResPathUtil.GetIconPath(itemCfg); UI_ListItem item = UI_ListItem.Proxy(obj); item.target.data = _listData[index]; item.m_loaIcon.url = resPath; item.m_txtName.text = itemCfg.name; } private void OnListItemClick(EventContext context) { int itemID = (int)((context.data as GObject).data); EnumPhotographType type = (EnumPhotographType)_ui.m_ComSelectRes.m_comBtnTab.m_c1.selectedIndex; switch (type) { case EnumPhotographType.BG: case EnumPhotographType.BORDER: case EnumPhotographType.NPC: SceneController.UpdatePhotographBgOrNpcOrBorder(_sceneObject, type, itemID, maxLayer, out maxLayer); break; case EnumPhotographType.SCENE: PhotographDataManager.Instance.AddEquipItem(_equipSceneData, itemID, out _equipSceneData); SceneController.AddItemToScene(_sceneObject, itemID, _equipSceneData[itemID].Count - 1, maxLayer + 1); maxLayer++; break; case EnumPhotographType.EFFECT: break; } } /************************** **********************************场景*********************************************************/ private void OnTouchUIBegin(EventContext context) { context.CaptureTouch(); if (_ui.m_ComSelectRes.target.visible == true) return; if (Stage.inst.touchCount > 1 || context.inputEvent.touchId != 0 || isTwoTouchPoint) return;//只监听一根手指 if (isTouchUI) return; RaycastHit2D[] hit2Ds = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); if (hit2Ds.Length > 0) { maxLayer++; hitParentGameObj = SceneController.GetFirstHitObj(hit2Ds); _ui.m_comSelectBox.m_btnDelete.visible = true; if (hitParentGameObj.name == "Body")//主角不可删除 { _ui.m_comSelectBox.m_btnDelete.visible = false; } _ui.m_comSelectBox.target.visible = false; if (hitParentGameObj.name != "BgRes")//背景不可改动层级 { hitParentGameObj.GetComponent().sortingOrder = maxLayer; hitParentGameObj = hitParentGameObj.transform.parent.gameObject; _ui.m_comSelectBox.target.visible = true; } distance = Input.mousePosition - Camera.main.WorldToScreenPoint(hitParentGameObj.transform.position); if (_ui.m_comSelectBox.target.data == null || _ui.m_comSelectBox.target.data as GameObject != hitParentGameObj) { lastPos = Vector2.zero; _ui.m_comSelectBox.target.rotation = -hitParentGameObj.transform.eulerAngles.z; _ui.m_comSelectBox.target.size = SceneController.GetGameObjectSize(hitParentGameObj); } _ui.m_comSelectBox.target.data = hitParentGameObj; ControllerSelectBoxPos(); } } private void OnTouchUIMove(EventContext context) { if (hitParentGameObj == null) return;//未选中任何物体 if (Stage.inst.touchCount > 1 || context.inputEvent.touchId != 0 || isTwoTouchPoint) return; //只监听1根手指 if (isTouchUI) return; Debug.Log("拖动"); ControllerObjectPos(); ControllerSelectBoxPos(); } private void OnTouchUIEnd(EventContext context) { if (Stage.inst.touchCount > 1 || context.inputEvent.touchId != 0) return; //只监听1根手指 hitParentGameObj = null; if (Stage.inst.touchCount == 0) { isTwoTouchPoint = false; } } //选中物体的位置 private void ControllerObjectPos() { hitParentGameObj.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition - distance); if (hitParentGameObj.name == "BgRes") { Vector2 size = hitParentGameObj.GetComponent().size; Vector2 uiSize = _ui.target.size; float deviationWidth = (size.x - uiSize.x / 100) / 2; float deviationHeigh = (size.y - uiSize.y / 100) / 2; Vector2 pos = hitParentGameObj.transform.position; if (pos.x <= -deviationWidth) { hitParentGameObj.transform.position = new Vector2(-deviationWidth, hitParentGameObj.transform.position.y); } if (pos.x >= deviationWidth) { hitParentGameObj.transform.position = new Vector2(deviationWidth, hitParentGameObj.transform.position.y); } if (pos.y <= -deviationHeigh) { hitParentGameObj.transform.position = new Vector2(hitParentGameObj.transform.position.x, -deviationHeigh); } if (pos.y >= deviationHeigh) { hitParentGameObj.transform.position = new Vector2(hitParentGameObj.transform.position.x, deviationHeigh); } } } //选中框的位置 private void ControllerSelectBoxPos() { SceneController.SetGameObjectCenter(hitParentGameObj); //位置:角色、道具、npc全用对应父物体的位置 Vector2 objScreenPos = Camera.main.WorldToScreenPoint(hitParentGameObj.transform.position); Vector2 localPos = this.viewCom.GlobalToLocal(new Vector2(objScreenPos.x, (Screen.height - objScreenPos.y))); _ui.m_comSelectBox.target.position = localPos;//(localPos.x, localPos.y); } private void OnTouchBtnSizeBegin(EventContext context) { isTouchUI = true; GameObject gameObject = _ui.m_comSelectBox.target.data as GameObject; InputEvent inputEvent = (InputEvent)context.data; Vector2 screenPos = this.viewCom.GlobalToLocal(_ui.m_comSelectBox.m_btnSize.LocalToGlobal(Vector2.zero)); Vector2 pt = new Vector2(screenPos.x, screenPos.y); Vector2 pt1 = this.viewCom.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y)); Vector2 pt2 = new Vector2(_ui.m_comSelectBox.target.x, _ui.m_comSelectBox.target.y); Debug.Log("pt1" + pt1 + " pt2:" + pt2); if (!_equipDistance.ContainsKey(gameObject)) { float distance = Vector2.Distance(pt, pt2) / gameObject.transform.localScale.x; _equipDistance.Add(gameObject, distance); } _startDistance = _equipDistance[gameObject]; Debug.Log("_startDistance:" + _startDistance); } private void OnTouchBtnSizeMove(EventContext context) { GameObject gameObject = _ui.m_comSelectBox.target.data as GameObject; if (gameObject == null) return; InputEvent inputEvent = (InputEvent)context.data; Vector2 pt1 = this.viewCom.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y)); Vector2 pt2 = new Vector2(_ui.m_comSelectBox.target.x, _ui.m_comSelectBox.target.y); Vector2 curPos = pt1 - pt2; Debug.Log("pt1" + pt1 + " pt2:" + pt2 + " curPos:" + curPos + " lastPos:" + lastPos); float angle = Vector3.Angle(lastPos, curPos); //求出两向量之间的夹角 Vector3 normal = Vector3.Cross(lastPos, curPos);//叉乘求出法线向量 angle *= Mathf.Sign(Vector3.Dot(normal, Vector3.forward)); //Mathf.Sign()求符号,Vector3.Dot()求方向,求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 lastPos = curPos; ControllerRotate(angle, gameObject); Debug.Log("angle:" + angle); float dist = Vector2.Distance(pt1, pt2); Debug.Log("dist:" + dist); float ss = dist / _startDistance; float newValue = Mathf.Clamp(ss, 0.1f, 2); ControllerScale(newValue, gameObject); } private void OnTouchBtnSizeEnd(EventContext context) { isTouchUI = false; lastPos = Vector2.zero; } //双指缩放 private void OnPinch(EventContext context) { if (hitParentGameObj == null) return; if (hitParentGameObj.name == "BgRes") return;//背景不可以缩放、旋转 isTwoTouchPoint = true; GTween.Kill(hitParentGameObj); PinchGesture gesture = (PinchGesture)context.sender; float newValue = Mathf.Clamp(hitParentGameObj.transform.localScale.x + gesture.delta, 0.3f, 2); Debug.Log("双指缩放:" + newValue); ControllerScale(newValue, hitParentGameObj); } private void ControllerScale(float value, GameObject gameObject) { if (value > MaxScale || value < MinScale) return; gameObject.transform.localScale = new Vector3(value, value, value); Vector2 size = SceneController.GetGameObjectSize(gameObject); _ui.m_comSelectBox.target.SetSize(size.x, size.y); } private void OnRotate(EventContext context) { if (hitParentGameObj == null) return; if (hitParentGameObj.name == "BgRes") return;//背景不可以缩放、旋转 isTwoTouchPoint = true; GTween.Kill(hitParentGameObj.transform); RotationGesture gesture = (RotationGesture)context.sender; Debug.Log("双指旋转:" + gesture.delta); ControllerRotate(gesture.delta, hitParentGameObj); } private void ControllerRotate(float value, GameObject gameObject) { gameObject.transform.Rotate(Vector3.forward, -value, Space.World); _ui.m_comSelectBox.target.rotation += value; } //主角 private void UpdateBody() { SceneController.UpdatePhotographBody(_equipRoleData.ToArray(), _sceneObject, false, null, false, bodyParent); } //场景道具 private void UpdateScene() { ICollection keys = _equipSceneData.Keys; foreach (int key in keys) { for (int i = 0; i < _equipSceneData[key].Count; i++) { SceneController.AddItemToScene(_sceneObject, key, i); ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(key); PhotographDataManager.Instance.GetMaxLayer(maxLayer, false, itemCfg, out maxLayer); } } } //滤镜效果 private void UpdateEffect() { } private void DisposeEquipData() { for (int i = 0; i < equipDataCache.equipDatas.Length; i++) { ItemCfg itemCfg = ItemCfgArray.Instance.GetCfg(equipDataCache.equipDatas[i]); if (itemCfg.subType == ConstDressUpItemType.QIAN_JING || itemCfg.subType == ConstDressUpItemType.BEI_SHI || itemCfg.subType == ConstDressUpItemType.HUAN_JING) { PhotographDataManager.Instance.AddEquipItem(_equipSceneData, itemCfg.id, out _equipSceneData); } else { _equipRoleData.Add(equipDataCache.equipDatas[i]); } } } private void OnClickBtnBg() { _ui.m_ComSelectRes.target.visible = false; } private void OnClickBtnChoose() { _ui.m_ComSelectRes.target.visible = true; _ui.m_comSelectBox.target.visible = false; hitParentGameObj = null; } private void OnTouchBtnFlipBegin() { isTouchUI = true; Transform transform = (_ui.m_comSelectBox.target.data as GameObject).transform; for (int i = 0; i < transform.childCount; i++) { transform.GetChild(i).Rotate(Vector3.up, 180, Space.World); } } private void OnTouchBtnFlipEnd() { isTouchUI = false; } private void OnTouchBtnDeleteBegin() { isTouchUI = true; GameObject gameObject = _ui.m_comSelectBox.target.data as GameObject; if (gameObject.transform.gameObject == bodyParent) { return; } else if (gameObject.transform.gameObject == npcParent) { SpriteRenderer spriteRenderer = gameObject.transform.GetChild(0).GetComponent(); if (spriteRenderer != null) { GameObject.Destroy(spriteRenderer); } } else { GameObject.DestroyImmediate(gameObject); } _ui.m_comSelectBox.target.visible = false; } private void OnTouchBtnDeleteEnd() { isTouchUI = false; } private void OnClickBtnPhotograph() { _ui.target.visible = false; Timers.inst.StartCoroutine(ScreenShotTex());// (); } private IEnumerator ScreenShotTex() { _ui.target.visible = false; yield return new WaitForEndOfFrame(); Rect rect = new Rect(0, 0, UnityEngine.Screen.width, UnityEngine.Screen.height); Texture2D tex = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.ARGB32, false);//新建一个Texture2D对象 tex.ReadPixels(rect, 0, 0);//读取像素,屏幕左下角为0点 tex.Apply();//保存像素信息 ViewManager.Show(tex); _ui.target.visible = true; } private void OnClickBtnBack() { this.Hide(); // ViewManager.Show(ViewName.DRESS_UP_VIEW); EventAgent.DispatchEvent(ConstMessage.CLOSE_PHOTOGRAPHVIEW); } protected override void OnHide() { base.OnHide(); if (_sceneObject != null) { GameObject.Destroy(_sceneObject); _sceneObject = null; } equipDataCache = null; _equipRoleData.Clear(); _equipSceneData.Clear(); hitParentGameObj = null; pinchGesture.onAction.Remove(OnPinch); rotationGesture.onAction.Remove(OnRotate); pinchGesture = null; rotationGesture = null; } public override void Dispose() { if (_scenePrefab != null) { GameObject.Destroy(_scenePrefab); _scenePrefab = null; } base.Dispose(); } } }