Updated CYL_Controlller with Philip
This commit is contained in:
parent
33d2cc5444
commit
45db9bc4a1
8 changed files with 176 additions and 73 deletions
8
UnityProject/Assets/Polybrush Data.meta
Normal file
8
UnityProject/Assets/Polybrush Data.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d2ffacbc3f26ffe4e94f873800ce870c
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
UnityProject/Assets/Polybrush Data/Brush Settings.meta
Normal file
8
UnityProject/Assets/Polybrush Data/Brush Settings.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 724a7fa50d05ebc4d8456c54a1e92bcd
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta
Normal file
8
UnityProject/Assets/Scenes/Examples/Max Silly Demos.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 35edaba459ee497418ef7f2da8e4f25f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 244cf462d93bf8d42a242c3f6d43f66f
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -8,20 +8,24 @@ namespace cylvester
|
||||||
public class TimelineController : MonoBehaviour
|
public class TimelineController : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private PlayableDirector playableDirector;
|
[SerializeField] private PlayableDirector playableDirector;
|
||||||
[SerializeField] private StateManager stateManager;
|
//[SerializeField] private StateManager stateManager;
|
||||||
|
|
||||||
|
|
||||||
[SerializeField] private float initTransitionFactor = 1f;
|
[SerializeField] private float initTransitionFactor = 1f;
|
||||||
|
|
||||||
private IList<QlistMarker> qlistMarkers_;
|
private IList<QlistMarker> qlistMarkers_;
|
||||||
private Boundary boundary_;
|
private Boundary boundary_;
|
||||||
private float speed_;
|
private float speed_;
|
||||||
private float transitionTargetRealtime_;
|
private float transitionTargetRealtime_;
|
||||||
private float previousMarkerTime_;
|
private float previousMarkerTime_; //marker at which transition ends (if reversed)
|
||||||
private float nextMarkerTime_;
|
private float nextMarkerTime_; //marker at which transition ends (if forward)
|
||||||
private bool transitionDirectionReverse_;
|
private bool transitionDirectionReverse_;
|
||||||
|
private bool instantTriggerMode;
|
||||||
|
|
||||||
|
private string lastStateName = "";
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
var timeline = (TimelineAsset)playableDirector.playableAsset;
|
var timeline = (TimelineAsset)playableDirector.playableAsset;
|
||||||
var markers = timeline.markerTrack.GetMarkers();
|
var markers = timeline.markerTrack.GetMarkers();
|
||||||
qlistMarkers_ = new List<QlistMarker>();
|
qlistMarkers_ = new List<QlistMarker>();
|
||||||
|
@ -32,42 +36,64 @@ namespace cylvester
|
||||||
boundary_ = new Boundary(null, null);
|
boundary_ = new Boundary(null, null);
|
||||||
ResetSpeed();
|
ResetSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnStateChanged(IStateReader stateManager)
|
public void OnStateChanged(IStateReader stateManager)
|
||||||
{
|
{
|
||||||
var stateName = stateManager.CurrentState.Title;
|
var stateName = stateManager.CurrentState.Title;
|
||||||
|
lastStateName = stateName;
|
||||||
var numMarkers = qlistMarkers_.Count;
|
var numMarkers = qlistMarkers_.Count;
|
||||||
for (var i = 0; i < numMarkers; ++i)
|
for (var i = 0; i < numMarkers; ++i)
|
||||||
{
|
{
|
||||||
if (qlistMarkers_[i].id != stateName)
|
if (qlistMarkers_[i].id != stateName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
playableDirector.time = qlistMarkers_[i].time;
|
playableDirector.time = qlistMarkers_[i].time;
|
||||||
var previousMarkerTime = i > 0 ? (double?) qlistMarkers_[i - 1].time : 0;
|
var previousMarkerTime = i > 0 ? (double?)qlistMarkers_[i - 1].time : 0;
|
||||||
var nextMarkerTime = i < numMarkers - 1 ? (double?) qlistMarkers_[i + 1].time : qlistMarkers_[numMarkers - 1].time;
|
var nextMarkerTime = i < numMarkers - 1 ? (double?)qlistMarkers_[i + 1].time : qlistMarkers_[numMarkers - 1].time;
|
||||||
previousMarkerTime_ = (float) previousMarkerTime;
|
previousMarkerTime_ = (float)previousMarkerTime;
|
||||||
nextMarkerTime_ = (float) nextMarkerTime;
|
nextMarkerTime_ = (float)nextMarkerTime;
|
||||||
boundary_ = new Boundary(previousMarkerTime, nextMarkerTime);
|
boundary_ = new Boundary(previousMarkerTime, nextMarkerTime);
|
||||||
playableDirector.Play();
|
playableDirector.Play();
|
||||||
|
Debug.Log("prev=" + (i - 1) + " next=" + (i + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getStartMarkerTime() //Return time of marker where the current running animation started
|
||||||
|
{
|
||||||
|
var numMarkers = qlistMarkers_.Count;
|
||||||
|
for (var i = 0; i < numMarkers; ++i)
|
||||||
|
{
|
||||||
|
if (qlistMarkers_[i].id != lastStateName)
|
||||||
|
continue;
|
||||||
|
return qlistMarkers_[i].time;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (playableDirector.state == PlayState.Paused)
|
if (playableDirector.state == PlayState.Paused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check if Transition has not finished yet
|
if (!(Time.fixedUnscaledTime >= transitionTargetRealtime_)) // check if Transition has not finished yet
|
||||||
{
|
{
|
||||||
if (!transitionDirectionReverse_) // if transition direction forward, speed becomes positive
|
if (!transitionDirectionReverse_) // if transition direction forward, speed becomes positive
|
||||||
{
|
{
|
||||||
speed_ = CalculateTransitionSpeed(nextMarkerTime_);
|
if (!instantTriggerMode)
|
||||||
|
{
|
||||||
|
speed_ = CalculateTransitionSpeed(nextMarkerTime_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else // if transition direction backward, speed becomes negative
|
else // if transition direction backward, speed becomes negative
|
||||||
{
|
{
|
||||||
speed_ = CalculateTransitionSpeed(previousMarkerTime_);
|
if (!instantTriggerMode)
|
||||||
|
{
|
||||||
|
speed_ = CalculateTransitionSpeed(previousMarkerTime_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,12 +109,11 @@ namespace cylvester
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//sets playhead precisly to marker position at the end of transition.
|
//sets playhead precisly to marker position at the end of transition.
|
||||||
if (!transitionDirectionReverse_)
|
if (!transitionDirectionReverse_) //forward
|
||||||
{
|
{
|
||||||
playableDirector.time = nextMarkerTime_;
|
playableDirector.time = nextMarkerTime_;
|
||||||
}
|
}
|
||||||
|
else //backward
|
||||||
else
|
|
||||||
{
|
{
|
||||||
playableDirector.time = previousMarkerTime_;
|
playableDirector.time = previousMarkerTime_;
|
||||||
}
|
}
|
||||||
|
@ -104,8 +129,11 @@ namespace cylvester
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void UpdateTransitionTargetRealTime(float restTime, bool reverse)
|
public void UpdateTransitionTargetRealTime(float restTime, bool reverse)
|
||||||
{
|
{
|
||||||
|
instantTriggerMode = false; //update speed continuous
|
||||||
transitionDirectionReverse_ = reverse;
|
transitionDirectionReverse_ = reverse;
|
||||||
transitionTargetRealtime_ = Time.fixedUnscaledTime + restTime;
|
transitionTargetRealtime_ = Time.fixedUnscaledTime + restTime;
|
||||||
}
|
}
|
||||||
|
@ -113,13 +141,40 @@ namespace cylvester
|
||||||
private float CalculateTransitionSpeed(float targetMarkerTime)
|
private float CalculateTransitionSpeed(float targetMarkerTime)
|
||||||
{
|
{
|
||||||
var transitionSpeed = (targetMarkerTime - playableDirector.time) / (transitionTargetRealtime_ - Time.fixedUnscaledTime);
|
var transitionSpeed = (targetMarkerTime - playableDirector.time) / (transitionTargetRealtime_ - Time.fixedUnscaledTime);
|
||||||
return (float) transitionSpeed;
|
return (float)transitionSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool animationPaused()
|
||||||
|
{
|
||||||
|
return playableDirector.state == PlayState.Paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void abortAnimation()
|
||||||
|
{
|
||||||
|
if (animationPaused()) //safe check
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!transitionDirectionReverse_) //forward
|
||||||
|
{
|
||||||
|
transitionDirectionReverse_ = !transitionDirectionReverse_; //invert direction
|
||||||
|
previousMarkerTime_ = (float)getStartMarkerTime();
|
||||||
|
}
|
||||||
|
else //backward
|
||||||
|
{
|
||||||
|
transitionDirectionReverse_ = !transitionDirectionReverse_; //invert direction
|
||||||
|
nextMarkerTime_ = (float)getStartMarkerTime();
|
||||||
|
}
|
||||||
|
boundary_ = new Boundary(previousMarkerTime_, nextMarkerTime_); //Update Boundary to stop animation when target reached
|
||||||
|
}
|
||||||
|
|
||||||
|
public void instantTrigger(float speed)
|
||||||
|
{
|
||||||
|
speed_ = speed;
|
||||||
|
instantTriggerMode = true; //keep speed_ constant
|
||||||
|
transitionDirectionReverse_ = speed < 0;
|
||||||
|
playableDirector.Play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (reverse_ == true)
|
|
||||||
{
|
|
||||||
speed_ = speed_* -1;
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -196,7 +196,7 @@ MonoBehaviour:
|
||||||
timelineController: {fileID: 65620555}
|
timelineController: {fileID: 65620555}
|
||||||
channel: 3
|
channel: 3
|
||||||
stateManager: {fileID: 850208555}
|
stateManager: {fileID: 850208555}
|
||||||
instaTransitionSpeed: 1
|
instaTransitionSpeed: 10
|
||||||
--- !u!114 &65620555
|
--- !u!114 &65620555
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
@ -210,7 +210,6 @@ MonoBehaviour:
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
playableDirector: {fileID: 65620552}
|
playableDirector: {fileID: 65620552}
|
||||||
stateManager: {fileID: 850208555}
|
|
||||||
initTransitionFactor: 8
|
initTransitionFactor: 8
|
||||||
--- !u!1 &155821760
|
--- !u!1 &155821760
|
||||||
GameObject:
|
GameObject:
|
||||||
|
|
|
@ -7,14 +7,14 @@ namespace cylvester
|
||||||
public class CylMidiTransitionController : MonoBehaviour
|
public class CylMidiTransitionController : MonoBehaviour
|
||||||
{
|
{
|
||||||
private enum CylCommand
|
private enum CylCommand
|
||||||
{
|
{
|
||||||
OneBarLoopButton = 94,
|
OneBarLoopButton = 94,
|
||||||
FourBarLoopButton = 86,
|
FourBarLoopButton = 86,
|
||||||
NextSelectedScene = 18,
|
NextSelectedTransition = 18,
|
||||||
CurrentSelectedScene = 17,
|
CurrentSelectedAnimation = 17,
|
||||||
InstantTrigger = 2,
|
InstantTrigger = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField] private PlayableDirector playableDirector;
|
[SerializeField] private PlayableDirector playableDirector;
|
||||||
[SerializeField] private TimelineController timelineController;
|
[SerializeField] private TimelineController timelineController;
|
||||||
[SerializeField, Range(1, 16)] private int channel = 1;
|
[SerializeField, Range(1, 16)] private int channel = 1;
|
||||||
|
@ -23,22 +23,26 @@ namespace cylvester
|
||||||
|
|
||||||
private const int OneBarTrigger = 96;
|
private const int OneBarTrigger = 96;
|
||||||
private const int FourBarTrigger = OneBarTrigger * 4;
|
private const int FourBarTrigger = OneBarTrigger * 4;
|
||||||
private const float TransitionLength = 16;
|
private const float TransitionLength = 16;
|
||||||
|
|
||||||
private ScheduledAction scheduledAction_;
|
private ScheduledAction scheduledAction_;
|
||||||
private int currentTick_;
|
private int currentTick_;
|
||||||
private int currentSelectedScene_ ;
|
private int currentSelectedAnimation_;
|
||||||
private int nextSelectedScene_;
|
private int nextSelectedMarker_;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
scheduledAction_ = new ScheduledAction(() =>
|
scheduledAction_ = new ScheduledAction(() =>
|
||||||
{
|
{
|
||||||
stateManager.SelectedState = currentSelectedScene_;
|
stateManager.SelectedState = currentSelectedAnimation_;
|
||||||
playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(instaTransitionSpeed);
|
//playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(instaTransitionSpeed);
|
||||||
|
timelineController.instantTrigger(instaTransitionSpeed);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
currentSelectedAnimation_ = 0;
|
||||||
|
nextSelectedMarker_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSyncReceived(MidiSync midiSync, int counter)
|
public void OnSyncReceived(MidiSync midiSync, int counter)
|
||||||
{
|
{
|
||||||
currentTick_ = counter;
|
currentTick_ = counter;
|
||||||
|
@ -51,54 +55,55 @@ namespace cylvester
|
||||||
var command = (CylCommand)mes.Data1;
|
var command = (CylCommand)mes.Data1;
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case CylCommand.NextSelectedScene:
|
case CylCommand.NextSelectedTransition:
|
||||||
{
|
|
||||||
nextSelectedScene_ = mes.Data2;
|
nextSelectedMarker_ = mes.Data2; //next marker only used for direction
|
||||||
|
Debug.Log("command nextSelectedMarker_=" + nextSelectedMarker_);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case CylCommand.InstantTrigger:
|
case CylCommand.InstantTrigger:
|
||||||
{
|
|
||||||
scheduledAction_.Ready();
|
scheduledAction_.Ready();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case CylCommand.CurrentSelectedScene:
|
case CylCommand.CurrentSelectedAnimation:
|
||||||
{
|
|
||||||
currentSelectedScene_ = mes.Data2;
|
currentSelectedAnimation_ = mes.Data2;
|
||||||
|
Debug.Log("command currentSelectedAnimation_=" + currentSelectedAnimation_);
|
||||||
scheduledAction_.Go();
|
scheduledAction_.Go();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case CylCommand.FourBarLoopButton:
|
|
||||||
{
|
|
||||||
var restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger);
|
|
||||||
if (nextSelectedScene_ > currentSelectedScene_)
|
|
||||||
{
|
|
||||||
timelineController.UpdateTransitionTargetRealTime(restTime, false);
|
|
||||||
stateManager.SelectedState = nextSelectedScene_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timelineController.UpdateTransitionTargetRealTime(restTime, true);
|
|
||||||
stateManager.SelectedState = nextSelectedScene_ + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case CylCommand.FourBarLoopButton:
|
||||||
}
|
|
||||||
case CylCommand.OneBarLoopButton:
|
case CylCommand.OneBarLoopButton:
|
||||||
{
|
float restTime=0;
|
||||||
var restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger);
|
switch(command)
|
||||||
if (nextSelectedScene_ > currentSelectedScene_)
|
|
||||||
{
|
{
|
||||||
timelineController.UpdateTransitionTargetRealTime(restTime, false);
|
case CylCommand.FourBarLoopButton:
|
||||||
stateManager.SelectedState = nextSelectedScene_;
|
restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger);
|
||||||
|
break;
|
||||||
|
case CylCommand.OneBarLoopButton:
|
||||||
|
restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
Debug.Log("currentSelectedAnimation_=" + currentSelectedAnimation_);
|
||||||
|
Debug.Log("nextSelectedScene_=" + nextSelectedMarker_);
|
||||||
|
bool _reverse = nextSelectedMarker_ <= currentSelectedAnimation_; //nextSelectedMarker_ used to calculate direction
|
||||||
|
|
||||||
|
if (timelineController.animationPaused())
|
||||||
{
|
{
|
||||||
timelineController.UpdateTransitionTargetRealTime(restTime, true);
|
timelineController.UpdateTransitionTargetRealTime(restTime, _reverse);
|
||||||
stateManager.SelectedState = nextSelectedScene_ + 1;
|
|
||||||
}
|
stateManager.SelectedState = currentSelectedAnimation_ + 1; //marker at which transition starts
|
||||||
|
}
|
||||||
|
else //trigger pressed while animation running
|
||||||
|
{
|
||||||
|
timelineController.abortAnimation();
|
||||||
|
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
|
Debug.Log("Unexpected Command: " + mes.Data1);
|
||||||
throw new Exception("Unexpected CYL command");
|
throw new Exception("Unexpected CYL command");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,14 @@ namespace cylvester
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
sceneSelection = value;
|
sceneSelection = value;
|
||||||
|
if (value > States.Length - 1)
|
||||||
|
{ //if index out of bounds
|
||||||
|
sceneSelection = States.Length - 1; //set to last index
|
||||||
|
}
|
||||||
|
else if (value < 0)
|
||||||
|
{
|
||||||
|
sceneSelection = 0;
|
||||||
|
}
|
||||||
onStateChanged.Invoke(this);
|
onStateChanged.Invoke(this);
|
||||||
}
|
}
|
||||||
get
|
get
|
||||||
|
@ -103,11 +111,13 @@ namespace cylvester
|
||||||
break;
|
break;
|
||||||
case Operation.Previous:
|
case Operation.Previous:
|
||||||
if (sceneSelection == 0) return;
|
if (sceneSelection == 0) return;
|
||||||
sceneSelection--;
|
sceneSelection--;
|
||||||
|
sceneSelection = Math.Max(sceneSelection, 0); //constrain minimum
|
||||||
break;
|
break;
|
||||||
case Operation.Next:
|
case Operation.Next:
|
||||||
if (sceneSelection >= States.Length - 1) return;
|
if (sceneSelection >= States.Length - 1) return;
|
||||||
sceneSelection++;
|
sceneSelection++;
|
||||||
|
sceneSelection = Math.Min(sceneSelection, States.Length - 1); //constrain maximum
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -127,10 +137,12 @@ namespace cylvester
|
||||||
case Operation.Previous:
|
case Operation.Previous:
|
||||||
if (sceneSelection == 0) return;
|
if (sceneSelection == 0) return;
|
||||||
sceneSelection--;
|
sceneSelection--;
|
||||||
|
sceneSelection = Math.Max(sceneSelection, 0); //constrain minimum
|
||||||
break;
|
break;
|
||||||
case Operation.Next:
|
case Operation.Next:
|
||||||
if (sceneSelection >= States.Length - 1) return;
|
if (sceneSelection >= States.Length - 1) return;
|
||||||
sceneSelection++;
|
sceneSelection++;
|
||||||
|
sceneSelection = Math.Min(sceneSelection, States.Length - 1); //constrain maximum
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue