mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-10 03:35:10 +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
|
||||
private float time;
|
||||
|
||||
double lastAbsTime;
|
||||
|
||||
// an AudioSource attached to this GameObject that will play the music.
|
||||
public AudioSource musicSource;
|
||||
|
||||
|
@ -140,6 +142,7 @@ namespace HeavenStudio
|
|||
musicSource.PlayScheduled(AudioSettings.dspTime);
|
||||
}
|
||||
}
|
||||
lastAbsTime = Time.realtimeSinceStartupAsDouble;
|
||||
|
||||
// GameManager.instance.SetCurrentEventToClosest(songPositionInBeats);
|
||||
}
|
||||
|
@ -172,7 +175,9 @@ namespace HeavenStudio
|
|||
|
||||
if (isPlaying)
|
||||
{
|
||||
var dt = Time.unscaledDeltaTime * musicSource.pitch;
|
||||
double absTime = Time.realtimeSinceStartupAsDouble;
|
||||
float dt = (float) (absTime - lastAbsTime) * musicSource.pitch;
|
||||
lastAbsTime = absTime;
|
||||
|
||||
time += dt;
|
||||
|
||||
|
@ -344,7 +349,7 @@ namespace HeavenStudio
|
|||
secPerBeat = 60f / songBpm;
|
||||
}
|
||||
|
||||
public void SetVolume(int percent)
|
||||
public void SetVolume(float percent)
|
||||
{
|
||||
musicSource.volume = percent / 100f;
|
||||
}
|
||||
|
|
|
@ -31,19 +31,28 @@ namespace HeavenStudio
|
|||
Coroutine currentGameSwitchIE;
|
||||
|
||||
[Header("Properties")]
|
||||
public int currentEvent, currentTempoEvent, currentPreEvent, currentPreSwitch;
|
||||
public int currentEvent, currentTempoEvent, currentVolumeEvent, currentSectionEvent,
|
||||
currentPreEvent, currentPreSwitch;
|
||||
public float endBeat;
|
||||
public float startOffset;
|
||||
public bool playOnStart;
|
||||
public float startBeat;
|
||||
[NonSerialized] public GameObject currentGameO;
|
||||
public bool autoplay;
|
||||
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()
|
||||
{
|
||||
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; }
|
||||
|
@ -218,22 +227,47 @@ namespace HeavenStudio
|
|||
return;
|
||||
if (!Conductor.instance.isPlaying)
|
||||
return;
|
||||
|
||||
|
||||
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
||||
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
|
||||
|
||||
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
|
||||
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])
|
||||
{
|
||||
// Debug.Log("Tempo Change at " + Conductor.instance.songPositionInBeats + " of bpm " + DynamicBeatmap.tempoChanges[currentTempoEvent].tempo);
|
||||
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
|
||||
Conductor.instance.timeSinceLastTempoChange = Time.time;
|
||||
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;
|
||||
//seek ahead to preload games that have assetbundles
|
||||
SeekAheadAndPreload(Conductor.instance.songPositionInBeats, seekTime);
|
||||
|
@ -273,6 +307,8 @@ namespace HeavenStudio
|
|||
// currentEvent += gameManagerEntities.Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ToggleInputs(bool inputs)
|
||||
|
@ -305,6 +341,10 @@ namespace HeavenStudio
|
|||
}
|
||||
|
||||
KillAllSounds();
|
||||
|
||||
Minigame miniGame = currentGameO.GetComponent<Minigame>();
|
||||
if (miniGame != null)
|
||||
miniGame.OnPlay(beat);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
|
@ -389,10 +429,17 @@ namespace HeavenStudio
|
|||
{
|
||||
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
|
||||
{
|
||||
SetGame("noGame");
|
||||
endBeat = Conductor.instance.SongLengthInBeats();
|
||||
}
|
||||
|
||||
if (Beatmap.tempoChanges.Count > 0)
|
||||
|
@ -413,6 +460,39 @@ namespace HeavenStudio
|
|||
// 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ MonoImporter:
|
|||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -43
|
||||
executionOrder: -44
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
|
|
@ -135,6 +135,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
|
|||
float yWeight = -(yMul*yMul) + 1f;
|
||||
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);
|
||||
animator.Play("FanJump", -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -446,8 +446,24 @@ namespace HeavenStudio.Games
|
|||
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()
|
||||
{
|
||||
var cond = Conductor.instance;
|
||||
|
||||
GameCamera.additionalPosition = cameraPosition - GameCamera.defaultPosition;
|
||||
bgEffectAnimator = BGEffect.GetComponent<Animator>();
|
||||
bgEffectSpriteRenderer = BGEffect.GetComponent<SpriteRenderer>();
|
||||
|
@ -456,7 +472,8 @@ namespace HeavenStudio.Games
|
|||
bgBloodRenderer = BGBlood.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);
|
||||
UpdateMaterialColour(BodyColor, HighlightColor, ItemColor);
|
||||
ToggleBop(WantBop);
|
||||
|
@ -806,10 +823,10 @@ namespace HeavenStudio.Games
|
|||
var e = bgfx[i];
|
||||
if (e.beat > beat)
|
||||
break;
|
||||
SetBgAndShadowCol(e.beat, e.length, e["type"], e["type2"], e["colorA"], e["colorB"], e["type3"]);
|
||||
SetBgTexture(e["type4"], e["type5"], e["colorC"], e["colorD"]);
|
||||
SetBgEffectsUnloaded(e.beat, e.length, e["type"], e["type2"], e["colorA"], e["colorB"], e["type3"], e["type4"], e["type5"], e["colorC"], e["colorD"]);
|
||||
}
|
||||
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++)
|
||||
{
|
||||
var e = camfx[i];
|
||||
|
@ -817,17 +834,16 @@ namespace HeavenStudio.Games
|
|||
break;
|
||||
DoSpecialCamera(e.beat, e.length, e["toggle"]);
|
||||
}
|
||||
// has issues when creating a new hitx entity so this is deactivated for now
|
||||
// var hitx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/hitX");
|
||||
// for (int i = 0; i < hitx.Count; i++)
|
||||
// {
|
||||
// var e = hitx[i];
|
||||
// if (e.beat > beat)
|
||||
// break;
|
||||
// Debug.Log("hitx");
|
||||
// DoWord(e.beat, e["type"], false);
|
||||
// }
|
||||
|
||||
var objfx = GameManager.instance.Beatmap.entities.FindAll(en => en.datamodel == "karateman/set object colors");
|
||||
for (int i = 0; i < objfx.Count; i++)
|
||||
{
|
||||
var e = objfx[i];
|
||||
if (e.beat > beat)
|
||||
break;
|
||||
UpdateMaterialColour(e["colorA"], e["colorB"], e["colorC"]);
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace HeavenStudio.Games
|
|||
{
|
||||
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>();
|
||||
|
||||
[System.Serializable]
|
||||
|
@ -132,7 +132,6 @@ namespace HeavenStudio.Games
|
|||
{
|
||||
PlayerActionEvent input = GetClosestScheduledInput();
|
||||
if (input == null) return false;
|
||||
|
||||
return input.IsExpectingInputNow();
|
||||
}
|
||||
|
||||
|
@ -190,6 +189,11 @@ namespace HeavenStudio.Games
|
|||
|
||||
}
|
||||
|
||||
public virtual void OnPlay(float beat)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int MultipleEventsAtOnce()
|
||||
{
|
||||
int sameTime = 0;
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace HeavenStudio.Games
|
|||
this.canHit = canHit;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -4,7 +4,7 @@ MonoImporter:
|
|||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
executionOrder: 5
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace HeavenStudio
|
|||
DontDestroyOnLoad(this.gameObject);
|
||||
instance = this;
|
||||
Starpelly.OS.ChangeWindowTitle("Heaven Studio DEMO");
|
||||
QualitySettings.maxQueuedFrames = 1;
|
||||
PlayerInput.InitInputControllers();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace HeavenStudio.Editor.Commands
|
|||
{
|
||||
Pos p = new Pos();
|
||||
p.eventObj = eventObjs[i];
|
||||
p.lastPos_ = eventObjs[i].lastPos_;
|
||||
p.lastPos_ = eventObjs[i].moveStartPos;
|
||||
p.previousPos = eventObjs[i].transform.localPosition;
|
||||
this.pos.Add(p);
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace HeavenStudio.Editor
|
|||
Fullscreen();
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Delete))
|
||||
if (Input.GetKeyDown(KeyCode.Delete) || Input.GetKeyDown(KeyCode.Backspace))
|
||||
{
|
||||
List<TimelineEventObj> ev = new List<TimelineEventObj>();
|
||||
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);
|
||||
Timeline.instance.LoadRemix();
|
||||
Timeline.instance.TempoInfo.UpdateStartingBPMText();
|
||||
Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
|
||||
Timeline.instance.TempoInfo.UpdateOffsetText();
|
||||
// Timeline.instance.SpecialInfo.UpdateStartingBPMText();
|
||||
// Timeline.instance.VolumeInfo.UpdateStartingVolumeText();
|
||||
// Timeline.instance.SpecialInfo.UpdateOffsetText();
|
||||
Timeline.FitToSong();
|
||||
|
||||
currentRemixPath = string.Empty;
|
||||
|
|
|
@ -19,8 +19,10 @@ namespace HeavenStudio.Editor
|
|||
|
||||
[Header("Components")]
|
||||
[SerializeField] private Image layer;
|
||||
[SerializeField] private Image specialLayers;
|
||||
[SerializeField] private Image tempoLayer;
|
||||
[SerializeField] private Image musicLayer;
|
||||
[SerializeField] private Image sectionLayer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
@ -29,10 +31,14 @@ namespace HeavenStudio.Editor
|
|||
|
||||
private void Start()
|
||||
{
|
||||
specialLayers.GetComponent<Image>().color = theme.properties.SpecialLayersCol.Hex2RGB();
|
||||
tempoLayer.GetComponent<Image>().color = theme.properties.TempoLayerCol.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(musicLayer.gameObject, $"Music Volume Track");
|
||||
Tooltip.AddTooltip(sectionLayer.gameObject, $"Remix Sections Track");
|
||||
|
||||
|
||||
layer.gameObject.SetActive(false);
|
||||
|
|
|
@ -183,10 +183,11 @@ namespace HeavenStudio.Editor
|
|||
|
||||
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)
|
||||
{
|
||||
Timeline.instance.timelineState.SetState(Timeline.CurrentTimelineState.State.Selection);
|
||||
dragTimes++;
|
||||
|
||||
TimelineEventObj eventObj;
|
||||
|
|
|
@ -12,8 +12,10 @@ namespace HeavenStudio.Editor
|
|||
[Serializable]
|
||||
public class Properties
|
||||
{
|
||||
public string SpecialLayersCol;
|
||||
public string TempoLayerCol;
|
||||
public string MusicLayerCol;
|
||||
public string SectionLayerCol;
|
||||
|
||||
public string Layer1Col;
|
||||
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
|
||||
guid: ea7831ec549a9984c8c3e5afd98bac2f
|
||||
guid: 7e5d39fb5bc171f44ba013cf8e37fdd2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
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
|
||||
guid: 10dd19278a802c24fbeb39d1ccb23219
|
||||
guid: 364cfb513d7ef744cb0d4828804188e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
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
|
||||
guid: 86bb8f2f290876a4387f1ea6fedf332b
|
||||
guid: 84c1633846a16fb42baa226572335fae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
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 UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
@ -34,45 +34,109 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
public class CurrentTimelineState
|
||||
{
|
||||
public bool selected;
|
||||
public bool tempoChange;
|
||||
public bool musicVolume;
|
||||
public enum State
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (Conductor.instance.NotStopped()) return;
|
||||
|
||||
this.selected = selected;
|
||||
this.tempoChange = tempoChange;
|
||||
this.musicVolume = musicVolume;
|
||||
|
||||
if (selected)
|
||||
{
|
||||
currentState = State.Selection;
|
||||
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||
instance.SelectionsBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||
}
|
||||
else
|
||||
instance.SelectionsBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||
if (tempoChange)
|
||||
{
|
||||
currentState = State.TempoChange;
|
||||
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||
instance.TempoChangeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||
}
|
||||
else
|
||||
instance.TempoChangeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||
if (musicVolume)
|
||||
{
|
||||
currentState = State.MusicVolume;
|
||||
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.white;
|
||||
instance.MusicVolumeBTN.GetComponent<TabButton>().Invoke("OnClick", 0);
|
||||
}
|
||||
else
|
||||
instance.MusicVolumeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||
|
||||
}
|
||||
|
||||
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")]
|
||||
[SerializeField] private RectTransform TimelineSlider;
|
||||
[SerializeField] private RectTransform TimelineGridSelect;
|
||||
[SerializeField] private RectTransform TimelineEventGrid;
|
||||
[SerializeField] private TMP_Text TimelinePlaybackBeat;
|
||||
public RectTransform TimelineContent;
|
||||
[SerializeField] private RectTransform TimelineSongPosLineRef;
|
||||
[SerializeField] private RectTransform TimelineEventObjRef;
|
||||
[SerializeField] private RectTransform LayersRect;
|
||||
|
||||
public TempoTimeline TempoInfo;
|
||||
public VolumeTimeline VolumeInfo;
|
||||
[SerializeField] private GameObject TimelineSectionDisplay;
|
||||
[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;
|
||||
|
||||
[Header("Timeline Playbar")]
|
||||
|
@ -84,6 +148,7 @@ namespace HeavenStudio.Editor.Track
|
|||
public Button SelectionsBTN;
|
||||
public Button TempoChangeBTN;
|
||||
public Button MusicVolumeBTN;
|
||||
public Button ChartSectionBTN;
|
||||
public Slider PlaybackSpeed;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
//tempo changes
|
||||
TempoInfo.ClearTempoTimeline();
|
||||
for (int i = 0; i < GameManager.instance.Beatmap.tempoChanges.Count; i++)
|
||||
{
|
||||
var t = GameManager.instance.Beatmap.tempoChanges[i];
|
||||
|
||||
TempoInfo.AddTempoChange(false, t);
|
||||
}
|
||||
|
||||
//volume changes
|
||||
SpecialInfo.Setup();
|
||||
UpdateOffsetText();
|
||||
UpdateStartingBPMText();
|
||||
UpdateStartingVolText();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
|
@ -170,15 +229,19 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
SelectionsBTN.onClick.AddListener(delegate
|
||||
{
|
||||
timelineState.SetState(true, false, false);
|
||||
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||
});
|
||||
TempoChangeBTN.onClick.AddListener(delegate
|
||||
{
|
||||
timelineState.SetState(false, true, false);
|
||||
timelineState.SetState(CurrentTimelineState.State.TempoChange);
|
||||
});
|
||||
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");
|
||||
|
@ -195,15 +258,21 @@ namespace HeavenStudio.Editor.Track
|
|||
Tooltip.AddTooltip(SelectionsBTN.gameObject, "Tool: Selection <color=#adadad>[1]</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(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");
|
||||
|
||||
SetTimeButtonColors(true, false, false);
|
||||
MetronomeBTN.transform.GetChild(0).GetComponent<Image>().color = Color.gray;
|
||||
|
||||
timelineState.SetState(true, false, false);
|
||||
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||
|
||||
AutoBtnUpdate();
|
||||
GameManager.instance.onSectionChange += OnSectionChange;
|
||||
}
|
||||
|
||||
public void FitToSong()
|
||||
|
@ -269,6 +338,7 @@ namespace HeavenStudio.Editor.Track
|
|||
SongBeat.text = $"Beat {string.Format("{0:0.000}", Conductor.instance.songPositionInBeats)}";
|
||||
SongPos.text = FormatTime(Conductor.instance.songPosition);
|
||||
}
|
||||
TimelineSectionProgress.value = GameManager.instance.sectionProgress;
|
||||
|
||||
SliderControl();
|
||||
|
||||
|
@ -300,15 +370,19 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
if (Input.GetKeyDown(KeyCode.Alpha1))
|
||||
{
|
||||
timelineState.SetState(true, false, false);
|
||||
timelineState.SetState(CurrentTimelineState.State.Selection);
|
||||
}
|
||||
else if (Input.GetKeyDown(KeyCode.Alpha2))
|
||||
{
|
||||
timelineState.SetState(false, true, false);
|
||||
timelineState.SetState(CurrentTimelineState.State.TempoChange);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -350,7 +424,7 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
TimelineContent.transform.localPosition = new Vector3(Mathf.Clamp(TimelineContent.transform.localPosition.x, Mathf.NegativeInfinity, 0), TimelineContent.transform.localPosition.y);
|
||||
|
||||
CurrentTempo.text = $" = {Conductor.instance.songBpm}";
|
||||
CurrentTempo.text = $" = {Conductor.instance.songBpm}";
|
||||
|
||||
LayersRect.GetWorldCorners(LayerCorners);
|
||||
}
|
||||
|
@ -497,7 +571,7 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
#region Commands
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace HeavenStudio.Editor.Track
|
|||
private float startPosY;
|
||||
|
||||
private Vector3 lastPos;
|
||||
public Vector2 lastPos_;
|
||||
public Vector2 moveStartPos;
|
||||
private RectTransform rectTransform;
|
||||
|
||||
[Header("Components")]
|
||||
|
@ -50,7 +50,7 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
private void Start()
|
||||
{
|
||||
lastPos_ = transform.localPosition;
|
||||
moveStartPos = transform.localPosition;
|
||||
|
||||
rectTransform = GetComponent<RectTransform>();
|
||||
|
||||
|
@ -163,13 +163,16 @@ namespace HeavenStudio.Editor.Track
|
|||
this.wasDuplicated = false;
|
||||
this.moving = false;
|
||||
|
||||
transform.localPosition = moveStartPos;
|
||||
OnComplete(false);
|
||||
|
||||
var te = Timeline.instance.CopyEventObject(this);
|
||||
|
||||
Selections.instance.DragSelect(te);
|
||||
|
||||
te.wasDuplicated = true;
|
||||
te.transform.localPosition = transform.localPosition;
|
||||
te.lastPos_ = transform.localPosition;
|
||||
te.moveStartPos = transform.localPosition;
|
||||
|
||||
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
||||
{
|
||||
|
@ -179,12 +182,11 @@ namespace HeavenStudio.Editor.Track
|
|||
|
||||
te.moving = true;
|
||||
}
|
||||
|
||||
|
||||
lastPos_ = transform.localPosition;
|
||||
|
||||
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));
|
||||
else
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
if (lastPos != transform.localPosition)
|
||||
{
|
||||
|
@ -281,7 +283,7 @@ namespace HeavenStudio.Editor.Track
|
|||
{
|
||||
if (selected && Timeline.instance.timelineState.selected)
|
||||
{
|
||||
lastPos_ = transform.localPosition;
|
||||
moveStartPos = transform.localPosition;
|
||||
|
||||
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
|
||||
{
|
||||
|
@ -314,6 +316,7 @@ namespace HeavenStudio.Editor.Track
|
|||
if (eligibleToMove)
|
||||
{
|
||||
OnComplete(true);
|
||||
moveStartPos = transform.localPosition;
|
||||
}
|
||||
|
||||
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",
|
||||
|
||||
"properties": {
|
||||
"SpecialLayersCol": "f06d60",
|
||||
"TempoLayerCol": "6cbcc4",
|
||||
"MusicLayerCol": "a663cc",
|
||||
"SectionLayerCol": "ed9b2f",
|
||||
//A7F085
|
||||
|
||||
"Layer1Col": "ef476f",
|
||||
"Layer2Col": "f5813d",
|
||||
|
|
|
@ -8,8 +8,8 @@ AudioManager:
|
|||
Rolloff Scale: 1
|
||||
Doppler Factor: 1
|
||||
Default Speaker Mode: 2
|
||||
m_SampleRate: 96000
|
||||
m_DSPBufferSize: 1024
|
||||
m_SampleRate: 48000
|
||||
m_DSPBufferSize: 512
|
||||
m_VirtualVoiceCount: 512
|
||||
m_RealVoiceCount: 32
|
||||
m_EnableOutputSuspension: 1
|
||||
|
@ -17,4 +17,4 @@ AudioManager:
|
|||
m_AmbisonicDecoderPlugin:
|
||||
m_DisableAudio: 0
|
||||
m_VirtualizeEffects: 1
|
||||
m_RequestedDSPBufferSize: 0
|
||||
m_RequestedDSPBufferSize: 512
|
||||
|
|
|
@ -320,7 +320,9 @@ PlayerSettings:
|
|||
Android: 1
|
||||
iPhone: 1
|
||||
tvOS: 1
|
||||
m_BuildTargetGroupLightmapEncodingQuality: []
|
||||
m_BuildTargetGroupLightmapEncodingQuality:
|
||||
- m_BuildTarget: Standalone
|
||||
m_EncodingQuality: 1
|
||||
m_BuildTargetGroupLightmapSettings: []
|
||||
m_BuildTargetNormalMapEncoding: []
|
||||
playModeTestRunnerEnabled: 0
|
||||
|
|
Loading…
Reference in a new issue