void Awake() { model = NotesEditorModel.Instance; rectTransform = GetComponent <RectTransform>(); rectTransform.localPosition = model.NoteToScreenPosition(notePosition); var image = GetComponent <Image>(); noteType.DistinctUntilChanged() .Select(type => type == NoteTypes.Long) .Subscribe(isLongNote => image.color = isLongNote ? Color.cyan : new Color(175 / 255f, 1, 78 / 255f)); this.UpdateAsObservable() .Select(_ => model.NoteToScreenPosition(notePosition)) .DistinctUntilChanged() .Subscribe(pos => rectTransform.localPosition = pos); var mouseDownObservable = onMouseDownObservable .Where(_ => model.ClosestNotePosition.Value.Equals(notePosition)); var editObservable = mouseDownObservable .Where(editType => editType == NoteTypes.Normal) .Where(editType => noteType.Value == editType) .Merge(mouseDownObservable .Where(editType => editType == NoteTypes.Long)); editObservable.Where(editType => editType == NoteTypes.Normal) .Subscribe(_ => model.NormalNoteObservable.OnNext(notePosition)); editObservable.Where(editType => editType == NoteTypes.Long) .Subscribe(_ => model.LongNoteObservable.OnNext(notePosition)); var longNoteLateUpdateObservable = this.LateUpdateAsObservable() .Where(_ => noteType.Value == NoteTypes.Long); longNoteLateUpdateObservable .Where(_ => next != null) .Select(_ => model.NoteToScreenPosition(next.notePosition)) .Merge(longNoteLateUpdateObservable .Where(_ => next == null) .Where(_ => model.EditType.Value == NoteTypes.Long) .Where(_ => model.LongNoteTailPosition.Value.Equals(notePosition)) .Select(_ => model.ScreenToCanvasPosition(Input.mousePosition))) .Select(nextPosition => new Line[] { new Line(model.NoteToScreenPosition(notePosition), nextPosition, 0 < nextPosition.x - model.NoteToScreenPosition(notePosition).x ? Color.cyan : Color.red) }) .Subscribe(lines => GLLineRenderer.RenderLines(notePosition.ToString(), lines)); }
void Awake() { model = NotesEditorModel.Instance; rectTransform = GetComponent<RectTransform>(); rectTransform.localPosition = model.NoteToScreenPosition(notePosition); var image = GetComponent<Image>(); noteType.DistinctUntilChanged() .Select(type => type == NoteTypes.Long) .Subscribe(isLongNote => image.color = isLongNote ? Color.cyan : new Color(175 / 255f, 1, 78 / 255f)); this.UpdateAsObservable() .Select(_ => model.NoteToScreenPosition(notePosition)) .DistinctUntilChanged() .Subscribe(pos => rectTransform.localPosition = pos); var mouseDownObservable = onMouseDownObservable .Where(_ => model.ClosestNotePosition.Value.Equals(notePosition)); var editObservable = mouseDownObservable .Where(editType => editType == NoteTypes.Normal) .Where(editType => noteType.Value == editType) .Merge(mouseDownObservable .Where(editType => editType == NoteTypes.Long)); editObservable.Where(editType => editType == NoteTypes.Normal) .Subscribe(_ => model.NormalNoteObservable.OnNext(notePosition)); editObservable.Where(editType => editType == NoteTypes.Long) .Subscribe(_ => model.LongNoteObservable.OnNext(notePosition)); var longNoteLateUpdateObservable = this.LateUpdateAsObservable() .Where(_ => noteType.Value == NoteTypes.Long); longNoteLateUpdateObservable .Where(_ => next != null) .Select(_ => model.NoteToScreenPosition(next.notePosition)) .Merge(longNoteLateUpdateObservable .Where(_ => next == null) .Where(_ => model.EditType.Value == NoteTypes.Long) .Where(_ => model.LongNoteTailPosition.Value.Equals(notePosition)) .Select(_ => model.ScreenToCanvasPosition(Input.mousePosition))) .Select(nextPosition => new Line[] { new Line(model.NoteToScreenPosition(notePosition), nextPosition, 0 < nextPosition.x - model.NoteToScreenPosition(notePosition).x ? Color.cyan : Color.red) }) .Subscribe(lines => GLLineRenderer.RenderLines(notePosition.ToString(), lines)); }
void LateUpdate() { if (model.Audio == null || model.Audio.clip == null) { return; } var beatNum = model.LPB.Value * Mathf.CeilToInt(model.Audio.clip.samples / (float)model.UnitBeatSamples.Value); var beatSamples = Enumerable.Range(0, beatNum) .Select(i => i * model.UnitBeatSamples.Value / model.LPB.Value) .ToArray(); var beatLines = beatSamples .Select(x => model.SamplesToScreenPositionX(x)) .Select((x, i) => new Line( new Vector3(x, 140, 0), new Vector3(x, -140, 0), i % model.LPB.Value == 0 ? Color.white : Color.white / 2)) .ToArray(); var blockLines = Enumerable.Range(0, 5) .Select(i => model.BlockNumToScreenPositionY(i)) .Select(i => i + Screen.height * 0.5f) .Select((y, i) => new Line( model.ScreenToCanvasPosition(new Vector3(0, y, 0)), model.ScreenToCanvasPosition(new Vector3(Screen.width, y, 0)), Color.white / 2f)) .ToArray(); // Highlighting closest line to mouse pointer if (model.IsMouseOverCanvas.Value) { var highlightColor = new Color(253 / 255f, 230 / 255f, 3 / 255f) * 0.8f; var mouseX = model.ScreenToCanvasPosition(Input.mousePosition).x; var closestLineIndex = GetClosestLineIndex(beatLines, c => Mathf.Abs(c.start.x - mouseX)); var closestBeatLine = beatLines[closestLineIndex]; var mouseY = model.ScreenToCanvasPosition(Input.mousePosition).y; var closestBlockLindex = GetClosestLineIndex(blockLines, c => Mathf.Abs(c.start.y - mouseY)); var closestBlockLine = blockLines[closestBlockLindex]; var distance = Vector2.Distance( new Vector2(closestBeatLine.start.x, closestBlockLine.start.y), new Vector2(mouseX, mouseY)); var threshold = Mathf.Min( Mathf.Abs(model.BlockNumToScreenPositionY(0) - model.BlockNumToScreenPositionY(1)), Mathf.Abs(model.SamplesToScreenPositionX(beatSamples[0]) - model.SamplesToScreenPositionX(beatSamples[1]))) / 3f; if (distance < threshold) { closestBlockLine.color = highlightColor; closestBeatLine.color = highlightColor; model.ClosestNotePosition.Value = new NotePosition(model.BPM.Value, model.LPB.Value, closestLineIndex, closestBlockLindex); } else { model.ClosestNotePosition.Value = new NotePosition(-1, -1, -1, -1); } } GLLineRenderer.RenderLines("beats", beatLines); GLLineRenderer.RenderLines("blocks", blockLines); }