├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Editor.meta ├── Editor ├── CMPathAutoGroundEditor.cs ├── CMPathAutoGroundEditor.cs.meta ├── com.bennykok.cmdollycart-timeline-helper.editor.asmdef └── com.bennykok.cmdollycart-timeline-helper.editor.asmdef.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── CMDollyCartBehaviour.cs ├── CMDollyCartBehaviour.cs.meta ├── CMDollyCartClip.cs ├── CMDollyCartClip.cs.meta ├── CMDollyCartMixerBehaviour.cs ├── CMDollyCartMixerBehaviour.cs.meta ├── CMDollyCartTrack.cs ├── CMDollyCartTrack.cs.meta ├── CMPathAutoGround.cs ├── CMPathAutoGround.cs.meta ├── com.bennykok.cmdollycart-timeline-helper.asmdef └── com.bennykok.cmdollycart-timeline-helper.asmdef.meta ├── package.json └── package.json.meta /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.1.2](https://github.com/BennyKok/unity-cmdollycart-timeline-helper/compare/v0.1.1...v0.1.2) (2021-04-20) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * 🐛 add proper GatherProperties for CMDollyCart ([31eabf4](https://github.com/BennyKok/unity-cmdollycart-timeline-helper/commit/31eabf4e3260f2de38b1db18f933795866765473)) 11 | * 🐛 make sure m_Speed is set to 0 in track mixer behaviour ([e26a101](https://github.com/BennyKok/unity-cmdollycart-timeline-helper/commit/e26a1017a13c6be836f844f49e77e05a71d9b55a)) 12 | 13 | ### [0.1.1](https://github.com/BennyKok/cmdollycart-timeline-helper/compare/v0.1.0...v0.1.1) (2020-10-01) 14 | 15 | ## 0.1.0 (2020-09-29) 16 | 17 | Init release -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1489455f07eb3d745a00e69c488cb389 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c37339ebe9b5f54eb52b03201338c3d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/CMPathAutoGroundEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace BK.CMDollyCartTimelineHelper.Editor 5 | { 6 | [CustomEditor(typeof(CMPathAutoGround))] 7 | public class CMPathAutoGroundEditor : UnityEditor.Editor 8 | { 9 | public override void OnInspectorGUI() 10 | { 11 | CMPathAutoGround m_target = (CMPathAutoGround)target; 12 | serializedObject.Update(); 13 | DrawPropertiesExcluding(serializedObject, "m_Script"); 14 | // using (new EditorGUI.DisabledScope(m_target.autoProject)) 15 | // { 16 | if (GUILayout.Button("Project")) 17 | { 18 | ((CMPathAutoGround)target).ProjectToGround(true); 19 | } 20 | // } 21 | serializedObject.ApplyModifiedProperties(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Editor/CMPathAutoGroundEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 369deef6915cf5247aa1251f9a0e0016 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/com.bennykok.cmdollycart-timeline-helper.editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.bennykok.cmdollycart-timeline-helper.rditor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:41d84c9209265454294c3c2ef4b2967f", 6 | "GUID:4307f53044263cf4b835bd812fc161a4" 7 | ], 8 | "includePlatforms": [ 9 | "Editor" 10 | ], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "versionDefines": [], 18 | "noEngineReferences": false 19 | } -------------------------------------------------------------------------------- /Editor/com.bennykok.cmdollycart-timeline-helper.editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e92647ab988ea542a7cd62d3609b552 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 BennyKok 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb76ab2f242c95043ae18982f06da5b0 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CMDollyCart Timeline Helper 2 | 3 | Install as upm package from git url 4 | ``` 5 | https://github.com/BennyKok/unity-cmdollycart-timeline-helper.git 6 | ``` 7 | 8 | ## Features 9 | 10 | - Custom Timeline track for CM Dolly Cart 11 | 12 | ![Imgur](https://i.imgur.com/87uupzv.gif) 13 | 14 | - Auto Ground Projection component for CM Smooth Path 15 | 16 | ![Imgur](https://i.imgur.com/jNi7hr0.gif) 17 | 18 | ## Explore 19 | Feel free to check me out!! :) 20 | 21 | [Twitter](https://twitter.com/BennyKokMusic) | [Website](https://bennykok.com) | [AssetStore](https://assetstore.unity.com/publishers/28510) 22 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8222f155c9f4947448dc02ba8a339756 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8eec87bbd6486e14c92c162e71e93512 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/CMDollyCartBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.Playables; 4 | using UnityEngine.Timeline; 5 | using Cinemachine; 6 | 7 | namespace BK.CMDollyCartTimelineHelper 8 | { 9 | [Serializable] 10 | public class CMDollyCartBehaviour : PlayableBehaviour 11 | { 12 | public float speed; 13 | 14 | public PositionMode positionMode; 15 | public float customStart; 16 | 17 | public enum PositionMode 18 | { 19 | BaseOnOriginal, DeltaTime, CustomStart 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Runtime/CMDollyCartBehaviour.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 153d54a4e65e6d74db95dc9da550178d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/CMDollyCartClip.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.Playables; 4 | using UnityEngine.Timeline; 5 | using Cinemachine; 6 | 7 | namespace BK.CMDollyCartTimelineHelper 8 | { 9 | [Serializable] 10 | public class CMDollyCartClip : PlayableAsset, ITimelineClipAsset 11 | { 12 | public CMDollyCartBehaviour template = new CMDollyCartBehaviour(); 13 | // public ExposedReference dollyCart; 14 | 15 | public ClipCaps clipCaps 16 | { 17 | get { return ClipCaps.Extrapolation; } 18 | } 19 | 20 | public override Playable CreatePlayable(PlayableGraph graph, GameObject owner) 21 | { 22 | var playable = ScriptPlayable.Create(graph, template); 23 | CMDollyCartBehaviour clone = playable.GetBehaviour(); 24 | // clone.dollyCart = dollyCart.Resolve(graph.GetResolver()); 25 | return playable; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Runtime/CMDollyCartClip.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e2454809e0d9e0c4dab7afb24f55f14c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/CMDollyCartMixerBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Cinemachine; 3 | using UnityEngine; 4 | using UnityEngine.Playables; 5 | 6 | namespace BK.CMDollyCartTimelineHelper 7 | { 8 | public class CMDollyCartMixerBehaviour : PlayableBehaviour 9 | { 10 | public CinemachineDollyCart dollyCart; 11 | private float m_DefaultPosition, m_DefaultSpeed; 12 | private bool stateCached; 13 | 14 | public override void OnGraphStop(Playable playable) => ResetState(); 15 | 16 | public void CacheStartState() 17 | { 18 | if (stateCached) return; 19 | 20 | stateCached = true; 21 | 22 | m_DefaultPosition = dollyCart.m_Position; 23 | m_DefaultSpeed = dollyCart.m_Speed; 24 | } 25 | 26 | public void ResetState() 27 | { 28 | stateCached = false; 29 | dollyCart.m_Position = m_DefaultPosition; 30 | dollyCart.m_Speed = m_DefaultSpeed; 31 | } 32 | 33 | public override void ProcessFrame(Playable playable, FrameData info, object playerData) 34 | { 35 | dollyCart = playerData as CinemachineDollyCart; 36 | // float finalSpeed = 0f; 37 | // float finalWeight = 0f; 38 | 39 | if (!dollyCart) 40 | return; 41 | 42 | CacheStartState(); 43 | 44 | int inputCount = playable.GetInputCount(); //get the number of all clips on this track 45 | 46 | 47 | for (int i = 0; i < inputCount; i++) 48 | { 49 | float inputWeight = playable.GetInputWeight(i); 50 | ScriptPlayable inputPlayable = (ScriptPlayable)playable.GetInput(i); 51 | CMDollyCartBehaviour input = inputPlayable.GetBehaviour(); 52 | 53 | // finalWeight += inputWeight; 54 | 55 | // Use the above variables to process each frame of this playable. 56 | // finalSpeed += input.GetSpeed() * inputWeight; 57 | if (inputWeight == 1) 58 | { 59 | // var maxTime = Mathf.Min((float)inputPlayable.GetTime(), (float)inputPlayable.GetDuration()); 60 | dollyCart.m_Speed = 0; 61 | 62 | switch (input.positionMode) 63 | { 64 | case CMDollyCartBehaviour.PositionMode.BaseOnOriginal: 65 | dollyCart.m_Position = m_DefaultPosition + (float)(inputPlayable.GetTime() * input.speed); 66 | break; 67 | case CMDollyCartBehaviour.PositionMode.CustomStart: 68 | dollyCart.m_Position = input.customStart + (float)(inputPlayable.GetTime() * input.speed); 69 | break; 70 | case CMDollyCartBehaviour.PositionMode.DeltaTime: 71 | dollyCart.m_Position += (float)(info.deltaTime * input.speed); 72 | break; 73 | } 74 | } 75 | } 76 | 77 | // Debug.Log(finalWeight); 78 | 79 | // dollyCart.m_Speed = 0; 80 | 81 | // if (finalWeight > 0) 82 | // dollyCart.m_Position = m_DefaultPosition + (float)(playable.GetTime() * finalSpeed); 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /Runtime/CMDollyCartMixerBehaviour.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9740f7f2f6fb71f42a797e063b01fc56 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/CMDollyCartTrack.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Playables; 3 | using UnityEngine.Timeline; 4 | using Cinemachine; 5 | 6 | namespace BK.CMDollyCartTimelineHelper 7 | { 8 | [TrackColor(0.7238969f, 0.6117647f, 0.9058824f)] 9 | [TrackClipType(typeof(CMDollyCartClip))] 10 | [TrackBindingType(typeof(CinemachineDollyCart))] 11 | public class CMDollyCartTrack : TrackAsset 12 | { 13 | public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount) 14 | { 15 | return ScriptPlayable.Create(graph, inputCount); 16 | } 17 | 18 | public override void GatherProperties(PlayableDirector director, IPropertyCollector driver) 19 | { 20 | #if UNITY_EDITOR 21 | CinemachineDollyCart trackBinding = director.GetGenericBinding(this) as CinemachineDollyCart; 22 | if (trackBinding == null) 23 | return; 24 | 25 | driver.AddFromName(trackBinding.gameObject, "m_Position"); 26 | driver.AddFromName(trackBinding.gameObject, "m_Speed"); 27 | #endif 28 | base.GatherProperties(director, driver); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/CMDollyCartTrack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d60d8b7f941f354297892eb46174f36 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/CMPathAutoGround.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Cinemachine; 3 | 4 | namespace BK.CMDollyCartTimelineHelper 5 | { 6 | [ExecuteAlways] 7 | public class CMPathAutoGround : MonoBehaviour 8 | { 9 | public bool autoProject = true; 10 | public LayerMask layerMask; 11 | public float projectionHeight = 1; 12 | public float projectionMaxDistance = 5; 13 | 14 | private CinemachineSmoothPath path = null; 15 | private CinemachineSmoothPath.Waypoint[] m_WaypointsCaches; 16 | 17 | private void LateUpdate() 18 | { 19 | if (autoProject) 20 | { 21 | ProjectToGround(); 22 | } 23 | } 24 | 25 | public void CacheWaypoints() 26 | { 27 | m_WaypointsCaches = new CinemachineSmoothPath.Waypoint[path.m_Waypoints.Length]; 28 | path.m_Waypoints.CopyTo(m_WaypointsCaches, 0); 29 | } 30 | 31 | public bool EnsurePathComponent() 32 | { 33 | if (path == null) path = GetComponent(); 34 | 35 | if (m_WaypointsCaches == null) CacheWaypoints(); 36 | 37 | return path; 38 | } 39 | 40 | public void ProjectToGround(bool force = false, bool useCache = true) 41 | { 42 | if (!EnsurePathComponent()) return; 43 | 44 | var changed = false; 45 | 46 | //when a point is removed 47 | if (m_WaypointsCaches.Length > path.m_Waypoints.Length) 48 | { 49 | if (useCache) 50 | CacheWaypoints(); 51 | } 52 | 53 | for (int i = 0; i < path.m_Waypoints.Length; i++) 54 | { 55 | CinemachineSmoothPath.Waypoint waypoint = path.m_Waypoints[i]; 56 | 57 | if (useCache && !force) 58 | if (m_WaypointsCaches.Length == path.m_Waypoints.Length) 59 | //This waypoint hasn't changed, skipping raycast\ 60 | if (waypoint.position == m_WaypointsCaches[i].position) 61 | { 62 | continue; 63 | } 64 | 65 | var rayOrigin = path.transform.TransformPoint(waypoint.position); 66 | rayOrigin.y += projectionHeight; 67 | #if UNITY_EDITOR 68 | if (UnityEditor.Selection.activeGameObject == gameObject) 69 | UnityEngine.Debug.DrawRay(rayOrigin, Vector3.down * projectionMaxDistance, Color.cyan, 0.1f); 70 | #endif 71 | if (Physics.Raycast(rayOrigin, Vector3.down, out var hit, projectionMaxDistance, layerMask, QueryTriggerInteraction.Ignore)) 72 | { 73 | var newPos = path.transform.InverseTransformPoint(hit.point); 74 | 75 | if (newPos != waypoint.position) 76 | { 77 | changed = true; 78 | waypoint.position = newPos; 79 | path.m_Waypoints[i] = waypoint; 80 | } 81 | } 82 | } 83 | 84 | if (changed) 85 | { 86 | // Debug.Log("Changed"); 87 | path.InvalidateDistanceCache(); 88 | } 89 | 90 | if (useCache) 91 | CacheWaypoints(); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /Runtime/CMPathAutoGround.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 45ec5ef579f2fb8489ea3651860d3cf0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/com.bennykok.cmdollycart-timeline-helper.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "come.bennykok.cmdollycart-timeline-helper", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:f06555f75b070af458a003d92f9efb00", 6 | "GUID:4307f53044263cf4b835bd812fc161a4" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } -------------------------------------------------------------------------------- /Runtime/com.bennykok.cmdollycart-timeline-helper.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41d84c9209265454294c3c2ef4b2967f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.bennykok.cmdollycart-timeline-helper", 3 | "displayName": "CMDollyCart Timeline Helper", 4 | "version": "0.1.2", 5 | "unity": "2020.1", 6 | "description": "Custom Timeline track for CM Dolly Cart\nAuto Ground Projection component for CM Smooth Path", 7 | "type": "tool", 8 | "dependencies": { 9 | "com.unity.timeline": "1.4.4", 10 | "com.unity.cinemachine": "2.6.3" 11 | }, 12 | "author": { 13 | "name": "BennyKok", 14 | "url": "https://github.com/BennyKok" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66f9b102f90c4c248926a65211eef299 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------