2023-12-26 05:22:51 +00:00
|
|
|
using System;
|
2022-07-10 21:39:14 +00:00
|
|
|
using UnityEngine;
|
|
|
|
using HeavenStudio.Util;
|
|
|
|
|
|
|
|
namespace HeavenStudio.StudioDance
|
|
|
|
{
|
|
|
|
public class Dancer : MonoBehaviour
|
|
|
|
{
|
2023-12-26 05:22:51 +00:00
|
|
|
[SerializeField] ChoreographyInfo debugChoreography;
|
|
|
|
[SerializeField] ChoreographyInfo[] choreographies;
|
2024-03-30 02:52:14 +00:00
|
|
|
Conductor cond;
|
|
|
|
GameManager gm;
|
2022-07-10 21:39:14 +00:00
|
|
|
private Animator animator;
|
2023-06-10 19:13:29 +00:00
|
|
|
private double currentBeat = 0f;
|
2022-07-10 21:39:14 +00:00
|
|
|
|
|
|
|
private bool isDance = false;
|
|
|
|
|
2023-12-26 05:22:51 +00:00
|
|
|
private ChoreographyInfo currentChoreography;
|
|
|
|
private double totalChoreographyLength = 0f;
|
|
|
|
|
|
|
|
public ChoreographyInfo[] ChoreographyInfos { get => choreographies; }
|
|
|
|
public ChoreographyInfo CurrentChoreography { get => currentChoreography; }
|
|
|
|
|
|
|
|
public void SetChoreography(ChoreographyInfo choreography)
|
|
|
|
{
|
|
|
|
currentChoreography = choreography;
|
|
|
|
totalChoreographyLength = 0f;
|
|
|
|
foreach (var step in choreography.choreographySteps)
|
|
|
|
{
|
|
|
|
totalChoreographyLength += step.beatLength;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SetChoreography(int index)
|
|
|
|
{
|
|
|
|
if (index < 0 || index >= choreographies.Length) return;
|
|
|
|
var choreography = choreographies[index];
|
|
|
|
currentChoreography = choreography;
|
|
|
|
totalChoreographyLength = 0f;
|
|
|
|
foreach (var step in choreography.choreographySteps)
|
|
|
|
{
|
|
|
|
totalChoreographyLength += step.beatLength;
|
|
|
|
}
|
|
|
|
|
2024-03-30 02:52:14 +00:00
|
|
|
if (cond is not null && animator is not null && !cond.isPlaying)
|
2023-12-26 05:22:51 +00:00
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
animator.Play(currentChoreography.introState, -1, 0f);
|
2023-12-26 05:22:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-10 21:39:14 +00:00
|
|
|
private void Start()
|
|
|
|
{
|
|
|
|
animator = GetComponent<Animator>();
|
2024-03-30 02:52:14 +00:00
|
|
|
cond = Conductor.instance;
|
|
|
|
gm = GameManager.instance;
|
2023-12-26 05:22:51 +00:00
|
|
|
|
|
|
|
if (gm != null)
|
|
|
|
{
|
|
|
|
gm.onBeatPulse += OnBeatPulse;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debugChoreography != null)
|
|
|
|
{
|
|
|
|
SetChoreography(debugChoreography);
|
|
|
|
}
|
|
|
|
|
2024-03-30 02:52:14 +00:00
|
|
|
animator.Play(currentChoreography.introState, -1, 0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SetStartChoreography()
|
|
|
|
{
|
|
|
|
if (debugChoreography != null)
|
|
|
|
{
|
|
|
|
SetChoreography(debugChoreography);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetChoreography(0);
|
|
|
|
}
|
2023-12-26 05:22:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void OnBeatPulse(double beat)
|
|
|
|
{
|
|
|
|
currentBeat = beat;
|
2022-07-10 21:39:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void Update()
|
|
|
|
{
|
2023-12-26 05:22:51 +00:00
|
|
|
if (currentChoreography == null || cond == null) return;
|
|
|
|
if (!cond.isPlaying)
|
2022-07-10 21:39:14 +00:00
|
|
|
{
|
|
|
|
if (!isDance) return;
|
|
|
|
if (currentBeat % 2 != 0)
|
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
animator.Play(currentChoreography.poseStateOdd, -1, 0f);
|
2022-07-10 21:39:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
animator.Play(currentChoreography.poseStateEven, -1, 0f);
|
2022-07-10 21:39:14 +00:00
|
|
|
}
|
|
|
|
isDance = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
isDance = true;
|
|
|
|
|
2024-03-30 02:52:14 +00:00
|
|
|
float speed = 1f;
|
|
|
|
if (currentChoreography.halfSpeedBpm != currentChoreography.doubleSpeedBpm)
|
|
|
|
{
|
|
|
|
if (cond.songBpm < currentChoreography.halfSpeedBpm)
|
|
|
|
{
|
|
|
|
speed = 0.5f;
|
|
|
|
}
|
|
|
|
else if (cond.songBpm > currentChoreography.doubleSpeedBpm)
|
|
|
|
{
|
|
|
|
speed = 2f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double choreoBeat = cond.songPositionInBeatsAsDouble % (totalChoreographyLength * speed);
|
|
|
|
double cycleStartBeat = Math.Floor(cond.songPositionInBeatsAsDouble / (totalChoreographyLength * speed)) * (totalChoreographyLength * speed);
|
2023-12-26 05:22:51 +00:00
|
|
|
|
|
|
|
double beatSum = 0.0;
|
|
|
|
double stepLength = 0.0;
|
|
|
|
string stepState = "";
|
|
|
|
foreach (ChoreographyInfo.ChoreographyStep s in currentChoreography.choreographySteps)
|
2022-07-10 21:39:14 +00:00
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
if (choreoBeat > beatSum && choreoBeat < beatSum + (s.beatLength * speed))
|
2023-12-26 05:22:51 +00:00
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
stepLength = s.beatLength * speed;
|
2023-12-26 05:22:51 +00:00
|
|
|
stepState = s.stateName;
|
|
|
|
break;
|
|
|
|
}
|
2024-03-30 02:52:14 +00:00
|
|
|
beatSum += s.beatLength * speed;
|
2022-07-10 21:39:14 +00:00
|
|
|
}
|
2023-12-26 05:22:51 +00:00
|
|
|
if (stepState is not null or "")
|
2022-07-10 21:39:14 +00:00
|
|
|
{
|
2024-03-30 02:52:14 +00:00
|
|
|
animator.DoScaledAnimation(stepState, cycleStartBeat + beatSum, stepLength, animLayer: -1, clamp: true);
|
2022-07-10 21:39:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|