///<summary> チップを非アクティブにする処理 </summary> private void DisactiveChipUI(ChipUI chip) { RemoveAll(chip); chip.Disactive(); if (chip.Name == Lobot.ChipName.GAIN) { num_gain_chip--; if (num_gain_chip < 0) { num_gain_chip = 0; } } if (onDisactiveChipUI != null) { onDisactiveChipUI(chip); } int index = -1; for (int ind = 0; ind < useChips.Count; ind++) { if (chip == useChips[ind]) { index = ind; break; } } if (index != -1) { useChips.RemoveAt(index); } }
///<summary> 使用中チップリストから削除する </summary> private void RemoveChipUI(ChipUI chip) { if (useChips.Contains(chip)) { useChips.Remove(chip); } }
///<summary> 操作範囲を超えているかどうか判定する。 </summary> private bool CheckLimitOver(ChipUI chip) { float x_min = LIMIT_UI_SPACE["min x"]; float y_min = LIMIT_UI_SPACE["min y"]; float x_max = LIMIT_UI_SPACE["max x"]; float y_max = LIMIT_UI_SPACE["max y"]; ChipUI.Corner corner = chip.GetCorner(); // 4辺の接触判定 Vector2[] checks = new Vector2[8] { new Vector2(x_min, corner.top.y), new Vector2(x_min, corner.bottom.y), new Vector2(corner.top.x, y_min), new Vector2(corner.bottom.x, y_min), new Vector2(x_max, corner.top.y), new Vector2(x_max, corner.bottom.y), new Vector2(corner.top.x, y_max), new Vector2(corner.bottom.x, y_max) }; // どこかの座標が入っていたら、範囲を超えている。 foreach (Vector2 check in checks) { if (chip.CheckOnPoint(check)) { return(true); } } return(false); }
///<summary> 回路全体をコンパイル </summary> private Circuit CircuitCompile(ChipUI root) { Circuit ret = new Circuit(); // cpuの接続上限だけを参照 for (int i = 0; i < LimitConnect.Get(ChipName.CPU); i++) { var temp = root.next_list[i]; if (temp != null) { ret.Root.next[i] = NextAttach(temp); } } //Debug foreach (var node in ret.Root.next) { if (node == null) { continue; } } return(ret); }
///<summary> 全てを解除する </summary> public void RemoveAll(ChipUI from) { for (int index = 0; index < from.next_list.Count; index++) { Remove(from.next_list[index], from); } }
private Vector3[] CalcLinkedUIPos(ChipUI new_chip, ChipUI pre_chip) { Vector3 pos_new = new_chip.transform.position; Vector3 pos_pre = pre_chip.transform.position; Vector3 direction = CalcSettingDirection(pos_new, pos_pre); return(new Vector3[] { (pos_new + pos_pre) / 2, direction }); }
/// <summary> リンクUIを表示 </summary> public void ShowLinked(ChipUI new_chip, Vector3[] info) { if (info[1].x == 0) { new_chip.ShowLinkedHorizontal(info[0]); } else if (info[1].y == 0) { new_chip.ShowLinkedVertical(info[0]); } }
///<summary> 切断する </summary> public void Disconnect(ChipUI chip) { int index = -1; for (int i = 0; i < next_list.Count; i++) { if (next_list[i] == chip) { index = 1; break; } } Disconnect(index); }
///<summary> 非アクティブ化 </summary> public void Disactive() { FreezePos(); AllDisactiveLinkedUI(); if (parent != null) { Debug.Log("disconnect"); parent.Disconnect(connect_index); } parent = null; connect_index = -1; numConnect = 0; next_list.Clear(); gameObject.SetActive(false); }
///<summary> 起動毎の初期化 </summary> public void Init() { AllDisactiveLinkedUI(); next_list.Clear(); connect_limit = Lobot.LimitConnect.Get(name); for (int i = 0; i < connect_limit; i++) { next_list.Add(null); } numConnect = 0; parent = null; connect_index = -1; line_index = -1; }
///<summary> ChipUIオブジェクトをドラッグ状態にする。 </summary> private void SetDrag(ChipUI chip) { if (chip == null) { return; } // ドラッグモードに変更 chip.ActivateChase(); now_drag = chip; chip.SetScale(ChipUI.STANDARD_DRAG_SCALE); if (onDrag != null) { onDrag(chip); } RemoveChipUI(chip); HideChipConfig(); }
///<summary> 引数のチップから最も近いチップを探索する。 </summary> private ChipUI FindNearestChipUI(ChipUI chip) { Vector3 pos = chip.transform.position; float min_distance = float.PositiveInfinity; ChipUI ret = null; foreach (var use_chip in useChips) { if (use_chip.CheckHit(chip)) { float temp_distance = Vector3.Distance(use_chip.transform.position, pos); if (temp_distance < min_distance) { min_distance = temp_distance; ret = use_chip; } } } return(ret); }
///<summary> 解除する </summary> public void Remove(ChipUI target, ChipUI from) { int index = -1; for (int i = 0; i < from.next_list.Count; i++) { if (target == from.next_list[i]) { index = i; break; } } if (index == -1) { return; } if (from.next_list[index] != null) { DisactiveChipUI(from.next_list[index]); } from.next_list[index] = null; }
///<summary> ChipUIを左クリックした時の処理を追加する。</summary> private void SetLeftClickActionToChipUI(ChipUI chip) { // EventTriggerがアタッチされていないなら終了 EventTrigger trigger = chip.Trigger; if (trigger == null) { return; } Vector3 pos = chip.transform.position; EventTrigger.Entry press = new EventTrigger.Entry(); press.eventID = EventTriggerType.PointerDown; press.callback.AddListener((data) => { Debug.Log("on click chip ui"); // 左クリック // ドラッグ状態に変更 if (InputManager.CheckMouseLeft().isTouch) { Debug.Log("left click"); SetDrag(chip); } // 右クリック // コンフィグを表示 else if (InputManager.CheckMouseRight().isTouch) { Debug.Log("right click"); chip_config.SetActive(true); } }); trigger.triggers.Add(press); }
///<summary> あとに続くノードを全て追加したノードを返す。 </summary> private Node NextAttach(ChipUI chip) { // Chipインスタンスを作成して、追加 var instance = ChipFactory.GetInstance(chip.Name); if (chip.Name == ChipName.COLOR) { instance.colorType = chip.nowColor; } else if (chip.Name == ChipName.SOUND) { instance.soundType = chip.nowSound; } Node ret = new Node(instance); // nextをnullでうめる ret.next.Clear(); for (int i = 0; i < LimitConnect.Get(chip.Name); i++) { ret.next.Add(null); } // nextを全て参照して次に続くNodeを追加 for (int i = 0; i < LimitConnect.Get(chip.Name); i++) { // 次を参照して、挿入 var temp = chip.next_list[i]; if (temp != null) { ret.next[i] = NextAttach(temp); } } return(ret); }
///<summary> 接続する </summary> public bool Connect(ChipUI chip, int index) { if (!IsConnectable) { return(false); } if (index >= next_list.Count) { return(false); } if (index >= connect_limit) { return(false); } if (next_list[index] == null) { if (isCPU) { chip.lineIndex = index; } else { chip.lineIndex = lineIndex; } next_list[index] = chip; chip.parent = this; numConnect++; chip.connect_index = index; return(true); } return(false); }
///<summary> 他のChipUIと接触しているかどうか </summary> public bool CheckHit(ChipUI chip) { Corner _corner_chip = chip.GetCorner(); Corner _corner_this = this.GetCorner(); // それぞれの大きさを計算する float size_chip = Vector2.Distance(_corner_chip.top, _corner_chip.bottom); float size_this = Vector2.Distance(_corner_this.top, _corner_this.bottom); // サイズが小さい方の頂点が大きい方の範囲内に入っていることを判定すればよい。 bool is_check_this = true; // thisの方が小さい場合 if (size_chip > size_this) { is_check_this = false; // chipの方が小さい場合 } // this側が小さい時の判定 if (is_check_this) { // this側のチェックで判定する座標群 Vector2[] this_check = new Vector2[4] { _corner_chip.top, new Vector2(_corner_chip.top.x, _corner_chip.bottom.y), _corner_chip.bottom, new Vector2(_corner_chip.bottom.x, _corner_chip.top.y) }; // this側のあたり判定 foreach (Vector2 check in this_check) { if (this.CheckOnPoint(check)) { return(true); } } } // chip側が小さい時の判定 else { // chip側のチェックで判定する座標群 Vector2[] chip_check = new Vector2[4] { _corner_this.top, new Vector2(_corner_this.top.x, _corner_this.bottom.y), _corner_this.bottom, new Vector2(_corner_this.bottom.x, _corner_this.top.y) }; // chip側のあたり判定 foreach (Vector2 check in chip_check) { if (chip.CheckOnPoint(check)) { return(true); } } } // 全てのチェックを通過したら、接触していない return(false); }
// Start is called before the first frame update void Start() { chipui_obj = new GameObject("ChipUIs"); chipui_obj.transform.parent = transform; // chipの詳細設定メニュー config_delete = chip_config.transform.GetChild(0).GetComponent <Button>(); config_delete.onClick.AddListener(() => { HideChipConfig(); now_selected = null; }); config_red = chip_config.transform.GetChild(1).GetComponent <Button>(); config_red.onClick.AddListener(() => { now_selected.ChangeMode(Map.ColorType.RED); }); config_blue = chip_config.transform.GetChild(2).GetComponent <Button>(); config_blue.onClick.AddListener(() => { now_selected.ChangeMode(Map.ColorType.BLUE); }); config_green = chip_config.transform.GetChild(3).GetComponent <Button>(); config_green.onClick.AddListener(() => { now_selected.ChangeMode(Map.ColorType.GREEN); }); config_yellow = chip_config.transform.GetChild(4).GetComponent <Button>(); config_yellow.onClick.AddListener(() => { now_selected.ChangeMode(Map.ColorType.YELLOW); }); // ChipUIを生成するボタンの登録 SetClickDown(UpChipButton, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_UP_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(RightChipButton, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_RIGHT_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(LeftChipButton, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_LEFT_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(DownChipButton, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_DOWN_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(sound_chip_button, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_SOUND_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(color_chip_button, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_COLOR_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); SetClickDown(gain_chip_button, (data) => { // 左クリックで押していないなら何もしない if (!InputManager.CheckMouseLeft().isTouch) { return; } if (now_drag != null) { return; } var temp = factory.GetObject(EditCircuitManager.NAME_GAIN_CHIP, InputManager.MousePosOnWorld(-3), chipui_obj.transform); SetDrag(temp.GetComponent <ChipUI>()); }); // マップボタンを押したら大きなマップを表示する。 map_button.onClick.AddListener(() => { DisplayMap(true); }); // ゲームスタートボタンでシーンをゲームに変更する様にする。 game_start_button.onClick.AddListener(() => { if (num_gain_chip <= 0) { error_dialog.SetActive(true); return; } // CPUチップをルートにして、コンパイル Compile(useChips[0]); // ゲームシーンに移動 onChangeGameScene(); }); // CPUChipをセンター配置 var temp = factory.GetObject(EditCircuitManager.NAME_CPU_CHIP, EditCircuitUI.CPU_STANDARD_POSITION, chipui_obj.transform); var script = temp.GetComponent <ChipUI>(); useChips.Add(script); }
///<summary> チップを離した時の処理 </summary> private void DropChip(Vector3 pos) { // サイズを固定用に変更して、固定モードにする。 now_drag.SetScale(ChipUI.STANDARD_SCALE); // ドロップした座標を設定 now_drag.SetPosition3D(pos); // 最も近いチップを参照する。 ChipUI nearest = FindNearestChipUI(now_drag); // 最も近いチップが接続できないなら、終了 if (nearest == null || (!nearest.IsConnectable)) { DisactiveChipUI(now_drag); // なんであれドラッグ状態は解除する。 now_drag = null; return; } // 接触したチップが存在しないなら、終了 if (nearest == null) { DisactiveChipUI(now_drag); // なんであれドラッグ状態は解除する。 now_drag = null; return; } // 最も適した設置方向を計算する。 Vector3 set_pos = CalcSettingPos( now_drag.transform.position, nearest.transform.position ); // 内部でドラッグ状態が解除されているなら、終了 if (now_drag == null) { return; } now_drag.SetPosition3D(set_pos); // UI範囲を超えているなら、非アクティブにして終了。 if (CheckLimitOver(now_drag)) { // 画面外なので非アクティブ DisactiveChipUI(now_drag); // なんであれドラッグ状態は解除する。 now_drag = null; return; } // 全く同じ場所にチップが既にあるなら終了 foreach (ChipUI use in useChips) { if (Vector3.Equals(use.transform.position, now_drag.transform.position)) { // 画面外なので非アクティブ DisactiveChipUI(now_drag); // なんであれドラッグ状態は解除する。 now_drag = null; return; } } // 再接続の可能性を考慮 if (now_drag.parent != null) { now_drag.parent.Disconnect(now_drag.connect_index); RemoveAll(now_drag); now_drag.Init(); } // 位置を固定 now_drag.FreezePos(); // 使用中チップ配列に登録 useChips.Add(now_drag); // 接続UIを表示 Vector3[] linked_info = CalcLinkedUIPos(now_drag, nearest); // ChipUIを内部的に接続状態にする int index = 0; if (nearest.isCPU) { Vector3 direction = now_drag.transform.position - nearest.transform.position; if (direction.x == 0) { if (direction.y < 0) { index = 2; } else { index = 0; } } else if (direction.y == 0) { if (direction.x < 0) { index = 3; } else { index = 1; } } } // 接続に失敗したら終了 if (!nearest.Connect(now_drag, index)) { DisactiveChipUI(now_drag); // なんであれドラッグ状態は解除する。 now_drag = null; return; } ShowLinked(now_drag, linked_info); if (now_drag.Name == Lobot.ChipName.GAIN) { num_gain_chip++; } now_drag = null; }
// Update is called once per frame void Update() { // チュートリアルモードだったら、Updateを処理しない if (TutorialMode) { return; } // マップ画像が表示されている時の処理 is_erase_frame_lerge_map = false; if (learge_map_image.activeSelf) { if (InputManager.CheckMouseLeftDown().isTouch) { learge_map_image.SetActive(false); is_erase_frame_lerge_map = true; } return; } //エラーダイアログを表示しているときの処理 if (error_dialog.activeSelf) { if (InputManager.CheckMouseLeftDown().isTouch) { error_dialog.SetActive(false); } } if (now_drag != null) { // 左クリックを離したら、その場所で固定する。 RetMouse ret = InputManager.CheckMouseLeftUp(); if (ret.isTouch) { DropChip(ret.mousePos); } else { now_drag.SetPosition3D(InputManager.MousePosOnWorld(-3)); } return; } if (now_selected == null) { ChipUI left_click_chip = GetChipOnLeftMouseClick(); if (left_click_chip != null) { if (!left_click_chip.isCPU) { SetDrag(left_click_chip); } return; } } else { bool is_hide = false; var click_info = InputManager.CheckMouseLeftDown(true); if (click_info.isTouch) { List <RaycastResult> results = new List <RaycastResult>(); // マウスポインタの位置にレイ飛ばし、ヒットしたものを保存 // ポインタ(マウス/タッチ)イベントに関連するイベントの情報 var pointer = new PointerEventData(EventSystem.current); pointer.position = click_info.mousePos; EventSystem.current.RaycastAll(pointer, results); // ヒットしたUIの名前 is_hide = results.Count == 0; } if (is_hide) { HideChipConfig(); now_selected = null; return; } } ChipUI right_click_chip = GetChipOnRightMouseClick(); if (right_click_chip != null) { if (!right_click_chip.isCPU) { now_selected = right_click_chip; ShowChipConfig(right_click_chip.transform.position); } return; } }