special entities can be placed

This commit is contained in:
minenice55 2022-09-08 19:50:10 -04:00
parent 3a3d890f2c
commit 42e98ac42d
13 changed files with 1033 additions and 486 deletions

File diff suppressed because it is too large Load diff

View file

@ -409,9 +409,9 @@ namespace HeavenStudio.Editor
{
GameManager.instance.LoadRemix(json, type);
Timeline.instance.LoadRemix();
Timeline.instance.TempoInfo.UpdateStartingBPMText();
Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
Timeline.instance.TempoInfo.UpdateOffsetText();
// Timeline.instance.SpecialInfo.UpdateStartingBPMText();
// Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
// Timeline.instance.SpecialInfo.UpdateOffsetText();
Timeline.FitToSong();
currentRemixPath = string.Empty;

View file

@ -0,0 +1,158 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using TMPro;
using Starpelly;
namespace HeavenStudio.Editor.Track
{
public class SpecialTimeline : MonoBehaviour
{
[Header("References")]
[SerializeField] private RectTransform RefTempoChange;
[SerializeField] private RectTransform RefVolumeChange;
[SerializeField] private RectTransform RefSectionChange;
[Header("Components")]
private RectTransform rectTransform;
public List<SpecialTimelineObj> specialTimelineObjs = new List<SpecialTimelineObj>();
private bool firstUpdate;
private void Start()
{
rectTransform = this.GetComponent<RectTransform>();
Setup();
}
public void Setup()
{
ClearSpecialTimeline();
for (int i = 0; i < GameManager.instance.Beatmap.tempoChanges.Count; i++)
{
DynamicBeatmap.TempoChange tempoChange = GameManager.instance.Beatmap.tempoChanges[i];
AddTempoChange(false, tempoChange);
}
for (int i = 0; i < GameManager.instance.Beatmap.volumeChanges.Count; i++)
{
DynamicBeatmap.VolumeChange volumeChange = GameManager.instance.Beatmap.volumeChanges[i];
AddVolumeChange(false, volumeChange);
}
}
private void Update()
{
if (!firstUpdate)
{
firstUpdate = true;
}
if (Timeline.instance.userIsEditingInputField)
return;
if (!Conductor.instance.NotStopped())
{
if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, Editor.instance.EditorCamera))
{
if (Input.GetMouseButtonDown(0))
{
switch (Timeline.instance.timelineState.currentState)
{
case Timeline.CurrentTimelineState.State.TempoChange:
AddTempoChange(true);
break;
case Timeline.CurrentTimelineState.State.MusicVolume:
AddVolumeChange(true);
break;
}
}
}
}
}
public void ClearSpecialTimeline()
{
foreach (SpecialTimelineObj obj in specialTimelineObjs)
{
obj.DeleteObj();
}
specialTimelineObjs.Clear();
}
public void AddTempoChange(bool create, DynamicBeatmap.TempoChange tempoChange_ = null)
{
GameObject tempoChange = Instantiate(RefTempoChange.gameObject, this.transform);
tempoChange.transform.GetChild(0).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
tempoChange.transform.GetChild(1).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
tempoChange.transform.GetChild(2).GetComponent<TMP_Text>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
tempoChange.SetActive(true);
TempoTimelineObj tempoTimelineObj = tempoChange.GetComponent<TempoTimelineObj>();
if (create == true)
{
tempoChange.transform.position = new Vector3(Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition).x + 0.08f, tempoChange.transform.position.y);
tempoChange.transform.localPosition = new Vector3(Starpelly.Mathp.Round2Nearest(tempoChange.transform.localPosition.x, Timeline.SnapInterval()), tempoChange.transform.localPosition.y);
DynamicBeatmap.TempoChange tempoC = new DynamicBeatmap.TempoChange();
tempoC.beat = tempoChange.transform.localPosition.x;
tempoC.tempo = GameManager.instance.Beatmap.bpm;
tempoTimelineObj.tempoChange = tempoC;
GameManager.instance.Beatmap.tempoChanges.Add(tempoC);
}
else
{
tempoChange.transform.localPosition = new Vector3(tempoChange_.beat, tempoChange.transform.localPosition.y);
tempoTimelineObj.tempoChange = tempoChange_;
}
specialTimelineObjs.Add(tempoTimelineObj);
Timeline.instance.FitToSong();
}
public void AddVolumeChange(bool create, DynamicBeatmap.VolumeChange volumeChange_ = null)
{
GameObject volumeChange = Instantiate(RefVolumeChange.gameObject, this.transform);
volumeChange.transform.GetChild(0).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
volumeChange.transform.GetChild(1).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
volumeChange.transform.GetChild(2).GetComponent<TMP_Text>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();
volumeChange.SetActive(true);
VolumeTimelineObj volumeTimelineObj = volumeChange.GetComponent<VolumeTimelineObj>();
if (create == true)
{
volumeChange.transform.position = new Vector3(Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition).x + 0.08f, volumeChange.transform.position.y);
volumeChange.transform.localPosition = new Vector3(Starpelly.Mathp.Round2Nearest(volumeChange.transform.localPosition.x, Timeline.SnapInterval()), volumeChange.transform.localPosition.y);
DynamicBeatmap.VolumeChange volumeC = new DynamicBeatmap.VolumeChange();
volumeC.beat = volumeChange.transform.localPosition.x;
volumeC.volume = GameManager.instance.Beatmap.musicVolume;
volumeTimelineObj.volumeChange = volumeC;
GameManager.instance.Beatmap.volumeChanges.Add(volumeC);
}
else
{
volumeChange.transform.localPosition = new Vector3(volumeChange_.beat, volumeChange.transform.localPosition.y);
volumeTimelineObj.volumeChange = volumeChange_;
}
specialTimelineObjs.Add(volumeTimelineObj);
}
}
}

