public void add_new_ball(GameObject ball) { var bu = new BallUnit(ball); update_hit_pos(bu); Debug.Log("New ball discovered: " + bu.rb.position.ToString()); Debug.Log(System.String.Format("hit_pos={0}, hit_time={1}, leave_time={2}", bu.hit_pos, bu.hit_time, bu.leave_time)); if (bu.hit_time < 0) { return; } if (ball.GetComponent <Ball>().player_id == player_id) { attack_queue.Add(bu); attack_queue.Sort((x, y) => x.hit_time.CompareTo(y.hit_time)); } else { defence_queue.Add(bu); defence_queue.Sort((x, y) => x.hit_time.CompareTo(y.hit_time)); // A heap would be better } last_refresh_time = Time.time; }
private void update_hit_pos(BallUnit bu) { if (bu.ball.gameObject == null) { bu.leave_time = -1; return; } var v = bu.rb.velocity; var pos = bu.rb.position; var t = (Mathf.Abs(board_y - pos.y)) / Mathf.Abs(v.y); var wall_width = wall_x * 2 - ball_r * 2; var raw_x = wall_width / 2 + pos.x + t * v.x; var n = Mathf.Floor(raw_x / wall_width); bu.hit_time = (Mathf.Abs(board_y - pos.y) - ball_r) / Mathf.Abs(v.y); bu.leave_time = (Mathf.Abs(board_y - pos.y) + board_thick + ball_r) / Mathf.Abs(v.y); if (n % 2 == 0) { bu.hit_pos = raw_x - n * wall_width - wall_width / 2; } else { bu.hit_pos = wall_width / 2 - (raw_x - n * wall_width); } var r_ext = ball_r * Mathf.Abs(v.magnitude / v.y); var b_ext = (board_thick) * Mathf.Abs(v.x / v.y); bu.hit_ext = new float[2] { r_ext + (v.x < 0 ? b_ext : 0), r_ext + (v.x > 0 ? b_ext : 0) }; }