/// <summary> /// 오브젝트에 이벤트를 바인딩하는 함수. /// 오브젝트와 항목 선택 상태에 따라 클릭 시 선택/취소 되거나, 재질이 적용되도록 함. /// sliding door의 경우 애니메이션을 위해 문짝 모델을 분리하여 별도의 클릭 이벤트를 바인딩 해줌. /// no door의 경우 이벤트 바인딩을 하는 대신에 /// 재질 적용릉 위해 벽지/천장/바닥 부분을 땜빵하는 Quad 모델을 Probuilder로 다시 생성함. /// 이때 다시 생성된 mesh들은 nodoor mesh 부모 오브젝트 아래로 들어가서 벽지 또는 바닥재가 적용될 수 있도록 바인딩한다. /// </summary> /// <param name="item">바인딩 대상 오브젝트</param> /// <param name="type">오브젝트 타입</param> private void BindItem(Transform item, DecorateType type) { if (type == DecorateType.None) { type = FindType(item); } GameObject itemObject = (type == DecorateType.Furniture ? item.parent.gameObject : item.gameObject); #region for door Transform d = null; float dir = 0; Vector3 angle = Vector3.zero; Vector3 localPosition = Vector3.zero; // Sliding Door용 X좌표. float defaultX = 0; float defaultY = 0; bool isMoving = false; bool isOpen = false; float startPos = 0, endPos = 0; float animationTime = 0.5f; float currentTime = 0; if (type == DecorateType.Door) { if (type == DecorateType.Door && item.name == "NoDoor(Clone)") { GameObject mesh; float area; mesh = MakeMesh.MakeQuad(item.GetChild(0).Find("WallL").gameObject, model.Floor.DefaultFloorMaterial, out area); mesh.transform.parent = nodoorMeshParent; nodoorMeshs.Add(mesh, area); mesh = MakeMesh.MakeQuad(item.GetChild(0).Find("WallR").gameObject, model.Floor.DefaultFloorMaterial, out area); mesh.transform.parent = nodoorMeshParent; nodoorMeshs.Add(mesh, area); mesh = MakeMesh.MakeQuad(item.GetChild(0).Find("Floor").gameObject, model.Floor.DefaultFloorMaterial, out area); mesh.transform.parent = nodoorMeshParent; nodoorMeshs.Add(mesh, area); mesh = MakeMesh.MakeQuad(item.GetChild(0).Find("Ceiling").gameObject, model.Floor.DefaultFloorMaterial, out area); mesh.transform.parent = nodoorMeshParent; nodoorMeshs.Add(mesh, area); return; } // 애니메이션과 클릭 이벤트가 적용될 문짝 오브젝트 d = item.GetChild(0).GetChild(0); d.parent = item.transform; dir = item.GetChild(0).localScale.x > 0 ? 1 : -1; angle = d.eulerAngles; localPosition = d.localPosition; defaultX = localPosition.x; defaultY = angle.y; item.UpdateAsObservable() .Where(condition => isMoving) .Subscribe(_ => { if (currentTime > animationTime) { isMoving = false; currentTime = 0; } else { currentTime += Time.deltaTime; angle.y = Mathf.Lerp(startPos, endPos, currentTime / animationTime); d.eulerAngles = angle; } }); Destroy(item.GetComponent <BoxCollider>()); item = item.GetComponentInChildren <MeshCollider>().transform; } #endregion // 오브젝트 클릭시 if (item.GetComponent <Collider>() == null) { item.gameObject.AddComponent <MeshCollider>(); } item.OnMouseDownAsObservable() .Where(_ => !EventSystem.current.IsPointerOverGameObject()) .Subscribe(_ => { if (selectedObject == null || selectedObject != itemObject) { // 처음 클릭시 if (!selectable) { return; } else { Select(itemObject, type); } } else if (selectedObject == itemObject) { // 두번째 클릭시 switch (type) { case DecorateType.Furniture: if (!selectable) { SetFurniture(); } else { Cancel(); } break; case DecorateType.Door: // 문 열기/닫기 isMoving = true; if (!isOpen) { isOpen = true; if (item.parent.name == "SwingDoor(Clone)") { startPos = defaultY; endPos = defaultY + 90 * dir; } } else { isOpen = false; if (item.parent.name == "SwingDoor(Clone)") { startPos = defaultY + 90 * dir; endPos = defaultY; } } break; default: if (!selectable) { return; } // 다른 경우에는 선택취소 Cancel(); break; } } }).AddTo(this); }