mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-25 19:15:16 +00:00
Beatmap Sections & Latency Reduction (#170)
* prep UI for chart section * all special layers now on one area todo: have buttons toggle between special layers (selection mode shows all?), use the tabs system for this * swapping between special timelines - prelim * special entities can be placed * spec. timeline base functions complete music volume changes should work now * attempt at input lag reduction needs testing * fix dsp issues * smaller DSP buffer? * Revert "smaller DSP buffer?" This reverts commit 9d36db5ff90cf4e2d7bb8db9b4b7376cb493e02b. * make conductor clock use real time (double) change order of execution of input-related scripts to further attempt a reduction in input latency * start values can be changed make the old special entity bar visible when the corresponding type is selected * creation of Chart Sections (TODO: GO REFERENCE) * added GO references * section edit dialog * disable wrapping on chart section obj * backspace can now delete entities * entities don't shift when duplicated * fix PlayerActionEvent order of operations - fixed remix loading trying to clear special timeline while it's writing to itself * make oop check match parity * more operation order fix * fix Karate Man BG initialization * show section progress in editor todo: section progress in-game * more fix for entity duping
This commit is contained in:
parent
8df4a11666
commit
d74fe11e68
51 changed files with 5944 additions and 1129 deletions
BIN
Assets/Resources/Sprites/Editor/UI/bookmark.png
Normal file
BIN
Assets/Resources/Sprites/Editor/UI/bookmark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
108
Assets/Resources/Sprites/Editor/UI/bookmark.png.meta
Normal file
108
Assets/Resources/Sprites/Editor/UI/bookmark.png.meta
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e85d5d286a8191b499c570d33dd0899c
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 11
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 64
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 64
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Resources/Sprites/Editor/UI/document-signed.png
Normal file
BIN
Assets/Resources/Sprites/Editor/UI/document-signed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
108
Assets/Resources/Sprites/Editor/UI/document-signed.png.meta
Normal file
108
Assets/Resources/Sprites/Editor/UI/document-signed.png.meta
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dd516f1a3380ca642939d4fa86603249
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 11
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
vTOnly: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 1
|
||||||
|
aniso: 1
|
||||||
|
mipBias: 0
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
flipbookRows: 1
|
||||||
|
flipbookColumns: 1
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
ignorePngGamma: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 64
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 64
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
File diff suppressed because it is too large
Load diff
|
@ -31,6 +31,8 @@ namespace HeavenStudio
|
||||||
// Current time of the song
|
// Current time of the song
|
||||||
private float time;
|
private float time;
|
||||||
|
|
||||||
|
double lastAbsTime;
|
||||||
|
|
||||||
// an AudioSource attached to this GameObject that will play the music.
|
// an AudioSource attached to this GameObject that will play the music.
|
||||||
public AudioSource musicSource;
|
public AudioSource musicSource;
|
||||||
|
|
||||||
|
@ -140,6 +142,7 @@ namespace HeavenStudio
|
||||||
musicSource.PlayScheduled(AudioSettings.dspTime);
|
musicSource.PlayScheduled(AudioSettings.dspTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lastAbsTime = Time.realtimeSinceStartupAsDouble;
|
||||||
|
|
||||||
// GameManager.instance.SetCurrentEventToClosest(songPositionInBeats);
|
// GameManager.instance.SetCurrentEventToClosest(songPositionInBeats);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +175,9 @@ namespace HeavenStudio
|
||||||
|
|
||||||
if (isPlaying)
|
if (isPlaying)
|
||||||
{
|
{
|
||||||
var dt = Time.unscaledDeltaTime * musicSource.pitch;
|
double absTime = Time.realtimeSinceStartupAsDouble;
|
||||||
|
float dt = (float) (absTime - lastAbsTime) * musicSource.pitch;
|
||||||
|
lastAbsTime = absTime;
|
||||||
|
|
||||||
time += dt;
|
time += dt;
|
||||||
|
|
||||||
|
@ -344,7 +349,7 @@ namespace HeavenStudio
|
||||||
secPerBeat = 60f / songBpm;
|
secPerBeat = 60f / songBpm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVolume(int percent)
|
public void SetVolume(float percent)
|
||||||
{
|
{
|
||||||
musicSource.volume = percent / 100f;
|
musicSource.volume = percent / 100f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,19 +31,28 @@ namespace HeavenStudio
|
||||||
Coroutine currentGameSwitchIE;
|
Coroutine currentGameSwitchIE;
|
||||||
|
|
||||||
[Header("Properties")]
|
[Header("Properties")]
|
||||||
public int currentEvent, currentTempoEvent, currentPreEvent, currentPreSwitch;
|
public int currentEvent, currentTempoEvent, currentVolumeEvent, currentSectionEvent,
|
||||||
|
currentPreEvent, currentPreSwitch;
|
||||||
|
public float endBeat;
|
||||||
public float startOffset;
|
public float startOffset;
|
||||||
public bool playOnStart;
|
public bool playOnStart;
|
||||||
public float startBeat;
|
public float startBeat;
|
||||||
[NonSerialized] public GameObject currentGameO;
|
[NonSerialized] public GameObject currentGameO;
|
||||||
public bool autoplay;
|
public bool autoplay;
|
||||||
public bool canInput = true;
|
public bool canInput = true;
|
||||||
|
public DynamicBeatmap.ChartSection currentSection, nextSection;
|
||||||
|
public float sectionProgress { get {
|
||||||
|
if (currentSection == null) return 0;
|
||||||
|
if (nextSection == null) return (Conductor.instance.songPositionInBeats - currentSection.beat) / (endBeat - currentSection.beat);
|
||||||
|
return (Conductor.instance.songPositionInBeats - currentSection.beat) / (nextSection.beat - currentSection.beat);
|
||||||
|
}}
|
||||||
|
|
||||||
public event Action<float> onBeatChanged;
|
public event Action<float> onBeatChanged;
|
||||||
|
public event Action<DynamicBeatmap.ChartSection> onSectionChange;
|
||||||
|
|
||||||
public int BeatmapEntities()
|
public int BeatmapEntities()
|
||||||
{
|
{
|
||||||
return Beatmap.entities.Count + Beatmap.tempoChanges.Count;
|
return Beatmap.entities.Count + Beatmap.tempoChanges.Count + Beatmap.volumeChanges.Count + Beatmap.beatmapSections.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameManager instance { get; private set; }
|
public static GameManager instance { get; private set; }
|
||||||
|
@ -219,21 +228,46 @@ namespace HeavenStudio
|
||||||
if (!Conductor.instance.isPlaying)
|
if (!Conductor.instance.isPlaying)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
|
||||||
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
|
|
||||||
|
|
||||||
|
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
||||||
|
|
||||||
|
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
|
||||||
if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0)
|
if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0)
|
||||||
{
|
{
|
||||||
// Debug.Log("Checking Tempo Change at " + tempoChanges[currentTempoEvent] + ", current beat " + Conductor.instance.songPositionInBeats);
|
|
||||||
if (Conductor.instance.songPositionInBeats >= tempoChanges[currentTempoEvent])
|
if (Conductor.instance.songPositionInBeats >= tempoChanges[currentTempoEvent])
|
||||||
{
|
{
|
||||||
// Debug.Log("Tempo Change at " + Conductor.instance.songPositionInBeats + " of bpm " + DynamicBeatmap.tempoChanges[currentTempoEvent].tempo);
|
|
||||||
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
|
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
|
||||||
Conductor.instance.timeSinceLastTempoChange = Time.time;
|
Conductor.instance.timeSinceLastTempoChange = Time.time;
|
||||||
currentTempoEvent++;
|
currentTempoEvent++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<float> volumeChanges = Beatmap.volumeChanges.Select(c => c.beat).ToList();
|
||||||
|
if (currentVolumeEvent < Beatmap.volumeChanges.Count && currentVolumeEvent >= 0)
|
||||||
|
{
|
||||||
|
if (Conductor.instance.songPositionInBeats >= volumeChanges[currentVolumeEvent])
|
||||||
|
{
|
||||||
|
Conductor.instance.SetVolume(Beatmap.volumeChanges[currentVolumeEvent].volume);
|
||||||
|
currentVolumeEvent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<float> chartSections = Beatmap.beatmapSections.Select(c => c.beat).ToList();
|
||||||
|
if (currentSectionEvent < Beatmap.beatmapSections.Count && currentSectionEvent >= 0)
|
||||||
|
{
|
||||||
|
if (Conductor.instance.songPositionInBeats >= chartSections[currentSectionEvent])
|
||||||
|
{
|
||||||
|
Debug.Log("Section " + Beatmap.beatmapSections[currentSectionEvent].sectionName + " started");
|
||||||
|
currentSection = Beatmap.beatmapSections[currentSectionEvent];
|
||||||
|
currentSectionEvent++;
|
||||||
|
if (currentSectionEvent < Beatmap.beatmapSections.Count)
|
||||||
|
nextSection = Beatmap.beatmapSections[currentSectionEvent];
|
||||||
|
else
|
||||||
|
nextSection = null;
|
||||||
|
onSectionChange?.Invoke(currentSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float seekTime = 8f;
|
float seekTime = 8f;
|
||||||
//seek ahead to preload games that have assetbundles
|
//seek ahead to preload games that have assetbundles
|
||||||
SeekAheadAndPreload(Conductor.instance.songPositionInBeats, seekTime);
|
SeekAheadAndPreload(Conductor.instance.songPositionInBeats, seekTime);
|
||||||
|
@ -273,6 +307,8 @@ namespace HeavenStudio
|
||||||
// currentEvent += gameManagerEntities.Count;
|
// currentEvent += gameManagerEntities.Count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleInputs(bool inputs)
|
public void ToggleInputs(bool inputs)
|
||||||
|
@ -305,6 +341,10 @@ namespace HeavenStudio
|
||||||
}
|
}
|
||||||
|
|
||||||
KillAllSounds();
|
KillAllSounds();
|
||||||
|
|
||||||
|
Minigame miniGame = currentGameO.GetComponent<Minigame>();
|
||||||
|
if (miniGame != null)
|
||||||
|
miniGame.OnPlay(beat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Pause()
|
public void Pause()
|
||||||
|
@ -389,10 +429,17 @@ namespace HeavenStudio
|
||||||
{
|
{
|
||||||
SetGame(newGame);
|
SetGame(newGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<DynamicBeatmap.DynamicEntity> allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "end" });
|
||||||
|
if (allEnds.Count > 0)
|
||||||
|
endBeat = allEnds.Select(c => c.beat).Min();
|
||||||
|
else
|
||||||
|
endBeat = Conductor.instance.SongLengthInBeats();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetGame("noGame");
|
SetGame("noGame");
|
||||||
|
endBeat = Conductor.instance.SongLengthInBeats();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Beatmap.tempoChanges.Count > 0)
|
if (Beatmap.tempoChanges.Count > 0)
|
||||||
|
@ -413,6 +460,39 @@ namespace HeavenStudio
|
||||||
// Debug.Log("currentTempoEvent is now " + currentTempoEvent);
|
// Debug.Log("currentTempoEvent is now " + currentTempoEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Beatmap.volumeChanges.Count > 0)
|
||||||
|
{
|
||||||
|
currentVolumeEvent = 0;
|
||||||
|
List<float> volumeChanges = Beatmap.volumeChanges.Select(c => c.beat).ToList();
|
||||||
|
|
||||||
|
for (int t = 0; t < volumeChanges.Count; t++)
|
||||||
|
{
|
||||||
|
if (volumeChanges[t] > beat)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentVolumeEvent = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSection = null;
|
||||||
|
nextSection = null;
|
||||||
|
if (Beatmap.beatmapSections.Count > 0)
|
||||||
|
{
|
||||||
|
currentSectionEvent = 0;
|
||||||
|
List<float> beatmapSections = Beatmap.beatmapSections.Select(c => c.beat).ToList();
|
||||||
|
|
||||||
|
for (int t = 0; t < beatmapSections.Count; t++)
|
||||||
|
{
|
||||||
|
if (beatmapSections[t] > beat)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentSectionEvent = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onSectionChange?.Invoke(currentSection);
|
||||||
|
|
||||||
SeekAheadAndPreload(beat);
|
SeekAheadAndPreload(beat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: -43
|
executionOrder: -44
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
|
|
@ -135,6 +135,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
|
||||||
float yWeight = -(yMul*yMul) + 1f;
|
float yWeight = -(yMul*yMul) + 1f;
|
||||||
motionRoot.transform.localPosition = new Vector3(0, 3f * yWeight);
|
motionRoot.transform.localPosition = new Vector3(0, 3f * yWeight);
|
||||||
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * 1.4f, (1f-yWeight*0.8f) * 1.4f, 1f);
|
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * 1.4f, (1f-yWeight*0.8f) * 1.4f, 1f);
|
||||||
|
animator.Play("FanJump", -1, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -446,8 +446,24 @@ namespace HeavenStudio.Games
|
||||||
cameraPosition = CameraPosition[0].position;
|
cameraPosition = CameraPosition[0].position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnPlay(float beat)
|
||||||
|
{
|
||||||
|
var cond = Conductor.instance;
|
||||||
|
if (!cond.isPlaying)
|
||||||
|
{
|
||||||
|
SetBgEffectsToLast(beat);
|
||||||
|
// remove all children of the ItemHolder
|
||||||
|
foreach (Transform child in ItemHolder)
|
||||||
|
{
|
||||||
|
Destroy(child.gameObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
var cond = Conductor.instance;
|
||||||
|
|
||||||
GameCamera.additionalPosition = cameraPosition - GameCamera.defaultPosition;
|
GameCamera.additionalPosition = cameraPosition - GameCamera.defaultPosition;
|
||||||
bgEffectAnimator = BGEffect.GetComponent<Animator>();
|
bgEffectAnimator = BGEffect.GetComponent<Animator>();
|
||||||
bgEffectSpriteRenderer = BGEffect.GetComponent<SpriteRenderer>();
|
bgEffectSpriteRenderer = BGEffect.GetComponent<SpriteRenderer>();
|
||||||
|
@ -456,7 +472,8 @@ namespace HeavenStudio.Games
|
||||||
bgBloodRenderer = BGBlood.GetComponent<SpriteRenderer>();
|
bgBloodRenderer = BGBlood.GetComponent<SpriteRenderer>();
|
||||||
bgRadialRenderer = BGRadial.GetComponent<SpriteRenderer>();
|
bgRadialRenderer = BGRadial.GetComponent<SpriteRenderer>();
|
||||||
|
|
||||||
SetBgAndShadowCol(WantBgChangeStart, WantBgChangeLength, bgType, (int) currentShadowType, BackgroundColors[bgType], customShadowColour, (int)currentBgEffect);
|
SetBgEffectsToLast(cond.songPositionInBeats);
|
||||||
|
SetBgAndShadowCol(WantBgChangeStart, WantBgChangeLength, bgType, (int) currentShadowType, bgColour, customShadowColour, (int)currentBgEffect);
|
||||||
SetBgTexture(textureType, textureFilterType, filterColour, filterColour);
|
SetBgTexture(textureType, textureFilterType, filterColour, filterColour);
|
||||||
UpdateMaterialColour(BodyColor, HighlightColor, ItemColor);
|
UpdateMaterialColour(BodyColor, HighlightColor, ItemColor);
|
||||||
ToggleBop(WantBop);
|
ToggleBop(WantBop);
|
||||||
|
@ -806,10 +823,10 @@ namespace HeavenStudio.Games
|
||||||
var e = bgfx[i];
|
var e = bgfx[i];
|
||||||
if (e.beat > beat)
|
if (e.beat > beat)
|
||||||
break;
|
break;
|
||||||
SetBgAndShadowCol(e.beat, e.length, e["type"], e["type2"], e["colorA"], e["colorB"], e["type3"]);
|
SetBgEffectsUnloaded(e.beat, e.length, e["type"], e["type2"], e["colorA"], e["colorB"], e["type3"], e["type4"], e["type5"], e["colorC"], e["colorD"]);
|
||||||
SetBgTexture(e["type4"], e["type5"], e["colorC"], e["colorD"]);
|
|
||||||
}
|
}
|
||||||
var camfx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/special camera");
|
var camfx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/special camera");
|
||||||
|
DoSpecialCamera(0, 0, true);
|
||||||
for (int i = 0; i < camfx.Count; i++)
|
for (int i = 0; i < camfx.Count; i++)
|
||||||
{
|
{
|
||||||
var e = camfx[i];
|
var e = camfx[i];
|
||||||
|
@ -817,17 +834,16 @@ namespace HeavenStudio.Games
|
||||||
break;
|
break;
|
||||||
DoSpecialCamera(e.beat, e.length, e["toggle"]);
|
DoSpecialCamera(e.beat, e.length, e["toggle"]);
|
||||||
}
|
}
|
||||||
// has issues when creating a new hitx entity so this is deactivated for now
|
var objfx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/set object colors");
|
||||||
// var hitx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/hitX");
|
for (int i = 0; i < objfx.Count; i++)
|
||||||
// for (int i = 0; i < hitx.Count; i++)
|
{
|
||||||
// {
|
var e = objfx[i];
|
||||||
// var e = hitx[i];
|
if (e.beat > beat)
|
||||||
// if (e.beat > beat)
|
break;
|
||||||
// break;
|
UpdateMaterialColour(e["colorA"], e["colorB"], e["colorC"]);
|
||||||
// Debug.Log("hitx");
|
}
|
||||||
// DoWord(e.beat, e["type"], false);
|
SetBgAndShadowCol(WantBgChangeStart, WantBgChangeLength, bgType, (int) currentShadowType, bgColour, customShadowColour, (int)currentBgEffect);
|
||||||
// }
|
SetBgTexture(textureType, textureFilterType, filterColour, filterColour);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetBgEffectsUnloaded(float beat, float length, int newBgType, int newShadowType, Color bgCol, Color shadowCol, int bgFx, int texture, int textureFilter, Color filterCol, Color filterColNext)
|
public static void SetBgEffectsUnloaded(float beat, float length, int newBgType, int newShadowType, Color bgCol, Color shadowCol, int bgFx, int texture, int textureFilter, Color filterCol, Color filterColNext)
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace HeavenStudio.Games
|
||||||
{
|
{
|
||||||
public class Minigame : MonoBehaviour
|
public class Minigame : MonoBehaviour
|
||||||
{
|
{
|
||||||
public static float earlyTime = 0.1f, perfectTime = 0.08f, aceEarlyTime = 0.02f, aceLateTime = 0.02f, lateTime = 0.08f, endTime = 0.1f;
|
public static float earlyTime = 0.1f, perfectTime = 0.08f, aceEarlyTime = 0.025f, aceLateTime = 0.025f, lateTime = 0.08f, endTime = 0.1f;
|
||||||
public List<Minigame.Eligible> EligibleHits = new List<Minigame.Eligible>();
|
public List<Minigame.Eligible> EligibleHits = new List<Minigame.Eligible>();
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
@ -132,7 +132,6 @@ namespace HeavenStudio.Games
|
||||||
{
|
{
|
||||||
PlayerActionEvent input = GetClosestScheduledInput();
|
PlayerActionEvent input = GetClosestScheduledInput();
|
||||||
if (input == null) return false;
|
if (input == null) return false;
|
||||||
|
|
||||||
return input.IsExpectingInputNow();
|
return input.IsExpectingInputNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +189,11 @@ namespace HeavenStudio.Games
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnPlay(float beat)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public int MultipleEventsAtOnce()
|
public int MultipleEventsAtOnce()
|
||||||
{
|
{
|
||||||
int sameTime = 0;
|
int sameTime = 0;
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace HeavenStudio.Games
|
||||||
this.canHit = canHit;
|
this.canHit = canHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if(!Conductor.instance.NotStopped()){CleanUp();} // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
if(!Conductor.instance.NotStopped()){CleanUp();} // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
|
||||||
|
|
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 0
|
executionOrder: 5
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace HeavenStudio
|
||||||
DontDestroyOnLoad(this.gameObject);
|
DontDestroyOnLoad(this.gameObject);
|
||||||
instance = this;
|
instance = this;
|
||||||
Starpelly.OS.ChangeWindowTitle("Heaven Studio DEMO");
|
Starpelly.OS.ChangeWindowTitle("Heaven Studio DEMO");
|
||||||
|
QualitySettings.maxQueuedFrames = 1;
|
||||||
PlayerInput.InitInputControllers();
|
PlayerInput.InitInputControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace HeavenStudio.Editor.Commands
|
||||||
{
|
{
|
||||||
Pos p = new Pos();
|
Pos p = new Pos();
|
||||||
p.eventObj = eventObjs[i];
|
p.eventObj = eventObjs[i];
|
||||||
p.lastPos_ = eventObjs[i].lastPos_;
|
p.lastPos_ = eventObjs[i].moveStartPos;
|
||||||
p.previousPos = eventObjs[i].transform.localPosition;
|
p.previousPos = eventObjs[i].transform.localPosition;
|
||||||
this.pos.Add(p);
|
this.pos.Add(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ namespace HeavenStudio.Editor
|
||||||
Fullscreen();
|
Fullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.Delete))
|
if (Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace))
|
||||||
{
|
{
|
||||||
List<TimelineEventObj> ev = new List<TimelineEventObj>();
|
List<TimelineEventObj> ev = new List<TimelineEventObj>();
|
||||||
for (int i = 0; i < Selections.instance.eventsSelected.Count; i++) ev.Add(Selections.instance.eventsSelected[i]);
|
for (int i = 0; i < Selections.instance.eventsSelected.Count; i++) ev.Add(Selections.instance.eventsSelected[i]);
|
||||||
|
@ -409,9 +409,9 @@ namespace HeavenStudio.Editor
|
||||||
{
|
{
|
||||||
GameManager.instance.LoadRemix(json, type);
|
GameManager.instance.LoadRemix(json, type);
|
||||||
Timeline.instance.LoadRemix();
|
Timeline.instance.LoadRemix();
|
||||||
Timeline.instance.TempoInfo.UpdateStartingBPMText();
|
// Timeline.instance.SpecialInfo.UpdateStartingBPMText();
|
||||||
Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
|
// Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
|
||||||
Timeline.instance.TempoInfo.UpdateOffsetText();
|
// Timeline.instance.SpecialInfo.UpdateOffsetText();
|
||||||
Timeline.FitToSong();
|
Timeline.FitToSong();
|
||||||
|
|
||||||
currentRemixPath = string.Empty;
|
currentRemixPath = string.Empty;
|
||||||
|
|
|
@ -19,8 +19,10 @@ namespace HeavenStudio.Editor
|
||||||
|
|
||||||
[Header("Components")]
|
[Header("Components")]
|
||||||
[SerializeField] private Image layer;
|
[SerializeField] private Image layer;
|
||||||
|
[SerializeField] private Image specialLayers;
|
||||||
[SerializeField] private Image tempoLayer;
|
[SerializeField] private Image tempoLayer;
|
||||||
[SerializeField] private Image musicLayer;
|
[SerializeField] private Image musicLayer;
|
||||||
|
[SerializeField] private Image sectionLayer;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
|
@ -29,10 +31,14 @@ namespace HeavenStudio.Editor
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
specialLayers.GetComponent<Image>().color = theme.properties.SpecialLayersCol.Hex2RGB();
|
||||||
tempoLayer.GetComponent<Image>().color = theme.properties.TempoLayerCol.Hex2RGB();
|
tempoLayer.GetComponent<Image>().color = theme.properties.TempoLayerCol.Hex2RGB();
|
||||||
musicLayer.GetComponent<Image>().color = theme.properties.MusicLayerCol.Hex2RGB();
|
musicLayer.GetComponent<Image>().color = theme.properties.MusicLayerCol.Hex2RGB();
|
||||||
|
sectionLayer.GetComponent<Image>().color = theme.properties.SectionLayerCol.Hex2RGB();
|
||||||
|
Tooltip.AddTooltip(specialLayers.gameObject, $"All Special Tracks");
|
||||||
Tooltip.AddTooltip(tempoLayer.gameObject, $"Tempo Track");
|
Tooltip.AddTooltip(tempoLayer.gameObject, $"Tempo Track");
|
||||||
Tooltip.AddTooltip(musicLayer.gameObject, $"Music Volume Track");
|
Tooltip.AddTooltip(musicLayer.gameObject, $"Music Volume Track");
|
||||||
|
Tooltip.AddTooltip(sectionLayer.gameObject, $"Remix Sections Track");
|
||||||
|
|
||||||
|
|
||||||
layer.gameObject.SetActive(false);
|
layer.gameObject.SetActive(false);
|
||||||
|
|
|
@ -183,10 +183,11 @@ namespace HeavenStudio.Editor
|
||||||
|
|
||||||
public void Drag()
|
public void Drag()
|
||||||
{
|
{
|
||||||
if (Conductor.instance.NotStopped() || !Timeline.instance.timelineState.selected) return;
|
if (Conductor.instance.NotStopped() || Editor.instance.inAuthorativeMenu) return;
|
||||||
|
|
||||||
if (Timeline.instance.CheckIfMouseInTimeline() && dragTimes < 1)
|
if (Timeline.instance.CheckIfMouseInTimeline() && dragTimes < 1)
|
||||||
{
|
{
|
||||||
|
Timeline.instance.timelineState.SetState(Timeline.CurrentTimelineState.State.Selection);
|
||||||
dragTimes++;
|
dragTimes++;
|
||||||
|
|
||||||
TimelineEventObj eventObj;
|
TimelineEventObj eventObj;
|
||||||
|
|
|
@ -12,8 +12,10 @@ namespace HeavenStudio.Editor
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Properties
|
public class Properties
|
||||||
{
|
{
|
||||||
|
public string SpecialLayersCol;
|
||||||
public string TempoLayerCol;
|
public string TempoLayerCol;
|
||||||
public string MusicLayerCol;
|
public string MusicLayerCol;
|
||||||
|
public string SectionLayerCol;
|
||||||
|
|
||||||
public string Layer1Col;
|
public string Layer1Col;
|
||||||
public string Layer2Col;
|
public string Layer2Col;
|
||||||
|
|
8
Assets/Scripts/LevelEditor/Timeline/SpecialTmeline.meta
Normal file
8
Assets/Scripts/LevelEditor/Timeline/SpecialTmeline.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a7de3a0880c755a48a30d4e4f740c68c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using HeavenStudio;
|
||||||
|
using HeavenStudio.Editor;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
public class SectionDialog : Dialog
|
||||||
|
{
|
||||||
|
SectionTimelineObj sectionObj;
|
||||||
|
[SerializeField] TMP_InputField sectionName;
|
||||||
|
|
||||||
|
public void SwitchSectionDialog()
|
||||||
|
{
|
||||||
|
if(dialog.activeSelf) {
|
||||||
|
sectionObj = null;
|
||||||
|
dialog.SetActive(false);
|
||||||
|
Editor.instance.inAuthorativeMenu = false;
|
||||||
|
} else {
|
||||||
|
Editor.instance.inAuthorativeMenu = true;
|
||||||
|
ResetAllDialogs();
|
||||||
|
dialog.SetActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSectionObj(SectionTimelineObj sectionObj)
|
||||||
|
{
|
||||||
|
this.sectionObj = sectionObj;
|
||||||
|
sectionName.text = sectionObj.chartSection.sectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteSection()
|
||||||
|
{
|
||||||
|
if(dialog.activeSelf) {
|
||||||
|
dialog.SetActive(false);
|
||||||
|
Editor.instance.inAuthorativeMenu = false;
|
||||||
|
}
|
||||||
|
if (sectionObj == null) return;
|
||||||
|
GameManager.instance.Beatmap.beatmapSections.Remove(sectionObj.chartSection);
|
||||||
|
sectionObj.DeleteObj();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeSectionName(string name)
|
||||||
|
{
|
||||||
|
if (sectionObj == null) return;
|
||||||
|
sectionObj.chartSection.sectionName = name;
|
||||||
|
sectionObj.UpdateLabel();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: ea7831ec549a9984c8c3e5afd98bac2f
|
guid: 7e5d39fb5bc171f44ba013cf8e37fdd2
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
|
@ -0,0 +1,229 @@
|
||||||
|
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>();
|
||||||
|
|
||||||
|
[System.Flags]
|
||||||
|
public enum HoveringTypes
|
||||||
|
{
|
||||||
|
TempoChange = 1,
|
||||||
|
VolumeChange = 2,
|
||||||
|
SectionChange = 4,
|
||||||
|
}
|
||||||
|
public static HoveringTypes hoveringTypes = 0;
|
||||||
|
|
||||||
|
private bool firstUpdate;
|
||||||
|
|
||||||
|
public static SpecialTimeline instance;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
instance = this;
|
||||||
|
rectTransform = this.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
Setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
ClearSpecialTimeline();
|
||||||
|
|
||||||
|
foreach (var tempoChange in GameManager.instance.Beatmap.tempoChanges)
|
||||||
|
AddTempoChange(false, tempoChange);
|
||||||
|
|
||||||
|
foreach (var volumeChange in GameManager.instance.Beatmap.volumeChanges)
|
||||||
|
AddVolumeChange(false, volumeChange);
|
||||||
|
|
||||||
|
foreach (var sectionChange in GameManager.instance.Beatmap.beatmapSections)
|
||||||
|
AddChartSection(false, sectionChange);
|
||||||
|
|
||||||
|
Timeline.instance.timelineState.SetState(Timeline.CurrentTimelineState.State.Selection);
|
||||||
|
FixObjectsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!firstUpdate)
|
||||||
|
{
|
||||||
|
hoveringTypes = 0;
|
||||||
|
firstUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Timeline.instance.userIsEditingInputField || Editor.instance.inAuthorativeMenu)
|
||||||
|
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:
|
||||||
|
if (!hoveringTypes.HasFlag(HoveringTypes.TempoChange))
|
||||||
|
AddTempoChange(true);
|
||||||
|
break;
|
||||||
|
case Timeline.CurrentTimelineState.State.MusicVolume:
|
||||||
|
if (!hoveringTypes.HasFlag(HoveringTypes.VolumeChange))
|
||||||
|
AddVolumeChange(true);
|
||||||
|
break;
|
||||||
|
case Timeline.CurrentTimelineState.State.ChartSection:
|
||||||
|
if (!hoveringTypes.HasFlag(HoveringTypes.SectionChange))
|
||||||
|
AddChartSection(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hoveringTypes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FixObjectsVisibility()
|
||||||
|
{
|
||||||
|
foreach (SpecialTimelineObj obj in specialTimelineObjs)
|
||||||
|
{
|
||||||
|
obj.SetVisibility(Timeline.instance.timelineState.currentState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearSpecialTimeline()
|
||||||
|
{
|
||||||
|
foreach (SpecialTimelineObj obj in specialTimelineObjs)
|
||||||
|
{
|
||||||
|
Destroy(obj.gameObject);
|
||||||
|
}
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
tempoTimelineObj.SetVisibility(Timeline.instance.timelineState.currentState);
|
||||||
|
|
||||||
|
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.MusicLayerCol.Hex2RGB();
|
||||||
|
volumeChange.transform.GetChild(1).GetComponent<Image>().color = EditorTheme.theme.properties.MusicLayerCol.Hex2RGB();
|
||||||
|
volumeChange.transform.GetChild(2).GetComponent<TMP_Text>().color = EditorTheme.theme.properties.MusicLayerCol.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_;
|
||||||
|
}
|
||||||
|
volumeTimelineObj.SetVisibility(Timeline.instance.timelineState.currentState);
|
||||||
|
|
||||||
|
specialTimelineObjs.Add(volumeTimelineObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddChartSection(bool create, DynamicBeatmap.ChartSection chartSection_ = null)
|
||||||
|
{
|
||||||
|
GameObject chartSection = Instantiate(RefSectionChange.gameObject, this.transform);
|
||||||
|
|
||||||
|
chartSection.transform.GetChild(0).GetComponent<Image>().color = EditorTheme.theme.properties.SectionLayerCol.Hex2RGB();
|
||||||
|
chartSection.transform.GetChild(1).GetComponent<Image>().color = EditorTheme.theme.properties.SectionLayerCol.Hex2RGB();
|
||||||
|
chartSection.transform.GetChild(2).GetComponent<Image>().color = EditorTheme.theme.properties.SectionLayerCol.Hex2RGB();
|
||||||
|
chartSection.transform.GetChild(3).GetComponent<TMP_Text>().color = EditorTheme.theme.properties.SectionLayerCol.Hex2RGB();
|
||||||
|
|
||||||
|
chartSection.SetActive(true);
|
||||||
|
|
||||||
|
SectionTimelineObj sectionTimelineObj = chartSection.GetComponent<SectionTimelineObj>();
|
||||||
|
|
||||||
|
if (create == true)
|
||||||
|
{
|
||||||
|
chartSection.transform.position = new Vector3(Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition).x + 0.08f, chartSection.transform.position.y);
|
||||||
|
chartSection.transform.localPosition = new Vector3(Starpelly.Mathp.Round2Nearest(chartSection.transform.localPosition.x, Timeline.SnapInterval()), chartSection.transform.localPosition.y);
|
||||||
|
|
||||||
|
DynamicBeatmap.ChartSection sectionC = new DynamicBeatmap.ChartSection();
|
||||||
|
sectionC.beat = chartSection.transform.localPosition.x;
|
||||||
|
sectionC.sectionName = "New Section";
|
||||||
|
sectionC.startPerfect = false;
|
||||||
|
sectionC.isCheckpoint = false;
|
||||||
|
|
||||||
|
sectionTimelineObj.chartSection = sectionC;
|
||||||
|
GameManager.instance.Beatmap.beatmapSections.Add(sectionC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chartSection.transform.localPosition = new Vector3(chartSection_.beat, chartSection.transform.localPosition.y);
|
||||||
|
|
||||||
|
sectionTimelineObj.chartSection = chartSection_;
|
||||||
|
}
|
||||||
|
sectionTimelineObj.SetVisibility(Timeline.instance.timelineState.currentState);
|
||||||
|
|
||||||
|
specialTimelineObjs.Add(sectionTimelineObj);
|
||||||
|
//auto-open the dialog
|
||||||
|
sectionTimelineObj.OnRightClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 10dd19278a802c24fbeb39d1ccb23219
|
guid: 364cfb513d7ef744cb0d4828804188e0
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 46f4e0c7199fe9648bcc8cc5c601cdf3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor
|
||||||
|
{
|
||||||
|
public class SpecialTimelineAll : TabsContent
|
||||||
|
{
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnOpenTab()
|
||||||
|
{
|
||||||
|
SpecialTimeline.instance.FixObjectsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCloseTab()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e15bb84f43093e94d8360fa51074bb97
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor
|
||||||
|
{
|
||||||
|
public class SpecialTimelineSection : TabsContent
|
||||||
|
{
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnOpenTab()
|
||||||
|
{
|
||||||
|
SpecialTimeline.instance.FixObjectsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCloseTab()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e528ff67df36f6242bd525e4b3911f4e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor
|
||||||
|
{
|
||||||
|
public class SpecialTimelineTempo : TabsContent
|
||||||
|
{
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnOpenTab()
|
||||||
|
{
|
||||||
|
SpecialTimeline.instance.FixObjectsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCloseTab()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b802d26536208b4b9ca9994187788a9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using HeavenStudio.Editor.Track;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor
|
||||||
|
{
|
||||||
|
public class SpecialTimelineVolume : TabsContent
|
||||||
|
{
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update is called once per frame
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnOpenTab()
|
||||||
|
{
|
||||||
|
SpecialTimeline.instance.FixObjectsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnCloseTab()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 01f0c8cfacd823a40a2f3cc7d01ac78a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c80527f878ac1594bb0eedc6884a3a5f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
using DG.Tweening;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor.Track
|
||||||
|
{
|
||||||
|
public class SectionTimelineObj : SpecialTimelineObj
|
||||||
|
{
|
||||||
|
[Header("Components")]
|
||||||
|
[SerializeField] private TMP_Text sectionLabel;
|
||||||
|
[SerializeField] private GameObject chartLine;
|
||||||
|
[SerializeField] private SectionDialog sectionDialog;
|
||||||
|
|
||||||
|
public DynamicBeatmap.ChartSection chartSection;
|
||||||
|
|
||||||
|
new private void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
if (hovering)
|
||||||
|
{
|
||||||
|
SpecialTimeline.hoveringTypes |= SpecialTimeline.HoveringTypes.SectionChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateLabel()
|
||||||
|
{
|
||||||
|
sectionLabel.text = chartSection.sectionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
UpdateLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnLeftClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.ChartSection)
|
||||||
|
StartMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRightClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.ChartSection)
|
||||||
|
{
|
||||||
|
sectionDialog.SetSectionObj(this);
|
||||||
|
sectionDialog.SwitchSectionDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnMove(float beat)
|
||||||
|
{
|
||||||
|
foreach (var sectionChange in GameManager.instance.Beatmap.beatmapSections)
|
||||||
|
{
|
||||||
|
if (this.chartSection == sectionChange)
|
||||||
|
continue;
|
||||||
|
if (beat > sectionChange.beat - Timeline.instance.snapInterval && beat < sectionChange.beat + Timeline.instance.snapInterval)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.chartSection.beat = beat;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetVisibility(Timeline.CurrentTimelineState.State state)
|
||||||
|
{
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.ChartSection || state == Timeline.CurrentTimelineState.State.Selection)
|
||||||
|
{
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.ChartSection)
|
||||||
|
{
|
||||||
|
chartLine.SetActive(true);
|
||||||
|
sectionLabel.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chartLine.SetActive(false);
|
||||||
|
sectionLabel.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameObject.SetActive(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 396d5b0b822f8da4cb7b855a39b4a90f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,103 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
using DG.Tweening;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor.Track
|
||||||
|
{
|
||||||
|
public class SpecialTimelineObj : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Components")]
|
||||||
|
[SerializeField] private RectTransform rectTransform;
|
||||||
|
[SerializeField] private RectTransform raycastRect;
|
||||||
|
|
||||||
|
private float startPosX;
|
||||||
|
private bool moving = false;
|
||||||
|
|
||||||
|
public bool hovering;
|
||||||
|
private float lastPosX;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
rectTransform = GetComponent<RectTransform>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Update()
|
||||||
|
{
|
||||||
|
if (!Conductor.instance.NotStopped())
|
||||||
|
{
|
||||||
|
if (RectTransformUtility.RectangleContainsScreenPoint(raycastRect, Input.mousePosition, Editor.instance.EditorCamera))
|
||||||
|
{
|
||||||
|
if (Input.GetMouseButtonDown(0))
|
||||||
|
{
|
||||||
|
OnLeftClick();
|
||||||
|
}
|
||||||
|
else if (Input.GetMouseButtonDown(1))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
public virtual void SetVisibility(Timeline.CurrentTimelineState.State state) {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4dda06181c616dc4bb406f3d5f3bb6cf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,98 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
using DG.Tweening;
|
||||||
|
|
||||||
|
namespace HeavenStudio.Editor.Track
|
||||||
|
{
|
||||||
|
public class TempoTimelineObj : SpecialTimelineObj
|
||||||
|
{
|
||||||
|
[Header("Components")]
|
||||||
|
[SerializeField] private TMP_Text tempoTXT;
|
||||||
|
[SerializeField] private GameObject tempoLine;
|
||||||
|
|
||||||
|
public DynamicBeatmap.TempoChange tempoChange;
|
||||||
|
|
||||||
|
new private void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
if (hovering)
|
||||||
|
{
|
||||||
|
SpecialTimeline.hoveringTypes |= SpecialTimeline.HoveringTypes.TempoChange;
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.TempoChange)
|
||||||
|
{
|
||||||
|
float newTempo = Input.mouseScrollDelta.y;
|
||||||
|
|
||||||
|
if (Input.GetKey(KeyCode.LeftShift))
|
||||||
|
newTempo *= 5f;
|
||||||
|
if (Input.GetKey(KeyCode.LeftControl))
|
||||||
|
newTempo /= 100f;
|
||||||
|
|
||||||
|
tempoChange.tempo += newTempo;
|
||||||
|
|
||||||
|
//make sure tempo is positive
|
||||||
|
if (tempoChange.tempo < 1)
|
||||||
|
tempoChange.tempo = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateTempo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTempo()
|
||||||
|
{
|
||||||
|
tempoTXT.text = $"{tempoChange.tempo} BPM";
|
||||||
|
Timeline.instance.FitToSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
UpdateTempo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnLeftClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.TempoChange)
|
||||||
|
StartMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRightClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.TempoChange)
|
||||||
|
{
|
||||||
|
GameManager.instance.Beatmap.tempoChanges.Remove(tempoChange);
|
||||||
|
DeleteObj();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnMove(float beat)
|
||||||
|
{
|
||||||
|
foreach (var tempoChange in GameManager.instance.Beatmap.tempoChanges)
|
||||||
|
{
|
||||||
|
if (this.tempoChange == tempoChange)
|
||||||
|
continue;
|
||||||
|
if (beat > tempoChange.beat - Timeline.instance.snapInterval && beat < tempoChange.beat + Timeline.instance.snapInterval)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.tempoChange.beat = beat;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetVisibility(Timeline.CurrentTimelineState.State state)
|
||||||
|
{
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.TempoChange || state == Timeline.CurrentTimelineState.State.Selection)
|
||||||
|
{
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.TempoChange)
|
||||||
|
tempoLine.SetActive(true);
|
||||||
|
else
|
||||||
|
tempoLine.SetActive(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
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;
|
||||||
|
[SerializeField] private GameObject volumeLine;
|
||||||
|
|
||||||
|
public DynamicBeatmap.VolumeChange volumeChange;
|
||||||
|
|
||||||
|
new private void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
if (hovering)
|
||||||
|
{
|
||||||
|
SpecialTimeline.hoveringTypes |= SpecialTimeline.HoveringTypes.VolumeChange;
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.MusicVolume)
|
||||||
|
{
|
||||||
|
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 OnLeftClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.MusicVolume)
|
||||||
|
StartMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRightClick()
|
||||||
|
{
|
||||||
|
if (Timeline.instance.timelineState.currentState == Timeline.CurrentTimelineState.State.MusicVolume)
|
||||||
|
{
|
||||||
|
GameManager.instance.Beatmap.volumeChanges.Remove(volumeChange);
|
||||||
|
DeleteObj();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnMove(float beat)
|
||||||
|
{
|
||||||
|
foreach (var volumeChange in GameManager.instance.Beatmap.volumeChanges)
|
||||||
|
{
|
||||||
|
if (this.volumeChange == volumeChange)
|
||||||
|
continue;
|
||||||
|
if (beat > volumeChange.beat - Timeline.instance.snapInterval && beat < volumeChange.beat + Timeline.instance.snapInterval)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.volumeChange.beat = beat;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetVisibility(Timeline.CurrentTimelineState.State state)
|
||||||
|
{
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.MusicVolume || state == Timeline.CurrentTimelineState.State.Selection)
|
||||||
|
{
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
if (state == Timeline.CurrentTimelineState.State.MusicVolume)
|
||||||
|
volumeLine.SetActive(true);
|
||||||
|
else
|
||||||
|
volumeLine.SetActive(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 86bb8f2f290876a4387f1ea6fedf332b
|
guid: 84c1633846a16fb42baa226572335fae
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
|
@ -1,180 +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 TempoTimeline : MonoBehaviour
|
|
||||||
{
|
|
||||||
[Header("Components")]
|
|
||||||
private RectTransform rectTransform;
|
|
||||||
[SerializeField] private RectTransform RefTempoChange;
|
|
||||||
public TMP_InputField StartingBPM;
|
|
||||||
private RectTransform StartingBPMRect;
|
|
||||||
public TMP_InputField FirstBeatOffset;
|
|
||||||
|
|
||||||
public List<TempoTimelineObj> tempoTimelineObjs = new List<TempoTimelineObj>();
|
|
||||||
|
|
||||||
private bool firstUpdate;
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
rectTransform = this.GetComponent<RectTransform>();
|
|
||||||
StartingBPMRect = StartingBPM.GetComponent<RectTransform>();
|
|
||||||
|
|
||||||
for (int i = 0; i < GameManager.instance.Beatmap.tempoChanges.Count; i++)
|
|
||||||
{
|
|
||||||
DynamicBeatmap.TempoChange tempoChange = GameManager.instance.Beatmap.tempoChanges[i];
|
|
||||||
AddTempoChange(false, tempoChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (!firstUpdate)
|
|
||||||
{
|
|
||||||
UpdateStartingBPMText();
|
|
||||||
UpdateOffsetText();
|
|
||||||
firstUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Timeline.instance.userIsEditingInputField)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Timeline.instance.timelineState.tempoChange && !Conductor.instance.NotStopped())
|
|
||||||
{
|
|
||||||
if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, Editor.instance.EditorCamera))
|
|
||||||
{
|
|
||||||
if (Input.GetMouseButtonDown(0))
|
|
||||||
{
|
|
||||||
if (tempoTimelineObjs.FindAll(c => c.hovering == true).Count == 0)
|
|
||||||
{
|
|
||||||
AddTempoChange(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RectTransformUtility.RectangleContainsScreenPoint(StartingBPMRect, Input.mousePosition, Editor.instance.EditorCamera))
|
|
||||||
{
|
|
||||||
float increase = Input.mouseScrollDelta.y;
|
|
||||||
if (Input.GetKey(KeyCode.LeftControl))
|
|
||||||
increase /= 100f;
|
|
||||||
if (Input.GetKey(KeyCode.LeftShift))
|
|
||||||
increase *= 5f;
|
|
||||||
|
|
||||||
if (increase != 0f)
|
|
||||||
{
|
|
||||||
GameManager.instance.Beatmap.bpm += increase;
|
|
||||||
UpdateStartingBPMText();
|
|
||||||
UpdateStartingBPMFromText(); // In case the scrolled-to value is invalid.
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateStartingBPMText()
|
|
||||||
{
|
|
||||||
StartingBPM.text = GameManager.instance.Beatmap.bpm.ToString("G");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateOffsetText()
|
|
||||||
{
|
|
||||||
FirstBeatOffset.text = (GameManager.instance.Beatmap.firstBeatOffset * 1000f).ToString("G");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateStartingBPMFromText()
|
|
||||||
{
|
|
||||||
// Failsafe against empty string.
|
|
||||||
if (String.IsNullOrEmpty(StartingBPM.text))
|
|
||||||
StartingBPM.text = "120";
|
|
||||||
|
|
||||||
var newBPM = Convert.ToSingle(StartingBPM.text);
|
|
||||||
|
|
||||||
// Failsafe against negative BPM.
|
|
||||||
if (newBPM < 1f)
|
|
||||||
{
|
|
||||||
StartingBPM.text = "1";
|
|
||||||
newBPM = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit decimal places to 4.
|
|
||||||
newBPM = (float)System.Math.Round(newBPM, 4);
|
|
||||||
|
|
||||||
GameManager.instance.Beatmap.bpm = newBPM;
|
|
||||||
|
|
||||||
// In case the newBPM ended up differing from the inputted string.
|
|
||||||
UpdateStartingBPMText();
|
|
||||||
|
|
||||||
Timeline.instance.FitToSong();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateOffsetFromText()
|
|
||||||
{
|
|
||||||
// Failsafe against empty string.
|
|
||||||
if (String.IsNullOrEmpty(FirstBeatOffset.text))
|
|
||||||
FirstBeatOffset.text = "0";
|
|
||||||
|
|
||||||
// Convert ms to s.
|
|
||||||
var newOffset = Convert.ToSingle(FirstBeatOffset.text) / 1000f;
|
|
||||||
|
|
||||||
// Limit decimal places to 4.
|
|
||||||
newOffset = (float)System.Math.Round(newOffset, 4);
|
|
||||||
|
|
||||||
GameManager.instance.Beatmap.firstBeatOffset = newOffset;
|
|
||||||
|
|
||||||
UpdateOffsetText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearTempoTimeline()
|
|
||||||
{
|
|
||||||
foreach (TempoTimelineObj tempoTimelineObj in tempoTimelineObjs)
|
|
||||||
{
|
|
||||||
Destroy(tempoTimelineObj.gameObject);
|
|
||||||
}
|
|
||||||
tempoTimelineObjs.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_;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempoTimelineObjs.Add(tempoTimelineObj);
|
|
||||||
|
|
||||||
Timeline.instance.FitToSong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
using TMPro;
|
|
||||||
|
|
||||||
using DG.Tweening;
|
|
||||||
|
|
||||||
namespace HeavenStudio.Editor.Track
|
|
||||||
{
|
|
||||||
public class TempoTimelineObj : MonoBehaviour
|
|
||||||
{
|
|
||||||
[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 (RectTransformUtility.RectangleContainsScreenPoint(raycastRect, Input.mousePosition, Editor.instance.EditorCamera))
|
|
||||||
{
|
|
||||||
float newTempo = Input.mouseScrollDelta.y;
|
|
||||||
|
|
||||||
if (Input.GetKey(KeyCode.LeftShift))
|
|
||||||
newTempo *= 5f;
|
|
||||||
if (Input.GetKey(KeyCode.LeftControl))
|
|
||||||
newTempo /= 100f;
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTempo()
|
|
||||||
{
|
|
||||||
tempoTXT.text = $"{tempoChange.tempo} BPM";
|
|
||||||
Timeline.instance.FitToSong();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Collections;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
@ -34,45 +34,109 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
public class CurrentTimelineState
|
public class CurrentTimelineState
|
||||||
{
|
{
|
||||||
public bool selected;
|
public enum State
|
||||||
public bool tempoChange;
|
{
|
||||||
public bool musicVolume;
|
Selection,
|
||||||
|
TempoChange,
|
||||||
|
MusicVolume,
|
||||||
|
ChartSection
|
||||||
|
}
|
||||||
|
|
||||||
|
public State currentState = State.Selection;
|
||||||
|
|
||||||
|
public bool selected { get { return currentState == State.Selection; } }
|
||||||
|
public bool tempoChange { get { return currentState == State.TempoChange; } }
|
||||||
|
public bool musicVolume { get { return currentState == State.MusicVolume; } }
|
||||||
|
public bool chartSection { get { return currentState == State.ChartSection; } }
|
||||||
|
|
||||||
public void SetState(bool selected, bool tempoChange, bool musicVolume)
|
public void SetState(bool selected, bool tempoChange, bool musicVolume)
|
||||||
{
|
{
|
||||||
if (Conductor.instance.NotStopped()) return;
|
if (Conductor.instance.NotStopped()) return;
|
||||||
|
|
||||||
this.selected = selected;
|
|
||||||
this.tempoChange = tempoChange;
|
|
||||||
this.musicVolume = musicVolume;
|
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
|
{
|
||||||
|
currentState = State.Selection;
|
||||||
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||||
|
instance.SelectionsBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||||
if (tempoChange)
|
if (tempoChange)
|
||||||
|
{
|
||||||
|
currentState = State.TempoChange;
|
||||||
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||||
|
instance.TempoChangeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||||
if (musicVolume)
|
if (musicVolume)
|
||||||
|
{
|
||||||
|
currentState = State.MusicVolume;
|
||||||
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||||
|
instance.MusicVolumeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetState(State state)
|
||||||
|
{
|
||||||
|
if (Conductor.instance.NotStopped()) return;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Header("Timeline Components")]
|
[Header("Timeline Components")]
|
||||||
[SerializeField] private RectTransform TimelineSlider;
|
[SerializeField] private RectTransform TimelineSlider;
|
||||||
[SerializeField] private RectTransform TimelineGridSelect;
|
[SerializeField] private RectTransform TimelineGridSelect;
|
||||||
|
[SerializeField] private RectTransform TimelineEventGrid;
|
||||||
[SerializeField] private TMP_Text TimelinePlaybackBeat;
|
[SerializeField] private TMP_Text TimelinePlaybackBeat;
|
||||||
public RectTransform TimelineContent;
|
public RectTransform TimelineContent;
|
||||||
[SerializeField] private RectTransform TimelineSongPosLineRef;
|
[SerializeField] private RectTransform TimelineSongPosLineRef;
|
||||||
[SerializeField] private RectTransform TimelineEventObjRef;
|
[SerializeField] private RectTransform TimelineEventObjRef;
|
||||||
[SerializeField] private RectTransform LayersRect;
|
[SerializeField] private RectTransform LayersRect;
|
||||||
|
|
||||||
public TempoTimeline TempoInfo;
|
[SerializeField] private GameObject TimelineSectionDisplay;
|
||||||
public VolumeTimeline VolumeInfo;
|
[SerializeField] private TMP_Text TimelineSectionText;
|
||||||
|
[SerializeField] private Slider TimelineSectionProgress;
|
||||||
|
|
||||||
|
[Header("Timeline Inputs")]
|
||||||
|
public TMP_InputField FirstBeatOffset;
|
||||||
|
public TMP_InputField StartingTempoSpecialAll;
|
||||||
|
public TMP_InputField StartingTempoSpecialTempo;
|
||||||
|
public TMP_InputField StartingVolumeSpecialVolume;
|
||||||
|
|
||||||
|
public SpecialTimeline SpecialInfo;
|
||||||
private RectTransform TimelineSongPosLine;
|
private RectTransform TimelineSongPosLine;
|
||||||
|
|
||||||
[Header("Timeline Playbar")]
|
[Header("Timeline Playbar")]
|
||||||
|
@ -84,6 +148,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
public Button SelectionsBTN;
|
public Button SelectionsBTN;
|
||||||
public Button TempoChangeBTN;
|
public Button TempoChangeBTN;
|
||||||
public Button MusicVolumeBTN;
|
public Button MusicVolumeBTN;
|
||||||
|
public Button ChartSectionBTN;
|
||||||
public Slider PlaybackSpeed;
|
public Slider PlaybackSpeed;
|
||||||
|
|
||||||
public Vector3[] LayerCorners = new Vector3[4];
|
public Vector3[] LayerCorners = new Vector3[4];
|
||||||
|
@ -117,16 +182,10 @@ namespace HeavenStudio.Editor.Track
|
||||||
AddEventObject(e.datamodel, false, new Vector3(e.beat, -e.track * LayerHeight()), e, false, RandomID());
|
AddEventObject(e.datamodel, false, new Vector3(e.beat, -e.track * LayerHeight()), e, false, RandomID());
|
||||||
}
|
}
|
||||||
|
|
||||||
//tempo changes
|
SpecialInfo.Setup();
|
||||||
TempoInfo.ClearTempoTimeline();
|
UpdateOffsetText();
|
||||||
for (int i = 0; i < GameManager.instance.Beatmap.tempoChanges.Count; i++)
|
UpdateStartingBPMText();
|
||||||
{
|
UpdateStartingVolText();
|
||||||
var t = GameManager.instance.Beatmap.tempoChanges[i];
|
|
||||||
|
|
||||||
TempoInfo.AddTempoChange(false, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//volume changes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
|
@ -170,15 +229,19 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
SelectionsBTN.onClick.AddListener(delegate
|
SelectionsBTN.onClick.AddListener(delegate
|
||||||
{
|
{
|
||||||
timelineState.SetState(true, false, false);
|
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||||
});
|
});
|
||||||
TempoChangeBTN.onClick.AddListener(delegate
|
TempoChangeBTN.onClick.AddListener(delegate
|
||||||
{
|
{
|
||||||
timelineState.SetState(false, true, false);
|
timelineState.SetState(CurrentTimelineState.State.TempoChange);
|
||||||
});
|
});
|
||||||
MusicVolumeBTN.onClick.AddListener(delegate
|
MusicVolumeBTN.onClick.AddListener(delegate
|
||||||
{
|
{
|
||||||
timelineState.SetState(false, false, true);
|
timelineState.SetState(CurrentTimelineState.State.MusicVolume);
|
||||||
|
});
|
||||||
|
ChartSectionBTN.onClick.AddListener(delegate
|
||||||
|
{
|
||||||
|
timelineState.SetState(CurrentTimelineState.State.ChartSection);
|
||||||
});
|
});
|
||||||
|
|
||||||
Tooltip.AddTooltip(SongBeat.gameObject, "Current Beat");
|
Tooltip.AddTooltip(SongBeat.gameObject, "Current Beat");
|
||||||
|
@ -195,15 +258,21 @@ namespace HeavenStudio.Editor.Track
|
||||||
Tooltip.AddTooltip(SelectionsBTN.gameObject, "Tool: Selection <color=#adadad>[1]</color>");
|
Tooltip.AddTooltip(SelectionsBTN.gameObject, "Tool: Selection <color=#adadad>[1]</color>");
|
||||||
Tooltip.AddTooltip(TempoChangeBTN.gameObject, "Tool: Tempo Change <color=#adadad>[2]</color>");
|
Tooltip.AddTooltip(TempoChangeBTN.gameObject, "Tool: Tempo Change <color=#adadad>[2]</color>");
|
||||||
Tooltip.AddTooltip(MusicVolumeBTN.gameObject, "Tool: Music Volume <color=#adadad>[3]</color>");
|
Tooltip.AddTooltip(MusicVolumeBTN.gameObject, "Tool: Music Volume <color=#adadad>[3]</color>");
|
||||||
|
Tooltip.AddTooltip(ChartSectionBTN.gameObject, "Tool: Beatmap Sections <color=#adadad>[4]</color>");
|
||||||
|
|
||||||
|
Tooltip.AddTooltip(StartingTempoSpecialAll.gameObject, "Starting Tempo (BPM)");
|
||||||
|
Tooltip.AddTooltip(StartingTempoSpecialTempo.gameObject, "Starting Tempo (BPM)");
|
||||||
|
Tooltip.AddTooltip(StartingVolumeSpecialVolume.gameObject, "Starting Volume (%)");
|
||||||
|
|
||||||
Tooltip.AddTooltip(PlaybackSpeed.gameObject, "The preview's playback speed. Right click to reset to 1.0");
|
Tooltip.AddTooltip(PlaybackSpeed.gameObject, "The preview's playback speed. Right click to reset to 1.0");
|
||||||
|
|
||||||
SetTimeButtonColors(true, false, false);
|
SetTimeButtonColors(true, false, false);
|
||||||
MetronomeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
MetronomeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||||
|
|
||||||
timelineState.SetState(true, false, false);
|
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||||
|
|
||||||
AutoBtnUpdate();
|
AutoBtnUpdate();
|
||||||
|
GameManager.instance.onSectionChange += OnSectionChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FitToSong()
|
public void FitToSong()
|
||||||
|
@ -269,6 +338,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
SongBeat.text = $"Beat {string.Format("{0:0.000}", Conductor.instance.songPositionInBeats)}";
|
SongBeat.text = $"Beat {string.Format("{0:0.000}", Conductor.instance.songPositionInBeats)}";
|
||||||
SongPos.text = FormatTime(Conductor.instance.songPosition);
|
SongPos.text = FormatTime(Conductor.instance.songPosition);
|
||||||
}
|
}
|
||||||
|
TimelineSectionProgress.value = GameManager.instance.sectionProgress;
|
||||||
|
|
||||||
SliderControl();
|
SliderControl();
|
||||||
|
|
||||||
|
@ -300,15 +370,19 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.Alpha1))
|
if (Input.GetKeyDown(KeyCode.Alpha1))
|
||||||
{
|
{
|
||||||
timelineState.SetState(true, false, false);
|
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.Alpha2))
|
else if (Input.GetKeyDown(KeyCode.Alpha2))
|
||||||
{
|
{
|
||||||
timelineState.SetState(false, true, false);
|
timelineState.SetState(CurrentTimelineState.State.TempoChange);
|
||||||
}
|
}
|
||||||
else if (Input.GetKeyDown(KeyCode.Alpha3))
|
else if (Input.GetKeyDown(KeyCode.Alpha3))
|
||||||
{
|
{
|
||||||
timelineState.SetState(false, false, true);
|
timelineState.SetState(CurrentTimelineState.State.MusicVolume);
|
||||||
|
}
|
||||||
|
else if (Input.GetKeyDown(KeyCode.Alpha4))
|
||||||
|
{
|
||||||
|
timelineState.SetState(CurrentTimelineState.State.ChartSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,7 +571,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
public bool CheckIfMouseInTimeline()
|
public bool CheckIfMouseInTimeline()
|
||||||
{
|
{
|
||||||
return (this.gameObject.activeSelf && RectTransformUtility.RectangleContainsScreenPoint(TimelineContent.transform.parent.gameObject.GetComponent<RectTransform>(), Input.mousePosition, Editor.instance.EditorCamera));
|
return (this.gameObject.activeSelf && RectTransformUtility.RectangleContainsScreenPoint(TimelineEventGrid, Input.mousePosition, Editor.instance.EditorCamera));
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -683,6 +757,95 @@ namespace HeavenStudio.Editor.Track
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateOffsetText()
|
||||||
|
{
|
||||||
|
FirstBeatOffset.text = (GameManager.instance.Beatmap.firstBeatOffset * 1000f).ToString("G");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateOffsetFromText()
|
||||||
|
{
|
||||||
|
// Failsafe against empty string.
|
||||||
|
if (String.IsNullOrEmpty(FirstBeatOffset.text))
|
||||||
|
FirstBeatOffset.text = "0";
|
||||||
|
|
||||||
|
// Convert ms to s.
|
||||||
|
var newOffset = Convert.ToSingle(FirstBeatOffset.text) / 1000f;
|
||||||
|
|
||||||
|
// Limit decimal places to 4.
|
||||||
|
newOffset = (float)System.Math.Round(newOffset, 4);
|
||||||
|
|
||||||
|
GameManager.instance.Beatmap.firstBeatOffset = newOffset;
|
||||||
|
|
||||||
|
UpdateOffsetText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStartingBPMText()
|
||||||
|
{
|
||||||
|
StartingTempoSpecialAll.text = GameManager.instance.Beatmap.bpm.ToString("G");
|
||||||
|
StartingTempoSpecialTempo.text = StartingTempoSpecialAll.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStartingBPMFromText(bool all)
|
||||||
|
{
|
||||||
|
string text = all ? StartingTempoSpecialAll.text : StartingTempoSpecialTempo.text;
|
||||||
|
// Failsafe against empty string.
|
||||||
|
if (String.IsNullOrEmpty(text))
|
||||||
|
text = "120";
|
||||||
|
|
||||||
|
var newBPM = Convert.ToDouble(text);
|
||||||
|
|
||||||
|
// Failsafe against negative BPM.
|
||||||
|
if (newBPM < 1f)
|
||||||
|
{
|
||||||
|
text = "1";
|
||||||
|
newBPM = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit decimal places to 4.
|
||||||
|
newBPM = System.Math.Round(newBPM, 4);
|
||||||
|
|
||||||
|
GameManager.instance.Beatmap.bpm = (float) newBPM;
|
||||||
|
|
||||||
|
// In case the newBPM ended up differing from the inputted string.
|
||||||
|
UpdateStartingBPMText();
|
||||||
|
|
||||||
|
Timeline.instance.FitToSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStartingVolText()
|
||||||
|
{
|
||||||
|
StartingVolumeSpecialVolume.text = (GameManager.instance.Beatmap.musicVolume).ToString("G");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStartingVolFromText()
|
||||||
|
{
|
||||||
|
// Failsafe against empty string.
|
||||||
|
if (String.IsNullOrEmpty(StartingVolumeSpecialVolume.text))
|
||||||
|
StartingVolumeSpecialVolume.text = "100";
|
||||||
|
|
||||||
|
var newVol = Convert.ToInt32(StartingVolumeSpecialVolume.text);
|
||||||
|
newVol = Mathf.Clamp(newVol, 0, 100);
|
||||||
|
|
||||||
|
GameManager.instance.Beatmap.musicVolume = newVol;
|
||||||
|
|
||||||
|
UpdateStartingVolText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSectionChange(DynamicBeatmap.ChartSection section)
|
||||||
|
{
|
||||||
|
if (section == null)
|
||||||
|
{
|
||||||
|
TimelineSectionDisplay.SetActive(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!TimelineSectionDisplay.activeSelf)
|
||||||
|
TimelineSectionDisplay.SetActive(true);
|
||||||
|
TimelineSectionText.text = section.sectionName;
|
||||||
|
TimelineSectionProgress.value = GameManager.instance.sectionProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Commands
|
#region Commands
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
private float startPosY;
|
private float startPosY;
|
||||||
|
|
||||||
private Vector3 lastPos;
|
private Vector3 lastPos;
|
||||||
public Vector2 lastPos_;
|
public Vector2 moveStartPos;
|
||||||
private RectTransform rectTransform;
|
private RectTransform rectTransform;
|
||||||
|
|
||||||
[Header("Components")]
|
[Header("Components")]
|
||||||
|
@ -50,7 +50,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
lastPos_ = transform.localPosition;
|
moveStartPos = transform.localPosition;
|
||||||
|
|
||||||
rectTransform = GetComponent<RectTransform>();
|
rectTransform = GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
@ -163,13 +163,16 @@ namespace HeavenStudio.Editor.Track
|
||||||
this.wasDuplicated = false;
|
this.wasDuplicated = false;
|
||||||
this.moving = false;
|
this.moving = false;
|
||||||
|
|
||||||
|
transform.localPosition = moveStartPos;
|
||||||
|
OnComplete(false);
|
||||||
|
|
||||||
var te = Timeline.instance.CopyEventObject(this);
|
var te = Timeline.instance.CopyEventObject(this);
|
||||||
|
|
||||||
Selections.instance.DragSelect(te);
|
Selections.instance.DragSelect(te);
|
||||||
|
|
||||||
te.wasDuplicated = true;
|
te.wasDuplicated = true;
|
||||||
te.transform.localPosition = transform.localPosition;
|
te.transform.localPosition = transform.localPosition;
|
||||||
te.lastPos_ = transform.localPosition;
|
te.moveStartPos = transform.localPosition;
|
||||||
|
|
||||||
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -179,12 +182,11 @@ namespace HeavenStudio.Editor.Track
|
||||||
|
|
||||||
te.moving = true;
|
te.moving = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lastPos_ = transform.localPosition;
|
|
||||||
|
|
||||||
this.transform.position = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY - 0.40f, 0);
|
this.transform.position = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY - 0.40f, 0);
|
||||||
this.transform.localPosition = new Vector3(Mathf.Max(Mathp.Round2Nearest(this.transform.localPosition.x, Timeline.SnapInterval()), 0), Timeline.instance.SnapToLayer(this.transform.localPosition.y));
|
this.transform.localPosition = new Vector3(Mathf.Max(Mathp.Round2Nearest(this.transform.localPosition.x, Timeline.SnapInterval()), 0), Timeline.instance.SnapToLayer(this.transform.localPosition.y));
|
||||||
|
}
|
||||||
|
|
||||||
if (lastPos != transform.localPosition)
|
if (lastPos != transform.localPosition)
|
||||||
{
|
{
|
||||||
|
@ -281,7 +283,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
{
|
{
|
||||||
if (selected && Timeline.instance.timelineState.selected)
|
if (selected && Timeline.instance.timelineState.selected)
|
||||||
{
|
{
|
||||||
lastPos_ = transform.localPosition;
|
moveStartPos = transform.localPosition;
|
||||||
|
|
||||||
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +316,7 @@ namespace HeavenStudio.Editor.Track
|
||||||
if (eligibleToMove)
|
if (eligibleToMove)
|
||||||
{
|
{
|
||||||
OnComplete(true);
|
OnComplete(true);
|
||||||
|
moveStartPos = transform.localPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
moving = false;
|
moving = false;
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,8 +5,11 @@
|
||||||
"name": "Heaven Studio Default Editor Theme",
|
"name": "Heaven Studio Default Editor Theme",
|
||||||
|
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"SpecialLayersCol": "f06d60",
|
||||||
"TempoLayerCol": "6cbcc4",
|
"TempoLayerCol": "6cbcc4",
|
||||||
"MusicLayerCol": "a663cc",
|
"MusicLayerCol": "a663cc",
|
||||||
|
"SectionLayerCol": "ed9b2f",
|
||||||
|
//A7F085
|
||||||
|
|
||||||
"Layer1Col": "ef476f",
|
"Layer1Col": "ef476f",
|
||||||
"Layer2Col": "f5813d",
|
"Layer2Col": "f5813d",
|
||||||
|
|
|
@ -8,8 +8,8 @@ AudioManager:
|
||||||
Rolloff Scale: 1
|
Rolloff Scale: 1
|
||||||
Doppler Factor: 1
|
Doppler Factor: 1
|
||||||
Default Speaker Mode: 2
|
Default Speaker Mode: 2
|
||||||
m_SampleRate: 96000
|
m_SampleRate: 48000
|
||||||
m_DSPBufferSize: 1024
|
m_DSPBufferSize: 512
|
||||||
m_VirtualVoiceCount: 512
|
m_VirtualVoiceCount: 512
|
||||||
m_RealVoiceCount: 32
|
m_RealVoiceCount: 32
|
||||||
m_EnableOutputSuspension: 1
|
m_EnableOutputSuspension: 1
|
||||||
|
@ -17,4 +17,4 @@ AudioManager:
|
||||||
m_AmbisonicDecoderPlugin:
|
m_AmbisonicDecoderPlugin:
|
||||||
m_DisableAudio: 0
|
m_DisableAudio: 0
|
||||||
m_VirtualizeEffects: 1
|
m_VirtualizeEffects: 1
|
||||||
m_RequestedDSPBufferSize: 0
|
m_RequestedDSPBufferSize: 512
|
||||||
|
|
|
@ -320,7 +320,9 @@ PlayerSettings:
|
||||||
Android: 1
|
Android: 1
|
||||||
iPhone: 1
|
iPhone: 1
|
||||||
tvOS: 1
|
tvOS: 1
|
||||||
m_BuildTargetGroupLightmapEncodingQuality: []
|
m_BuildTargetGroupLightmapEncodingQuality:
|
||||||
|
- m_BuildTarget: Standalone
|
||||||
|
m_EncodingQuality: 1
|
||||||
m_BuildTargetGroupLightmapSettings: []
|
m_BuildTargetGroupLightmapSettings: []
|
||||||
m_BuildTargetNormalMapEncoding: []
|
m_BuildTargetNormalMapEncoding: []
|
||||||
playModeTestRunnerEnabled: 0
|
playModeTestRunnerEnabled: 0
|
||||||
|
|
Loading…
Reference in a new issue