View file

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ea7831ec549a9984c8c3e5afd98bac2f
guid: 364cfb513d7ef744cb0d4828804188e0
MonoImporter:
externalObjects: {}
serializedVersion: 2

View file

@ -33,18 +33,70 @@ namespace HeavenStudio.Editor.Track
{
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
startPosX = mousePos.x - transform.position.x;
moving = true;
lastPosX = transform.localPosition.x;
OnLeftClick();
}
else if (Input.GetMouseButtonDown(1))
{
// transform.parent.GetComponent<TempoTimeline>().tempoTimelineObjs.Remove(this);
Destroy(this.gameObject);
OnRightClick();
}
hovering = true;
}
else
{
hovering = false;
}
if (moving)
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(mousePos.x - startPosX, transform.position.y, 0);
transform.localPosition = new Vector3(Mathf.Clamp(Starpelly.Mathp.Round2Nearest(transform.localPosition.x, Timeline.SnapInterval()), 0, Mathf.Infinity), transform.localPosition.y);
if (Input.GetMouseButtonUp(0))
{
if (!OnMove(transform.localPosition.x))
transform.localPosition = new Vector3(lastPosX, transform.localPosition.y);
moving = false;
lastPosX = transform.localPosition.x;
}
}
}
else
{
if (moving)
{
if (!OnMove(transform.localPosition.x))
transform.localPosition = new Vector3(lastPosX, transform.localPosition.y);
moving = false;
lastPosX = transform.localPosition.x;
}
hovering = false;
}
}
public void StartMove()
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
startPosX = mousePos.x - transform.position.x;
moving = true;
lastPosX = transform.localPosition.x;
}
public void DeleteObj()
{
transform.parent.GetComponent<SpecialTimeline>().specialTimelineObjs.Remove(this);
Destroy(this.gameObject);
}
//events
public virtual void Init() {}
public virtual void OnLeftClick() {}
public virtual void OnRightClick() {}
public virtual bool OnMove(float beat)
{
return true;
}
}
}

