public static float GetStageAlpha(Beatmap.Stage data) => Mathf.Lerp( Mathf.Clamp01( VanishDuration < FLOAT_GAP ? 1f : Mathf.Min(data.Time + data.Duration - MusicTime, MusicTime - data.Time) / VanishDuration ), 1f, MusicPlaying ? Abreast.value : 1f );
public static Vector2 GetStagePosition(Beatmap.Stage data, int stageIndex, float musicTime) { if (Abreast.value < 0.0001f) { return(GetNormalPos()); } else if (Abreast.value > 0.9999f) { return(GetAbreastPos()); } else { return(Vector2.Lerp(GetNormalPos(), GetAbreastPos(), Abreast.value)); } // === Func === Vector3 GetNormalPos() => new Vector2(data.X, data.Y) + Evaluate(data.Positions, musicTime - data.Time); Vector3 GetAbreastPos() { if (StageCount <= 1) { return(new Vector2(0.5f, 0f)); } else { return(new Vector2(Util.Remap(0, StageCount - 1, 0.5f - (Abreast.index * Abreast.width), 0.5f + ((StageCount - Abreast.index - 1f) * Abreast.width), stageIndex), 0f)); } } }
private void Update_Gizmos(Beatmap.Stage linkedStage, Beatmap.Note noteData, int noteIndex) { bool active = !(noteData is null) && noteData._Active && MusicTime < noteData.Time + noteData.Duration; // Label if (Label != null) { if (ShowIndexLabel && !MusicPlaying && active) { Label.gameObject.SetActive(true); Label.Text = noteData.SoundFxIndex <= 0 ? noteIndex.ToString() : (noteIndex.ToString() + " fx"); Label.transform.localRotation = MainRenderer.transform.localRotation; } else { Label.gameObject.SetActive(false); } } // Col TrySetColliderLayer(Duration <= FLOAT_GAP ? LayerID_Note : LayerID_Note_Hold); // ZLine bool zlineActive = ShowGrid && active && Abreast.value <0.5f && noteData.Z> 0.0005f; if (m_ZLineRenderer.gameObject.activeSelf != zlineActive) { m_ZLineRenderer.gameObject.SetActive(zlineActive); } // ZLine Color if (zlineActive) { m_ZLineRenderer.color = Color.Lerp( m_ZLineRenderer.color, Color.black * 0.2f, UnityEngine.Time.deltaTime * 1.4f ); } else { if (m_ZLineRenderer.color != Color.clear) { m_ZLineRenderer.color = Color.clear; } } // ZLine Scale if (zlineActive) { float zlineScaleY = GetNoteZ(noteData) * Stage.GetStageHeight(linkedStage) * ZoneMinMax.size; var zScale = m_ZLineRenderer.transform.localScale; if (Mathf.Abs(zScale.y - zlineScaleY) > 0.0001f) { zScale.y = zlineScaleY; m_ZLineRenderer.transform.localScale = zScale; } // ZLine Rot m_ZLineRenderer.transform.localRotation = MainRenderer.transform.localRotation * Quaternion.Euler(-90f, 0f, 0f); } }
private void Update_Movement(Beatmap.Stage linkedStage, Beatmap.Track trackData) { var(zoneMin, zoneMax, zoneSize, _) = ZoneMinMax; float trackWidth = GetTrackWidth(trackData); float stageWidth = Stage.GetStageWidth(linkedStage); float stageHeight = Stage.GetStageHeight(linkedStage); float stagePivotY = Stage.GetStagePivotY(linkedStage); float stageRotZ = Stage.GetStageWorldRotationZ(linkedStage); var stagePos = Stage.GetStagePosition(linkedStage, trackData.StageIndex); float rotX = GetTrackAngle(trackData); float trackX = GetTrackX(trackData); var pos = Stage.LocalToZone(trackX, 0f, 0f, stagePos, stageWidth, stageHeight, stagePivotY, stageRotZ); // Movement transform.position = Util.Vector3Lerp3(zoneMin, zoneMax, pos.x, pos.y); transform.localRotation = Quaternion.Euler(0f, 0f, stageRotZ) * Quaternion.Euler(rotX, 0, 0); ColSize = MainRenderer.transform.localScale = m_TrackTintRenderer.transform.localScale = new Vector3( zoneSize * trackWidth * stageWidth, zoneSize * stageHeight, 1f ); // Tray if (trackData.HasTray) { var traySize = GetRectSize(SkinType.Tray, trackData.ItemType, false, false); var judgeLineSize = GetRectSize(SkinType.JudgeLine, trackData.ItemType); var trayPos = LocalToZone( TrayX, judgeLineSize.y / 2f / stageHeight, 0f, stagePos, stageWidth, stageHeight, stagePivotY, stageRotZ, trackX, trackWidth, rotX ); m_TrayRenderer.transform.position = Util.Vector3Lerp3(zoneMin, zoneMax, trayPos.x, trayPos.y); m_TrayRenderer.transform.localScale = new Vector3(traySize.x, traySize.y, 1f); m_TrayRenderer.Scale = traySize; } // Renderer MainRenderer.RendererEnable = true; m_TrackTintRenderer.RendererEnable = true; m_TrackTintRenderer.ItemType = trackData.ItemType; MainRenderer.ItemType = trackData.ItemType; m_TrayRenderer.RendererEnable = trackData.HasTray; m_TrayRenderer.ItemType = trackData.ItemType; MainRenderer.Duration = m_TrayRenderer.Duration = m_TrackTintRenderer.Duration = Duration; MainRenderer.Scale = m_TrackTintRenderer.Scale = new Vector2(stageWidth * trackWidth, stageHeight); m_TrackTintRenderer.Tint = trackData.c_Tint = GetTrackColor(trackData); MainRenderer.Alpha = m_TrayRenderer.Alpha = Stage.GetStageAlpha(linkedStage) * GetTrackAlpha(trackData); m_TrackTintRenderer.Alpha *= MainRenderer.Alpha; MainRenderer.SetSortingLayer(SortingLayerID_Track, GetSortingOrder()); m_TrackTintRenderer.SetSortingLayer(SortingLayerID_TrackTint, GetSortingOrder()); m_TrayRenderer.SetSortingLayer(SortingLayerID_Tray, GetSortingOrder()); }
private void Update_Movement(Beatmap.Stage stageData, int stageIndex) { var(zoneMin, zoneMax, zoneSize, ratio) = ZoneMinMax; float width = GetStageWidth(stageData); float height = GetStageHeight(stageData); float pivotY = GetStagePivotY(stageData); var stagePos = GetStagePosition(stageData, stageIndex); var judgeLineSize = GetRectSize(SkinType.JudgeLine, stageData.ItemType); var stageColor = GetStageColor(stageData); float stageAlpha = GetStageAlpha(stageData) * stageColor.a; var stagePosition = Util.Vector3Lerp3(zoneMin, zoneMax, stagePos.x, stagePos.y); var stageRotation = Quaternion.Euler(0f, 0f, GetStageWorldRotationZ(stageData)); var rendererPosition = new Vector3(0f, -height * pivotY * zoneSize, 0f); float judgeWidth = InfiniteJudgeLine ? Util.GetMaxDistanceBetweenLineAndRect( stagePosition, stagePosition + stageRotation * Vector3.right, zoneMin, new Vector2(zoneMax.x, zoneMin.y + zoneSize / ratio) ) * 2f : zoneSize * width; // Movement transform.position = stagePosition; transform.localRotation = stageRotation; ColSize = MainRenderer.transform.localScale = new Vector3(zoneSize * width, Mathf.Max(zoneSize * height, 0.00001f), 1f); MainRenderer.transform.localPosition = rendererPosition; m_JudgelineRenderer.transform.localPosition = rendererPosition; m_JudgelineRenderer.transform.localScale = new Vector3(judgeWidth, Mathf.Max(zoneSize * judgeLineSize.y, 0.00001f), 1f); ColPivotY = pivotY; // Renderer MainRenderer.RendererEnable = true; MainRenderer.ItemType = stageData.ItemType; MainRenderer.Scale = new Vector2(width, height); MainRenderer.Duration = Duration; MainRenderer.Tint = stageColor; MainRenderer.Alpha = stageAlpha; MainRenderer.SetSortingLayer(SortingLayerID_Stage, GetSortingOrder()); m_JudgelineRenderer.RendererEnable = true; m_JudgelineRenderer.ItemType = stageData.ItemType; m_JudgelineRenderer.Tint = stageColor; m_JudgelineRenderer.Alpha = stageAlpha; m_JudgelineRenderer.Duration = Duration; m_JudgelineRenderer.Scale = new Vector2(judgeWidth, judgeLineSize.y); m_JudgelineRenderer.SetSortingLayer(SortingLayerID_Judge, GetSortingOrder()); }
public static float GetStageWidth(Beatmap.Stage data) => Mathf.Lerp( Mathf.Max(data.Width * Evaluate(data.Widths, MusicTime - data.Time, 1f), 0f), Abreast.width - ABREAST_GAP, Abreast.value );
public static float GetStageSpeed(Beatmap.Stage data) => Mathf.Lerp( data.Speed, 1f, Abreast.value );
public static Vector2 GetStagePosition(Beatmap.Stage data, int stageIndex) => GetStagePosition(data, stageIndex, MusicTime);
public static float GetStagePivotY(Beatmap.Stage data) => Mathf.Lerp( data.PivotY, 0f, Abreast.value );
private void LateUpdate() { var map = GetBeatmap(); if (map == null) { return; } // Static Stage var gene = GetGene(); int staticStageCount = gene.StaticConfigs_Stage.Length; if (staticStageCount > 0 && map.Stages.Count != staticStageCount) { var stages = map.stages; int count = stages.Count; if (count > staticStageCount) { while (stages.Count > staticStageCount) { stages.RemoveAt(stages.Count - 1); } } else if (count < staticStageCount) { var stage = new Beatmap.Stage(); FixStageLogic(map, gene, stage, stages.Count); stages.Add(stage); } } // Add Track For Trackless Stage if (!gene.TrackAccessable && gene.Config_Track.UseConfig) { var tracks = map.tracks; for (int i = 0; i < map.Stages.Count; i++) { var stage = map.stages[i]; if (stage.c_TrackCount == 0) { tracks.Add(new Beatmap.Track() { StageIndex = i, }); int count = tracks.Count; FixTrackLogic(map, gene, tracks[count - 1], count - 1); } } } // Static Track int staticTrackCount = gene.StaticConfigs_Track.Length; if (staticTrackCount > 0 && map.Tracks.Count != staticTrackCount) { var tracks = map.tracks; int count = tracks.Count; if (gene.TrackAccessable || !gene.Config_Track.UseConfig) { if (count > staticTrackCount) { while (tracks.Count > staticTrackCount) { tracks.RemoveAt(tracks.Count - 1); } } else if (count < staticTrackCount) { tracks.Add(new Beatmap.Track()); } } // Fix Track count = tracks.Count; for (int i = 0; i < count; i++) { FixTrackLogic(map, gene, tracks[i], i); } } }
private void FixStageLogic(Beatmap map, GeneData gene, Beatmap.Stage stage, int index) { var config = GetStageConfig(gene, index); if (config.UseConfig) { if (config.Time_Real.Active) { stage.time = (int)(config.Time_Real.Value * GetMusicDuration()); } if (config.Duration_Real.Active) { stage.duration = (int)(config.Duration_Real.Value * GetMusicDuration()); } if (config.ItemType.Active) { stage.itemType = config.ItemType.Value; } if (config.X.Active) { stage.x = config.X.Value; } if (config.Y.Active) { stage.y = config.Y.Value; } if (config.Rotation.Active) { stage.rotation = config.Rotation.Value; } if (config.Width.Active) { stage.width = config.Width.Value; } if (config.Height.Active) { stage.height = config.Height.Value; } if (config.PivotY.Active) { stage.pivotY = config.PivotY.Value; } if (config.Speed.Active) { stage.speed = config.Speed.Value; } if (!config.Motion_Pos) { stage.positions.Clear(); } if (!config.Motion_Rot) { stage.rotations.Clear(); } if (!config.Motion_Width) { stage.widths.Clear(); } if (!config.Motion_Height) { stage.heights.Clear(); } if (!config.Motion_Color) { stage.colors.Clear(); } // Tile Tracks if (config.TileTrack) { int currentTrackIndex = 0; int trackCount = map.Tracks.Count; int trackCountInStage = 0; for (int i = 0; i < trackCount; i++) { if (map.Tracks[i].StageIndex == index) { trackCountInStage++; } } for (int i = 0; i < trackCount && trackCountInStage > 0; i++) { var track = map.Tracks[i]; if (track.StageIndex != index) { continue; } int trackWidth = 1000 / trackCountInStage; track.width = trackWidth; track.x = (int)(((float)currentTrackIndex / trackCountInStage) * 1000f + (trackWidth / 2f)); currentTrackIndex++; } } // Add Track For Trackless Stage if (!gene.TrackAccessable) { } } }
public static float GetStageHeight(Beatmap.Stage data) => Mathf.Lerp( Mathf.Max(data.Height * Evaluate(data.Heights, MusicTime - data.Time, 1f), 0.00001f), Mathf.Clamp(1f / ZoneMinMax.ratio, 0f, 256f), Abreast.value );
private static bool GetStageActive(Beatmap.Stage data, int stageIndex) => Solo.active ? stageIndex == Solo.stage : Abreast.value >= 0.5f || (MusicTime >= data.Time && MusicTime <= data.Time + data.Duration);
public static Color GetStageColor(Beatmap.Stage data) => EvaluateColor( data.Colors, MusicTime - data.Time, PaletteColor(data.Color) );
public static float GetStageWorldRotationZ_Motion(Beatmap.Stage stageData) { return(Evaluate(stageData.Rotations, MusicTime - stageData.Time)); }
public static float GetStageWorldRotationZ(Beatmap.Stage stageData) => Mathf.LerpAngle( -Mathf.Repeat(stageData.Rotation + Evaluate(stageData.Rotations, MusicTime - stageData.Time), 360f), 0f, Abreast.value );
public static void UpdateCache(Beatmap.Stage stageData, int index, bool timerActive, float parentSpeed) { stageData._Active = GetStageActive(stageData, index); stageData._SpeedMuti = parentSpeed * stageData.Speed; stageData._TimerActive = timerActive; }
// Motion public static Vector2 GetStagePosition_Motion(Beatmap.Stage data) => Evaluate(data.Positions, MusicTime - data.Time);
public static float GetStageWidth_Motion(Beatmap.Stage data) => Evaluate(data.Widths, MusicTime - data.Time, 1f);
public static float GetStageHeight_Motion(Beatmap.Stage data) => Evaluate(data.Heights, MusicTime - data.Time, 1f);
private void Update_Movement(Beatmap.Stage linkedStage, Beatmap.Track linkedTrack, Beatmap.Note noteData, Beatmap.Note linkedNote) { var stagePos = Stage.GetStagePosition(linkedStage, linkedTrack.StageIndex); float stageWidth = Stage.GetStageWidth(linkedStage); float stagePivotY = Stage.GetStagePivotY(linkedStage); float stageHeight = Stage.GetStageHeight(linkedStage); float stageRotZ = Stage.GetStageWorldRotationZ(linkedStage); float trackX = Track.GetTrackX(linkedTrack); float trackWidth = Track.GetTrackWidth(linkedTrack); float trackAngle = Track.GetTrackAngle(linkedTrack); float gameOffset = GetGameDropOffset(noteData.TimingID, noteData._SpeedMuti); float noteY01 = MusicTime < Time ? (noteData._NoteDropStart - gameOffset) : 0f; float noteSizeY = noteData._NoteDropEnd - gameOffset - noteY01; var(zoneMin, zoneMax, zoneSize, _) = ZoneMinMax; bool isLink = linkedNote != null; bool activeSelf = GetNoteActive(noteData, null, noteData._AppearTime); float alpha = Stage.GetStageAlpha(linkedStage) * Track.GetTrackAlpha(linkedTrack) * Mathf.Clamp01(16f - noteY01 * 16f); bool highlighing = MusicTime > Time && MusicTime < Time + Duration; float noteZ = GetNoteZ(noteData); var tint = highlighing ? HighlightTints[(int)SkinType.Note] : WHITE_32; if (TintNote) { tint *= linkedTrack.c_Tint; } // Movement var noteZonePos = Track.LocalToZone( noteData.X, noteY01, noteZ, stagePos, stageWidth, stageHeight, stagePivotY, stageRotZ, trackX, trackWidth, trackAngle ); var noteRot = Quaternion.Euler(0f, 0f, stageRotZ) * Quaternion.Euler(trackAngle, 0f, 0f); var noteWorldPos = Util.Vector3Lerp3(zoneMin, zoneMax, noteZonePos.x, noteZonePos.y, noteZonePos.z); // Size var noteSize = GetRectSize(SkinType.Note, noteData.ItemType); float minHeight = GetMinHeight(SkinType.Note, noteData.ItemType); float noteScaleX = noteSize.x < 0f ? stageWidth * trackWidth * noteData.Width : noteSize.x; float noteScaleY_scaler = Mathf.Max(noteSizeY * stageHeight, minHeight); float noteScaleY = Mathf.Max(noteSizeY * stageHeight + minHeight, 0f); Vector3 zoneNoteScale = new Vector3( zoneSize * noteScaleX, zoneSize * noteScaleY, 1f ); Vector3 zoneNoteScale_scaler = new Vector3( zoneSize * noteScaleX, zoneSize * noteScaleY_scaler, 1f ); // Transform transform.position = Late_NoteWorldPos = noteWorldPos; ColRot = MainRenderer.transform.rotation = noteRot; ColSize = MainRenderer.transform.localScale = zoneNoteScale; m_Scaler.localScale = zoneNoteScale_scaler; m_Scaler.rotation = noteRot; // Renderer MainRenderer.RendererEnable = !isLink || activeSelf; MainRenderer.ItemType = noteData.ItemType; MainRenderer.Tint = tint; MainRenderer.Alpha = alpha; MainRenderer.Duration = Duration; MainRenderer.Scale = new Vector2(noteScaleX, noteScaleY); MainRenderer.SetSortingLayer( Duration <= FLOAT_GAP ? SortingLayerID_Note : SortingLayerID_Note_Hold, GetSortingOrder() ); }