// Start is called before the first frame update void Start() { floor = GetComponent <Transform>(); //object start position 最初の位置を初期化 objPositions[playerName] = new int[] { 0, 0 }; objPositions[startName] = new int[] { 0, 0 }; //フロアの長さ-1の大きさ、にゴールを配置 objPositions[goalName] = new int[] { dx - 1, dz - 1 }; objPositions[enemyName] = new int[] { Mathf.RoundToInt(dx / 2), Mathf.RoundToInt(dz / 2) }; //blocks ブロックの大きさをフロアーの長さからマスでわって決める blockPreb.GetComponent <Transform>().localScale = new Vector3(floor.localScale.x / dx, 1f, floor.localScale.z / dz); blocks = new Blocks(blockPreb, floor, dx, dz, "map"); blocks.Init(objPositions); // goal GameObject goal = GameObject.Find(goalName); goal.name = goalName; goal.GetComponent <Transform>().position = blocks.GetBlockPosition(objPositions[goalName][0], objPositions[goalName][1]); // walls // ブロックを置くときに壁が置かれてしまう 最後にscaleを代入し直して解決 Vector3 scale = blockPreb.GetComponent <Transform>().localScale; for (int angle = 0; angle < 360; angle += 90) // 90度ずつの角度をループ { // Mathf.Deg2Rad * angleは角度をラジアンになおしている float x = Mathf.Cos(Mathf.Deg2Rad * angle); float z = Mathf.Sin(Mathf.Deg2Rad * angle); blockPreb.GetComponent <Transform>().localScale = new Vector3( // Mathf.Cosとかはたまに1ちょうどにならないことがあるので10をかけて0,1の位を四捨五入しようとしている Mathf.RoundToInt(z * 10) == 0? 0.01f : floor.localScale.x, scale.y, Mathf.RoundToInt(x * 10) == 0? 0.01f : floor.localScale.z ); // 座標の計算 float px = x * floor.localScale.x / 2f; float pz = z * floor.localScale.z / 2f; float py = floor.localScale.y / 2f + floor.position.y + scale.y / 2f; Instantiate(blockPreb, new Vector3(px, py, pz), Quaternion.identity); } blockPreb.GetComponent <Transform>().localScale = scale; // player, enemy new string[] { playerName, enemyName }.Select((v, i) => new { v, i }).All( item => { GameObject obj = Instantiate(playerPrefab); obj.name = item.v; Transform transform = obj.GetComponent <Transform>(); Vector3 p = blocks.GetBlockPosition(objPositions[item.v][0], objPositions[item.v][1]); p.y = floor.localScale.y / 2f + floor.position.y + transform.localScale.y * transform.Find("Body").localScale.y / 2f; transform.position = p; PlayerCellController ctrl = obj.GetComponent <PlayerCellController>(); if (item.v == playerName) { player = obj; ctrl.AutoMovingSpan = 0f; // 引数なしのラムダ式がよくわかってない↓ ctrl.AddTriggerAction(goalName, () => { ctrl.CancelMotions(); dlg.DoModal(name => {}, timer.ToString("0.0")); timer = 0.0f; // 最初のスタート位置に戻る transform.position = blocks.GetBlockPosition(objPositions[startName][0], objPositions[startName][1]); transform.localRotation = Quaternion.identity; audio_source_effects.PlayOneShot(audio_goal); }); ctrl.AddTriggerAction(enemyName, () => { timer += 5.0f; if (timerColor != null) { StopCoroutine(timerColor); } timerColor = StartCoroutine(TimerColor(Color.red, Color.black, 5.0f)); audio_source_effects.PlayOneShot(audio_damage); }); } else if (item.v == enemyName) { ctrl.AutoMovingSpan = 2f; ctrl.SetColor(new Color32(165, 35, 86, 255)); ctrl.SetLayer(LayerMask.NameToLayer("Ignore Raycast")); ctrl.TrackingObject = player.GetComponent <Transform>(); } return(true); } ); birdEye = GameObject.FindWithTag("MainCamera").GetComponent <Camera>(); birdEye.enabled = false; playersEye = player.GetComponent <Transform>().Find("Camera").GetComponent <Camera>(); playersEye.enabled = true; SetPlayerActionType(); if (start_bird_view == true) { ChangeCamera(); } timerText = GameObject.Find("TimerText"); dlg = GameObject.Find("Canvas").GetComponent <ModalDialog>(); audio_source_effects = gameObject.AddComponent <AudioSource>(); audio_source_effects.volume = volume_effects; audio_source_bgm = gameObject.AddComponent <AudioSource>(); audio_source_bgm.loop = true; audio_source_bgm.volume = volume_bgm; audio_bgms = new Dictionary <string, AudioClip>() { { "Default", audio_bgm }, { "Bird", audio_bird }, { "Navi", audio_navi }, { "Warning", audio_warning }, { "Distance", audio_distance }, }; BGM("Default"); routeRenderer = gameObject.AddComponent <RouteRenderer>(); // ゴールまでの位置の表示 // 全てのブロックのセルに対して処理を行っていく blocks.All((x, y) => { GameObject o = Instantiate(textPrefab, blocks.GetBlockPosition(x, y), Quaternion.Euler(90, 0, 0)); o.GetComponent <TextMesh>().text = Mathf.Sqrt(Mathf.Pow(objPositions[goalName][0] - x, 2) + Mathf.Pow(objPositions[goalName][1] - y, 2)).ToString("0.0"); o.SetActive(false); distances.Add(o); return(true); }); items = new Dictionary <ItemNames, Item>() { //Itemの引数 実行時間と行うアクションと終わったあとのアクションを引数として渡している { ItemNames.Bird, new Item( // 5fはどこに行っているのだろうか →おそらくスタートのところに入っている 5f, () => { BGM("Bird"); ChangeCamera(); }, () => { BGM("Default"); ChangeCamera(); } ) }, { ItemNames.BreakWall, new Item( 0f, () => { if (toBreakBlockXZ[0] != -1) { audio_source_effects.PlayOneShot(audio_break); //falseはゲーム内に保存するオプション blocks.RemoveBlock(toBreakBlockXZ[0], toBreakBlockXZ[1], false); reRoute = true; } }, () => { } ) }, { ItemNames.Distance, new Item( 5f, () => { BGM("Distance"); distances.ForEach(o => o.SetActive(true)); }, () => { BGM("Default"); distances.ForEach(o => o.SetActive(false)); } ) }, { ItemNames.Navi, new Item( 5f, () => { BGM("Navi"); reRoute = true; }, () => { BGM("Default"); routeRenderer.clear(); }, () => { if (reRoute) { reRoute = false; List <int> route = blocks.Solve(blocks.xz2i(objPositions[playerName]), blocks.xz2i(objPositions[goalName])); routeRenderer.Render(route, i => blocks.GetBlockPosition(i)); } } ) }, }; }
// Update is called once per frame void Update() { if (dlg.Active == true) { return; } if (TrackingObject != null) { float camera_angle = 90f; float toCheckDistance = 6f; ViewRader(camera_angle, toCheckDistance, GetComponent <Transform>().position); int index = Search(camera_angle, toCheckDistance, GetComponent <Transform>().position, TrackingObject); // Debug.Log(index); // エネミーに見つかっていないときの処理 if (index == -1) { if (floor.BGM() == "Warning") { floor.BGM("Default"); } TrackingObject.GetComponent <PlayerCellController>().SetColor(); // 自作 // autoMovingSpeed = 1.0f; } // エネミーに見つかっているときの処理 else { floor.BGM("Warning"); TrackingObject.GetComponent <PlayerCellController>().SetColor(new Color32(255, 0, 255, TrackingObject.GetComponent <PlayerCellController>().defaultColor.a)); autoMovingSpeed = 5.0f; // 初めて相手を見つけたときまたは見つけた相手が動いたとき(index番号が変わったとき) if (nextNavigation.Count == 0 || nextNavigation[nextNavigation.Count - 1] != index) { pmotion.Cancel(); // 一個前に自動移動した時間autoMovedTime autoMovedTime = Time.realtimeSinceStartup - AutoMovingSpan; //プレイヤーのいち List <int> route = floor.blocks.Solve(floor.blocks.GetBlockIndex(GetComponent <Transform>().position), index); nextNavigation.Clear(); for (int cnt = 1; cnt < route.Count; cnt++) { nextNavigation.Add(route[cnt]); } routeRenderer.Render(route, i => floor.blocks.GetBlockPosition(i), Color.red); } } } // Playerの条件分岐 if (AutoMovingSpan == 0) { foreach (var elem in actions) { if (Input.GetKeyDown(elem.Key)) { Move(elem.Value); } } } // エネミーの条件分岐 else if (Time.realtimeSinceStartup > autoMovedTime + AutoMovingSpan / autoMovingSpeed) { autoMovedTime = Time.realtimeSinceStartup; pmotion.Unset(); int[] pos = floor.blocks.GetBlockIndexXZ(GetComponent <Transform>().position); bool moved = false; while (nextNavigation.Count > 0) { int next = nextNavigation[0]; int x = floor.blocks.i2x(next); int z = floor.blocks.i2z(next); if (x - pos[0] != 0 || z - pos[1] != 0) { Move(new int[] { x - pos[0], z - pos[1], 0, 1 }, () => { nextNavigation.RemoveAt(0); if (nextNavigation.Count == 0) { autoMovingSpeed = 1.0f; routeRenderer.clear(); // Clearが効かない // routeRenderer.Clear(); } }); moved = true; break; } else { nextNavigation.RemoveAt(0); } } // movedがfalseだった場合は自動運転(ランダム)に切り替える if (moved == false) { List <string> avail = new List <string>(); // 動ける範囲があるか探す処理 foreach (var d in nextPosition) { if (floor.blocks.IsWall(pos[0] + d.Value[0], pos[1] + d.Value[1]) == false) { avail.Add(d.Key); } } if (avail.Count != 0) { Move(nextPosition[avail[UnityEngine.Random.Range(0, avail.Count)]]); } } } // めちゃくちゃ大事な処理 // 動いたあとの場所をしゅとくする // gameObject.nameが何の名前なのかを調べる floor.UpdateObjectPosition(gameObject.name, GetComponent <Transform>().position, GetComponent <Transform>().rotation); }