View file

@ -8,93 +8,32 @@ using DG.Tweening;
namespace HeavenStudio.Editor.Track
{
public class TempoTimelineObj : MonoBehaviour
public class TempoTimelineObj : SpecialTimelineObj
{
[Header("Components")]
[SerializeField] private RectTransform rectTransform;
[SerializeField] private TMP_Text tempoTXT;
[SerializeField] private RectTransform raycastRect;
public DynamicBeatmap.TempoChange tempoChange;
private float startPosX;
private bool moving = false;
public bool hovering;
private float lastPosX;
private void Start()
{
rectTransform = GetComponent<RectTransform>();
tempoTXT = transform.GetChild(2).GetComponent<TMP_Text>();
UpdateTempo();
}
private void Update()
{
if (Timeline.instance.timelineState.tempoChange && !Conductor.instance.NotStopped())
if (hovering)
{
if (RectTransformUtility.RectangleContainsScreenPoint(raycastRect, Input.mousePosition, Editor.instance.EditorCamera))
{
float newTempo = Input.mouseScrollDelta.y;
float newTempo = Input.mouseScrollDelta.y;
if (Input.GetKey(KeyCode.LeftShift))
newTempo *= 5f;
if (Input.GetKey(KeyCode.LeftControl))
newTempo /= 100f;
if (Input.GetKey(KeyCode.LeftShift))
newTempo *= 5f;
if (Input.GetKey(KeyCode.LeftControl))
newTempo /= 100f;
tempoChange.tempo += newTempo;
tempoChange.tempo += newTempo;
//make sure tempo is positive
if (tempoChange.tempo < 1)
tempoChange.tempo = 1;
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
startPosX = mousePos.x - transform.position.x;
moving = true;
lastPosX = transform.localPosition.x;
}
else if (Input.GetMouseButtonDown(1))
{
GameManager.instance.Beatmap.tempoChanges.Remove(tempoChange);
transform.parent.GetComponent<TempoTimeline>().tempoTimelineObjs.Remove(this);
Destroy(this.gameObject);
}
hovering = true;
}
else
{
hovering = false;
}
if (moving)
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(mousePos.x - startPosX, transform.position.y, 0);
transform.localPosition = new Vector3(Mathf.Clamp(Starpelly.Mathp.Round2Nearest(transform.localPosition.x, Timeline.SnapInterval()), 0, Mathf.Infinity), transform.localPosition.y);
}
if (Input.GetMouseButtonUp(0))
{
if (transform.parent.GetComponent<TempoTimeline>().tempoTimelineObjs.Find(c => c.gameObject.transform.localPosition.x == this.transform.localPosition.x && c != this) != null)
{
transform.localPosition = new Vector3(lastPosX, transform.localPosition.y);
}
else
{
tempoChange.beat = transform.localPosition.x;
}
moving = false;
lastPosX = transform.localPosition.x;
}
UpdateTempo();
//make sure tempo is positive
if (tempoChange.tempo < 1)
tempoChange.tempo = 1;
}
UpdateTempo();
}
private void UpdateTempo()
@ -102,5 +41,16 @@ namespace HeavenStudio.Editor.Track
tempoTXT.text = $"{tempoChange.tempo} BPM";
Timeline.instance.FitToSong();
}
public override void Init()
{
UpdateTempo();
}
public override void OnRightClick()
{
GameManager.instance.Beatmap.tempoChanges.Remove(tempoChange);
DeleteObj();
}
}
}

View file

@ -0,0 +1,54 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using DG.Tweening;
namespace HeavenStudio.Editor.Track
{
public class VolumeTimelineObj : SpecialTimelineObj
{
[Header("Components")]
[SerializeField] private TMP_Text volumeTXT;
public DynamicBeatmap.VolumeChange volumeChange;
private void Update()
{
if (hovering)
{
float newVolume = Input.mouseScrollDelta.y;
if (Input.GetKey(KeyCode.LeftShift))
newVolume *= 5f;
if (Input.GetKey(KeyCode.LeftControl))
newVolume /= 100f;
volumeChange.volume += newVolume;
//make sure volume is positive
volumeChange.volume = Mathf.Clamp(volumeChange.volume, 0, 100);
}
UpdateVolume();
}
private void UpdateVolume()
{
volumeTXT.text = $"{volumeChange.volume}%";
}
public override void Init()
{
UpdateVolume();
}
public override void OnRightClick()
{
GameManager.instance.Beatmap.volumeChanges.Remove(volumeChange);
DeleteObj();
}
}
}

View file

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 86bb8f2f290876a4387f1ea6fedf332b
guid: 84c1633846a16fb42baa226572335fae
MonoImporter:
externalObjects: {}
serializedVersion: 2

View file

@ -42,7 +42,7 @@ namespace HeavenStudio.Editor.Track
ChartSection
}
State currentState = State.Selection;
public State currentState = State.Selection;
public bool selected { get { return currentState == State.Selection; } }
public bool tempoChange { get { return currentState == State.TempoChange; } }
@ -57,6 +57,7 @@ namespace HeavenStudio.Editor.Track
{
currentState = State.Selection;
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.SelectionsBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
@ -64,6 +65,7 @@ namespace HeavenStudio.Editor.Track
{
currentState = State.TempoChange;
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.TempoChangeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
@ -71,6 +73,7 @@ namespace HeavenStudio.Editor.Track
{
currentState = State.MusicVolume;
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.MusicVolumeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
@ -83,19 +86,31 @@ namespace HeavenStudio.Editor.Track
currentState = state;
if (selected)
{
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.SelectionsBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
if (tempoChange)
{
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.TempoChangeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
if (musicVolume)
{
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.MusicVolumeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
if (chartSection)
{
instance.ChartSectionBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
instance.ChartSectionBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
}
else
instance.ChartSectionBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
}
@ -110,8 +125,7 @@ namespace HeavenStudio.Editor.Track
[SerializeField] private RectTransform TimelineEventObjRef;
[SerializeField] private RectTransform LayersRect;
public TempoTimeline TempoInfo;
public VolumeTimeline VolumeInfo;
public SpecialTimeline SpecialInfo;
private RectTransform TimelineSongPosLine;
[Header("Timeline Playbar")]
@ -157,16 +171,7 @@ namespace HeavenStudio.Editor.Track
AddEventObject(e.datamodel, false, new Vector3(e.beat, -e.track * LayerHeight()), e, false, RandomID());
}
//tempo changes
TempoInfo.ClearTempoTimeline();
for (int i = 0; i < GameManager.instance.Beatmap.tempoChanges.Count; i++)
{
var t = GameManager.instance.Beatmap.tempoChanges[i];
TempoInfo.AddTempoChange(false, t);
}
//volume changes
SpecialInfo.Setup();
}
public void Init()

View file

@ -1,89 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using TMPro;
using Starpelly;
namespace HeavenStudio.Editor.Track
{
public class VolumeTimeline : MonoBehaviour
{
[Header("Components")]
private RectTransform rectTransform;
public TMP_InputField StartingVolume;
private RectTransform StartingVolumeRect;
public List<VolumeTimelineObj> volumeTimelineObjs = new List<VolumeTimelineObj>();
private bool firstUpdate;
void Start()
{
rectTransform = this.GetComponent<RectTransform>();
StartingVolumeRect = StartingVolume.GetComponent<RectTransform>();
}
void Update()
{
if (!firstUpdate)
{
UpdateStartingVolumeText();
firstUpdate = true;
}
if (Timeline.instance.userIsEditingInputField)
return;
if (Timeline.instance.timelineState.musicVolume && !Conductor.instance.NotStopped())
{
if (RectTransformUtility.RectangleContainsScreenPoint(StartingVolumeRect, Input.mousePosition, Editor.instance.EditorCamera))
{
int increase = Mathf.RoundToInt(Input.mouseScrollDelta.y);
if (Input.GetKey(KeyCode.LeftShift))
increase *= 5;
if (increase != 0)
{
GameManager.instance.Beatmap.musicVolume += increase;
UpdateStartingVolumeText();
UpdateStartingVolumeFromText(); // In case the scrolled-to value is invalid.
}
}
}
}
public void UpdateStartingVolumeText()
{
StartingVolume.text = GameManager.instance.Beatmap.musicVolume.ToString();
}
public void UpdateStartingVolumeFromText()
{
// Failsafe against empty string.
if (String.IsNullOrEmpty(StartingVolume.text))
StartingVolume.text = "100";
var newVol = Convert.ToInt32(StartingVolume.text);
// Failsafe against invalid volume.
if (newVol > 100)
{
StartingVolume.text = "100";
newVol = 100;
}
else if (newVol < 0)
{
StartingVolume.text = "0";
newVol = 0;
}
GameManager.instance.Beatmap.musicVolume = newVol;
// In case the newVol ended up differing from the inputted string.
UpdateStartingVolumeText();
}
}
}

View file

@ -1,105 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using DG.Tweening;
namespace HeavenStudio.Editor.Track
{
public class VolumeTimelineObj : MonoBehaviour
{
[Header("Components")]
[SerializeField] private RectTransform rectTransform;
[SerializeField] private TMP_Text volumeTXT;
[SerializeField] private RectTransform raycastRect;
public DynamicBeatmap.VolumeChange volumeChange;
private float startPosX;
private bool moving = false;
public bool hovering;
private float lastPosX;
private void Start()
{
rectTransform = GetComponent<RectTransform>();
volumeTXT = transform.GetChild(2).GetComponent<TMP_Text>();
UpdateVolume();
}
private void Update()
{
if (Timeline.instance.timelineState.musicVolume && !Conductor.instance.NotStopped())
{
if (RectTransformUtility.RectangleContainsScreenPoint(raycastRect, Input.mousePosition, Editor.instance.EditorCamera))
{
float newVolume = Input.mouseScrollDelta.y;
if (Input.GetKey(KeyCode.LeftShift))
newVolume *= 5f;
if (Input.GetKey(KeyCode.LeftControl))
newVolume /= 100f;
volumeChange.volume += newVolume;
//make sure volume is positive
volumeChange.volume = Mathf.Clamp(volumeChange.volume, 0, 100);
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
startPosX = mousePos.x - transform.position.x;
moving = true;
lastPosX = transform.localPosition.x;
}
else if (Input.GetMouseButtonDown(1))
{
GameManager.instance.Beatmap.volumeChanges.Remove(volumeChange);
transform.parent.GetComponent<VolumeTimeline>().volumeTimelineObjs.Remove(this);
Destroy(this.gameObject);
}
hovering = true;
}
else
{
hovering = false;
}
if (moving)
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(mousePos.x - startPosX, transform.position.y, 0);
transform.localPosition = new Vector3(Mathf.Clamp(Starpelly.Mathp.Round2Nearest(transform.localPosition.x, Timeline.SnapInterval()), 0, Mathf.Infinity), transform.localPosition.y);
}
if (Input.GetMouseButtonUp(0))
{
if (transform.parent.GetComponent<VolumeTimeline>().volumeTimelineObjs.Find(c => c.gameObject.transform.localPosition.x == this.transform.localPosition.x && c != this) != null)
{
transform.localPosition = new Vector3(lastPosX, transform.localPosition.y);
}
else
{
volumeChange.beat = transform.localPosition.x;
}
moving = false;
lastPosX = transform.localPosition.x;
}
UpdateVolume();
}
}
private void UpdateVolume()
{
volumeTXT.text = $"{volumeChange.volume}%";
Timeline.instance.FitToSong();
}
}
}