using System; using System.Collections.Generic; using ABI.CCK.Components; using UnityEngine; #if UNITY_EDITOR using UnityEditor; using UnityEditor.Animations; using UnityEditorInternal; using UnityEngine.Rendering; using AnimatorController = UnityEditor.Animations.AnimatorController; using AnimatorControllerParameter = UnityEngine.AnimatorControllerParameter; using AnimatorControllerParameterType = UnityEngine.AnimatorControllerParameterType; using BlendTree = UnityEditor.Animations.BlendTree; #endif namespace ABI.CCK.Scripts { [System.Serializable] public class CVRAdvancedAvatarSettings { public bool initialized = false; public RuntimeAnimatorController baseController; public RuntimeAnimatorController baseOverrideController; #if UNITY_EDITOR public AnimatorController animator; public AnimatorOverrideController overrides; #endif public List settings = new List(); } [System.Serializable] public class CVRAdvancedSettingsEntry { public enum SettingsType { GameObjectToggle, GameObjectDropdown, MaterialColor, Slider, Joystick2D, Joystick3D, InputSingle, InputVector2, InputVector3 } public SettingsType type = SettingsType.GameObjectToggle; public CVRAdvancesAvatarSettingBase setting { get { switch (type) { case SettingsType.MaterialColor: return materialColorSettings; case SettingsType.GameObjectDropdown: return dropDownSettings; case SettingsType.Slider: return sliderSettings; case SettingsType.Joystick2D: return joystick2DSetting; case SettingsType.Joystick3D: return joystick3DSetting; case SettingsType.InputSingle: return inputSingleSettings; case SettingsType.InputVector2: return inputVector2Settings; case SettingsType.InputVector3: return inputVector3Settings; default: return toggleSettings; } } set { switch (type) { case SettingsType.MaterialColor: materialColorSettings = (CVRAdvancedAvatarSettingMaterialColor) value; break; case SettingsType.GameObjectDropdown: dropDownSettings = (CVRAdvancesAvatarSettingGameObjectDropdown) value; break; case SettingsType.Slider: sliderSettings = (CVRAdvancesAvatarSettingSlider) value; break; case SettingsType.Joystick2D: joystick2DSetting = (CVRAdvancesAvatarSettingJoystick2D) value; break; case SettingsType.Joystick3D: joystick3DSetting = (CVRAdvancesAvatarSettingJoystick3D) value; break; case SettingsType.InputSingle: inputSingleSettings = (CVRAdvancesAvatarSettingInputSingle) value; break; case SettingsType.InputVector2: inputVector2Settings = (CVRAdvancesAvatarSettingInputVector2) value; break; case SettingsType.InputVector3: inputVector3Settings = (CVRAdvancesAvatarSettingInputVector3) value; break; default: toggleSettings = (CVRAdvancesAvatarSettingGameObjectToggle) value; break; } } } [SerializeField] private CVRAdvancesAvatarSettingGameObjectToggle toggleSettings; [SerializeField] private CVRAdvancedAvatarSettingMaterialColor materialColorSettings; [SerializeField] private CVRAdvancesAvatarSettingGameObjectDropdown dropDownSettings; [SerializeField] private CVRAdvancesAvatarSettingSlider sliderSettings; [SerializeField] private CVRAdvancesAvatarSettingJoystick2D joystick2DSetting; [SerializeField] private CVRAdvancesAvatarSettingJoystick3D joystick3DSetting; [SerializeField] private CVRAdvancesAvatarSettingInputSingle inputSingleSettings; [SerializeField] private CVRAdvancesAvatarSettingInputVector2 inputVector2Settings; [SerializeField] private CVRAdvancesAvatarSettingInputVector3 inputVector3Settings; public string name; public string machineName; #if UNITY_EDITOR public void RunCollapsedSetup() { switch (type) { case SettingsType.MaterialColor: materialColorSettings.RunCollapsedSetup(); break; case SettingsType.Slider: sliderSettings.RunCollapsedSetup(); break; } } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingBase { public enum ParameterType { GenerateFloat = 1, GenerateInt = 2, GenerateBool = 3 } public ParameterType usedType = ParameterType.GenerateFloat; #if UNITY_EDITOR public bool isCollapsed = true; public virtual void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingGameObjectToggle : CVRAdvancesAvatarSettingBase { public bool defaultValue; #if UNITY_EDITOR public bool useAnimationClip; public AnimationClip animationClip; public List gameObjectTargets = new List(); private ReorderableList gameObjectList; private CVRAvatar target; public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); AnimatorControllerParameter animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Bool, defaultBool = defaultValue }; if (usedType == ParameterType.GenerateFloat) animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue ? 1f : 0f }; if (usedType == ParameterType.GenerateInt) animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Int, defaultInt = defaultValue ? 1 : 0 }; controller.AddParameter(animatorParameter); AnimationClip onClip = new AnimationClip(); AnimationClip offClip = new AnimationClip(); var animationCurveOn = new AnimationCurve(); var keyframe = new Keyframe(0f, 1); keyframe.outTangent = Mathf.Infinity; animationCurveOn.AddKey(keyframe); keyframe = new Keyframe(1f / 60f, 1); keyframe.outTangent = Mathf.Infinity; animationCurveOn.AddKey(keyframe); var animationCurveOff = new AnimationCurve(); keyframe = new Keyframe(0f, 0); keyframe.outTangent = Mathf.Infinity; animationCurveOff.AddKey(keyframe); keyframe = new Keyframe(1f / 60f, 0); keyframe.outTangent = Mathf.Infinity; animationCurveOff.AddKey(keyframe); foreach (var target in gameObjectTargets) { if(target.gameObject == null || target.treePath == null) continue; onClip.SetCurve(target.treePath, typeof(GameObject), "m_IsActive", target.onState ? animationCurveOn : animationCurveOff); offClip.SetCurve(target.treePath, typeof(GameObject), "m_IsActive", !target.onState ? animationCurveOn : animationCurveOff); } if (useAnimationClip) { onClip = animationClip; AssetDatabase.CreateAsset(offClip, folderPath + "/Anim_" + machineName + "_Toggle_Off.anim"); } else { AssetDatabase.CreateAsset(offClip, folderPath + "/Anim_" + machineName + "_Toggle_Off.anim"); AssetDatabase.CreateAsset(onClip, folderPath + "/Anim_" + machineName + "_Toggle_On.anim"); } if (usedType == ParameterType.GenerateBool) { var offState = animatorLayer.stateMachine.AddState(machineName + " OFF"); var onState = animatorLayer.stateMachine.AddState(machineName + " ON"); offState.motion = offClip; onState.motion = onClip; animatorLayer.stateMachine.AddAnyStateTransition(onState); animatorLayer.stateMachine.anyStateTransitions[0].destinationState = onState; animatorLayer.stateMachine.anyStateTransitions[0].duration = 0f; animatorLayer.stateMachine.anyStateTransitions[0].hasExitTime = false; animatorLayer.stateMachine.anyStateTransitions[0].canTransitionToSelf = false; animatorLayer.stateMachine.anyStateTransitions[0].AddCondition(AnimatorConditionMode.If, 0f, machineName); animatorLayer.stateMachine.AddAnyStateTransition(offState); animatorLayer.stateMachine.anyStateTransitions[1].destinationState = offState; animatorLayer.stateMachine.anyStateTransitions[1].duration = 0f; animatorLayer.stateMachine.anyStateTransitions[1].hasExitTime = false; animatorLayer.stateMachine.anyStateTransitions[1].canTransitionToSelf = false; animatorLayer.stateMachine.anyStateTransitions[1].AddCondition(AnimatorConditionMode.IfNot, 0f, machineName); } if (usedType == ParameterType.GenerateInt) { var offState = animatorLayer.stateMachine.AddState(machineName + " OFF"); var onState = animatorLayer.stateMachine.AddState(machineName + " ON"); offState.motion = offClip; onState.motion = onClip; animatorLayer.stateMachine.AddAnyStateTransition(onState); animatorLayer.stateMachine.anyStateTransitions[0].destinationState = onState; animatorLayer.stateMachine.anyStateTransitions[0].duration = 0f; animatorLayer.stateMachine.anyStateTransitions[0].hasExitTime = false; animatorLayer.stateMachine.anyStateTransitions[0].canTransitionToSelf = false; animatorLayer.stateMachine.anyStateTransitions[0].AddCondition(AnimatorConditionMode.Equals, 1f, machineName); animatorLayer.stateMachine.AddAnyStateTransition(offState); animatorLayer.stateMachine.anyStateTransitions[1].destinationState = offState; animatorLayer.stateMachine.anyStateTransitions[1].duration = 0f; animatorLayer.stateMachine.anyStateTransitions[1].hasExitTime = false; animatorLayer.stateMachine.anyStateTransitions[1].canTransitionToSelf = false; animatorLayer.stateMachine.anyStateTransitions[1].AddCondition(AnimatorConditionMode.Equals, 0f, machineName); } if (usedType == ParameterType.GenerateFloat) { var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName; blendTree.AddChild(offClip, 0f); blendTree.AddChild(onClip, 1f); animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; } } private void generateReorderableList() { gameObjectList = new ReorderableList(gameObjectTargets, typeof(CVRAdvancedSettingsTargetEntryGameObject), true, true, true, true); gameObjectList.drawHeaderCallback = OnDrawHeader; gameObjectList.drawElementCallback = OnDrawElement; gameObjectList.elementHeightCallback = OnHeightElement; gameObjectList.onAddCallback = OnAdd; gameObjectList.onChangedCallback = OnChanged; } public ReorderableList GetReorderableList(CVRAvatar avatar) { target = avatar; if (gameObjectList == null) generateReorderableList(); return gameObjectList; } private void OnChanged(ReorderableList list) { EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { gameObjectTargets.Add(new CVRAdvancedSettingsTargetEntryGameObject()); } private float OnHeightElement(int index) { CVRAdvancedSettingsTargetEntryGameObject entity = gameObjectTargets[index]; float height = 0; if (!entity.isCollapsed) { height += 1; } else { height += 3f; } return EditorGUIUtility.singleLineHeight * height * 1.25f; } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > gameObjectTargets.Count) return; CVRAdvancedSettingsTargetEntryGameObject entity = gameObjectTargets[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); entity.isCollapsed = EditorGUI.Foldout(_rect, entity.isCollapsed, "Name", true); _rect.x += 100; _rect.width = rect.width - 100; var targetGameObject = (GameObject) EditorGUI.ObjectField(_rect, entity.gameObject, typeof(GameObject), true); if (targetGameObject != null && targetGameObject.transform.GetComponentInParent(typeof(CVRAvatar)) == target) { entity.gameObject = targetGameObject; entity.treePath = AnimationUtility.CalculateTransformPath(targetGameObject.transform, target.transform); } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } // is Collapsed if (!entity.isCollapsed) return; rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Path"); _rect.x += 100; _rect.width = rect.width - 100; EditorGUI.LabelField(_rect, entity.treePath); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, new GUIContent("Set to", "If checked, the object will be active once the toggle was pressed. If unchecked the object " + "will be deactivated when the toggle is pressed.")); _rect.x += 100; _rect.width = rect.width - 100; entity.onState = EditorGUI.Toggle(_rect, entity.onState); } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "GameObjects"); } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingGameObjectDropdown : CVRAdvancesAvatarSettingBase { public int defaultValue; public List options = new List(); #if UNITY_EDITOR private ReorderableList gameObjectList; private CVRAvatar target; #endif public string[] getOptionsList() { var list = new string[options.Count]; var i = 0; foreach (var option in options) { list[i] = option.name; i++; } return list; } #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue }; if (usedType == ParameterType.GenerateInt) animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Int, defaultInt = defaultValue }; controller.AddParameter(animatorParameter); var animationCurveOn = new AnimationCurve(); var keyframe = new Keyframe(0f, 1); keyframe.outTangent = Mathf.Infinity; animationCurveOn.AddKey(keyframe); keyframe = new Keyframe(1f / 60f, 1); keyframe.outTangent = Mathf.Infinity; animationCurveOn.AddKey(keyframe); var animationCurveOff = new AnimationCurve(); keyframe = new Keyframe(0f, 0); keyframe.outTangent = Mathf.Infinity; animationCurveOff.AddKey(keyframe); keyframe = new Keyframe(1f / 60f, 0); keyframe.outTangent = Mathf.Infinity; animationCurveOff.AddKey(keyframe); var i = 0; AnimationClip animation; List animations = new List(); foreach (var option in options) { animation = new AnimationClip(); var j = 0; if (option.useAnimationClip && option.animationClip != null) { animation = option.animationClip; } else { var activeGameobjects = new List(); var inActiveGameobjects = new List(); foreach (var activeOption in options) { foreach (var gameObjectTarget in activeOption.gameObjectTargets) { if (gameObjectTarget == null || gameObjectTarget.gameObject == null || gameObjectTarget.treePath == null) continue; if (i == j && gameObjectTarget.onState) { activeGameobjects.Add(gameObjectTarget); } else { inActiveGameobjects.Add(gameObjectTarget); } } j++; } foreach (var gameObjectTarget in activeGameobjects) { animation.SetCurve( gameObjectTarget.treePath, typeof(GameObject), "m_IsActive", animationCurveOn ); } foreach (var gameObjectTarget in inActiveGameobjects) { if(activeGameobjects.Find(match => match.treePath == gameObjectTarget.treePath) != null) continue; animation.SetCurve( gameObjectTarget.treePath, typeof(GameObject), "m_IsActive", animationCurveOff ); } AssetDatabase.CreateAsset(animation, folderPath + "/Anim_" + machineName + "_Dropdown_" + i + ".anim"); } animations.Add(animation); i++; } if (usedType == ParameterType.GenerateFloat) { var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName; blendTree.useAutomaticThresholds = false; i = 0; foreach (AnimationClip animationClip in animations) { blendTree.AddChild(animationClip, i); i++; } animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; } if (usedType == ParameterType.GenerateInt) { i = 0; foreach (AnimationClip animationClip in animations) { var state = animatorLayer.stateMachine.AddState(machineName + " Option " + i); state.motion = animationClip; animatorLayer.stateMachine.AddAnyStateTransition(state); animatorLayer.stateMachine.anyStateTransitions[i].destinationState = state; animatorLayer.stateMachine.anyStateTransitions[i].duration = 0f; animatorLayer.stateMachine.anyStateTransitions[i].hasExitTime = false; animatorLayer.stateMachine.anyStateTransitions[i].canTransitionToSelf = false; animatorLayer.stateMachine.anyStateTransitions[i].AddCondition(AnimatorConditionMode.Equals, i, machineName); i++; } } } private void generateReorderableList() { gameObjectList = new ReorderableList(options, typeof(CVRAdvancedSettingsDropDownEntry), true, true, true, true); gameObjectList.drawHeaderCallback = OnDrawHeader; gameObjectList.drawElementCallback = OnDrawElement; gameObjectList.elementHeightCallback = OnHeightElement; gameObjectList.onAddCallback = OnAdd; gameObjectList.onChangedCallback = OnChanged; } public ReorderableList GetReorderableList(CVRAvatar avatar) { target = avatar; if (gameObjectList == null) generateReorderableList(); return gameObjectList; } private void OnChanged(ReorderableList list) { EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { options.Add(new CVRAdvancedSettingsDropDownEntry()); } private float OnHeightElement(int index) { CVRAdvancedSettingsDropDownEntry entity = options[index]; if (!entity.isCollapsed) { return EditorGUIUtility.singleLineHeight * 1.25f; } else { if (index > options.Count) return 0f; float height = 2.5f; if (entity.useAnimationClip) { height += 1; } else { if (entity.gameObjectTargets.Count == 0) { height += 0.5f; } height += 2.25f; foreach (var target in entity.gameObjectTargets) { if (!target.isCollapsed) { height += 1; } else { height += 3f; } } } return EditorGUIUtility.singleLineHeight * height * 1.25f; } } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > options.Count) return; CVRAdvancedSettingsDropDownEntry entity = options[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); entity.isCollapsed = EditorGUI.Foldout(_rect, entity.isCollapsed, "Name", true); _rect.x += 100; _rect.width = rect.width - 100; entity.name = EditorGUI.TextField(_rect, entity.name); // is Collapsed if (!entity.isCollapsed) return; rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); // Use Animation Clip EditorGUI.LabelField(_rect, "Use Animation"); _rect.x += 100; _rect.width = rect.width - 100; entity.useAnimationClip = EditorGUI.Toggle(_rect, entity.useAnimationClip); if (entity.useAnimationClip) { rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); // Animation Clip Slot EditorGUI.LabelField(_rect, "Clip"); _rect.x += 100; _rect.width = rect.width - 100; entity.animationClip = (AnimationClip)EditorGUI.ObjectField(_rect, entity.animationClip, typeof(AnimationClip), true); } else { rect.y += EditorGUIUtility.singleLineHeight * 1.25f; var gameObjectList = entity.GetReorderableList(target); gameObjectList.DoList(new Rect(rect.x, rect.y, rect.width, 20f)); } } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "Options"); } #endif } [System.Serializable] public class CVRAdvancedAvatarSettingMaterialColor : CVRAdvancesAvatarSettingBase { public Color defaultValue = Color.white; #if UNITY_EDITOR public List materialColorTargets = new List(); private CVRAdvancedSettingsTargetEntryMaterialColor entity; private ReorderableList gameObjectList; private CVRAvatar target; public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameterR = new AnimatorControllerParameter { name = machineName + "-r", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.r }; controller.AddParameter(animatorParameterR); var animatorParameterG = new AnimatorControllerParameter { name = machineName + "-g", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.g }; controller.AddParameter(animatorParameterG); var animatorParameterB = new AnimatorControllerParameter { name = machineName + "-b", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.b }; controller.AddParameter(animatorParameterB); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTreeRed = new BlendTree(); blendTreeRed.name = machineName + " Blend Tree Red"; blendTreeRed.blendParameter = machineName + "-r"; var blendTreeRedMin = new BlendTree(); blendTreeRedMin.name = machineName + " Blend Tree Red Min"; blendTreeRedMin.blendParameter = machineName + "-g"; blendTreeRedMin.useAutomaticThresholds = false; var blendTreeRedMax = new BlendTree(); blendTreeRedMax.name = machineName + " Blend Tree Red Max"; blendTreeRedMax.blendParameter = machineName + "-g"; blendTreeRedMax.useAutomaticThresholds = false; blendTreeRed.AddChild(blendTreeRedMin, 0f); blendTreeRed.AddChild(blendTreeRedMax, 1f); var blendTreeRedMinGreenMin = new BlendTree(); blendTreeRedMinGreenMin.name = machineName + " Blend Tree Red Min Green Min"; blendTreeRedMinGreenMin.blendParameter = machineName + "-b"; blendTreeRedMinGreenMin.useAutomaticThresholds = false; var blendTreeRedMinGreenMax = new BlendTree(); blendTreeRedMinGreenMax.name = machineName + " Blend Tree Red Min Green Max"; blendTreeRedMinGreenMax.blendParameter = machineName + "-b"; blendTreeRedMinGreenMax.useAutomaticThresholds = false; blendTreeRedMin.AddChild(blendTreeRedMinGreenMin, 0f); blendTreeRedMin.AddChild(blendTreeRedMinGreenMax, 1f); var blendTreeRedMaxGreenMin = new BlendTree(); blendTreeRedMaxGreenMin.name = machineName + " Blend Tree Red MaRed Green Min"; blendTreeRedMaxGreenMin.blendParameter = machineName + "-b"; blendTreeRedMaxGreenMin.useAutomaticThresholds = false; var blendTreeRedMaxGreenMax = new BlendTree(); blendTreeRedMaxGreenMax.name = machineName + " Blend Tree Red MaRed Green Max"; blendTreeRedMaxGreenMax.blendParameter = machineName + "-b"; blendTreeRedMaxGreenMax.useAutomaticThresholds = false; blendTreeRedMax.AddChild(blendTreeRedMaxGreenMin, 0f); blendTreeRedMax.AddChild(blendTreeRedMaxGreenMax, 1f); var clipR0G0B0 = new AnimationClip(); var clipR0G0B1 = new AnimationClip(); var clipR0G1B0 = new AnimationClip(); var clipR0G1B1 = new AnimationClip(); var clipR1G0B0 = new AnimationClip(); var clipR1G0B1 = new AnimationClip(); var clipR1G1B0 = new AnimationClip(); var clipR1G1B1 = new AnimationClip(); AnimationCurve animationCurve0 = new AnimationCurve(); animationCurve0.AddKey(0, 0); animationCurve0.AddKey(1f/60, 0); AnimationCurve animationCurve1 = new AnimationCurve(); animationCurve1.AddKey(0, 1); animationCurve1.AddKey(1f/60, 1); foreach (var target in materialColorTargets) { if(target.gameObject == null || target.propertyName == "" || target.treePath == null) continue; clipR0G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve0); clipR0G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve0); clipR0G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve0); clipR0G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve0); clipR1G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve1); clipR1G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve1); clipR1G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve1); clipR1G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".r", animationCurve1); clipR0G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve0); clipR0G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve0); clipR0G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve1); clipR0G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve1); clipR1G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve0); clipR1G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve0); clipR1G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve1); clipR1G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".g", animationCurve1); clipR0G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve0); clipR0G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve1); clipR0G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve0); clipR0G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve1); clipR1G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve0); clipR1G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve1); clipR1G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve0); clipR1G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".b", animationCurve1); clipR0G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR0G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR0G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR0G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR1G0B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR1G0B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR1G1B0.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); clipR1G1B1.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName + ".a", animationCurve1); } blendTreeRedMinGreenMin.AddChild(clipR0G0B0, 0); AssetDatabase.CreateAsset(clipR0G0B0, folderPath + "/Anim_" + machineName + "_Color_R0G0B0.anim"); blendTreeRedMinGreenMin.AddChild(clipR0G0B1, 1); AssetDatabase.CreateAsset(clipR0G0B1, folderPath + "/Anim_" + machineName + "_Color_R0G0B1.anim"); blendTreeRedMinGreenMax.AddChild(clipR0G1B0, 0); AssetDatabase.CreateAsset(clipR0G1B0, folderPath + "/Anim_" + machineName + "_Color_R0G1B0.anim"); blendTreeRedMinGreenMax.AddChild(clipR0G1B1, 1); AssetDatabase.CreateAsset(clipR0G1B1, folderPath + "/Anim_" + machineName + "_Color_R0G1B1.anim"); blendTreeRedMaxGreenMin.AddChild(clipR1G0B0, 0); AssetDatabase.CreateAsset(clipR1G0B0, folderPath + "/Anim_" + machineName + "_Color_R1G0B0.anim"); blendTreeRedMaxGreenMin.AddChild(clipR1G0B1, 1); AssetDatabase.CreateAsset(clipR1G0B1, folderPath + "/Anim_" + machineName + "_Color_R1G0B1.anim"); blendTreeRedMaxGreenMax.AddChild(clipR1G1B0, 0); AssetDatabase.CreateAsset(clipR1G1B0, folderPath + "/Anim_" + machineName + "_Color_R1G1B0.anim"); blendTreeRedMaxGreenMax.AddChild(clipR1G1B1, 1); AssetDatabase.CreateAsset(clipR1G1B1, folderPath + "/Anim_" + machineName + "_Color_R1G1B1.anim"); animatorState.motion = blendTreeRed; AssetDatabase.AddObjectToAsset(blendTreeRed, AssetDatabase.GetAssetPath(controller)); blendTreeRed.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMin, AssetDatabase.GetAssetPath(controller)); blendTreeRedMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMax, AssetDatabase.GetAssetPath(controller)); blendTreeRedMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMinGreenMin, AssetDatabase.GetAssetPath(controller)); blendTreeRedMinGreenMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMinGreenMax, AssetDatabase.GetAssetPath(controller)); blendTreeRedMinGreenMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMaxGreenMin, AssetDatabase.GetAssetPath(controller)); blendTreeRedMaxGreenMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeRedMaxGreenMax, AssetDatabase.GetAssetPath(controller)); blendTreeRedMaxGreenMax.hideFlags = HideFlags.HideInHierarchy; } private void generateReorderableList() { gameObjectList = new ReorderableList(materialColorTargets, typeof(CVRAdvancedSettingsTargetEntryMaterialColor), true, true, true, true); gameObjectList.drawHeaderCallback = OnDrawHeader; gameObjectList.drawElementCallback = OnDrawElement; gameObjectList.elementHeightCallback = OnHeightElement; gameObjectList.onAddCallback = OnAdd; gameObjectList.onChangedCallback = OnChanged; } public ReorderableList GetReorderableList(CVRAvatar avatar) { target = avatar; if (gameObjectList == null) generateReorderableList(); return gameObjectList; } private void OnChanged(ReorderableList list) { EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { materialColorTargets.Add(new CVRAdvancedSettingsTargetEntryMaterialColor()); } private float OnHeightElement(int index) { if (!materialColorTargets[index].isCollapsed) { return EditorGUIUtility.singleLineHeight * 1.25f; } else { return EditorGUIUtility.singleLineHeight * 3.75f; } } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > materialColorTargets.Count) return; entity = materialColorTargets[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); entity.isCollapsed = EditorGUI.Foldout(_rect, entity.isCollapsed, "Game Object", true); _rect.x += 100; _rect.width = rect.width - 100; var propertyList = new Dictionary(); var targetGameObject = (GameObject) EditorGUI.ObjectField(_rect, entity.gameObject, typeof(GameObject), true); if (targetGameObject != null && targetGameObject.transform.GetComponentInParent(typeof(CVRAvatar)) == target) { var meshRenderer = (MeshRenderer) targetGameObject.GetComponent(typeof(MeshRenderer)); var skinnedMeshRenderer = (SkinnedMeshRenderer) targetGameObject.GetComponent(typeof(SkinnedMeshRenderer)); var particleRenderer = (ParticleSystemRenderer) targetGameObject.GetComponent(typeof(ParticleSystemRenderer)); var lineRenderer = (LineRenderer) targetGameObject.GetComponent(typeof(LineRenderer)); var trailRenderer = (TrailRenderer) targetGameObject.GetComponent(typeof(TrailRenderer)); var rendererFound = false; if (meshRenderer != null) { for (var i = 0; i < meshRenderer.sharedMaterials.Length; i++) { var material = meshRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Color) { var propertyKey = "MeshRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add(propertyKey, "MSR:" + shader.GetPropertyName(j)); } } } } rendererFound = true; } if (skinnedMeshRenderer != null) { for (var i = 0; i < skinnedMeshRenderer.sharedMaterials.Length; i++) { var material = skinnedMeshRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Color) { var propertyKey = "SkinnedMeshRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add(propertyKey, "SMR:" + shader.GetPropertyName(j)); } } } } rendererFound = true; } if (particleRenderer != null) { for (var i = 0; i < particleRenderer.sharedMaterials.Length; i++) { var material = particleRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Color) { var propertyKey = "ParticleRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add(propertyKey, "PTR:" + shader.GetPropertyName(j)); } } } } rendererFound = true; } if (lineRenderer != null) { for (var i = 0; i < lineRenderer.sharedMaterials.Length; i++) { var material = lineRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Color) { var propertyKey = "LineRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add(propertyKey, "LNR:" + shader.GetPropertyName(j)); } } } } rendererFound = true; } if (trailRenderer != null) { for (var i = 0; i < trailRenderer.sharedMaterials.Length; i++) { var material = trailRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Color) { var propertyKey = "TrailRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add(propertyKey, "TLR:" + shader.GetPropertyName(j)); } } } } rendererFound = true; } if (rendererFound) { entity.gameObject = targetGameObject; entity.treePath = AnimationUtility.CalculateTransformPath(targetGameObject.transform, target.transform); } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } // is Collapsed if (!entity.isCollapsed) { switch (entity.propertyTypeIdentifier) { case "SMR": entity.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": entity.propertyType = typeof(MeshRenderer); break; case "PTR": entity.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": entity.propertyType = typeof(LineRenderer); break; case "TLR": entity.propertyType = typeof(TrailRenderer); break; default: entity.propertyType = typeof(SkinnedMeshRenderer); break; } return; } rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Path"); _rect.x += 100; _rect.width = rect.width - 100; EditorGUI.LabelField(_rect, entity.treePath); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); var propertyNames = new string[propertyList.Count]; propertyList.Values.CopyTo(propertyNames, 0); var propertyDescriptions = new string[propertyList.Count]; propertyList.Keys.CopyTo(propertyDescriptions, 0); EditorGUI.LabelField(_rect, "Property"); _rect.x += 100; _rect.width = rect.width - 100; var propertyIndex = EditorGUI.Popup(_rect, Array.IndexOf(propertyNames, entity.propertyTypeIdentifier + ":" + entity.propertyName), propertyDescriptions); if (propertyIndex >= 0) { var property = propertyNames[propertyIndex]; entity.propertyName = property.Substring(4); entity.propertyTypeIdentifier = property.Substring(0, 3); switch (entity.propertyTypeIdentifier) { case "SMR": entity.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": entity.propertyType = typeof(MeshRenderer); break; case "PTR": entity.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": entity.propertyType = typeof(LineRenderer); break; case "TLR": entity.propertyType = typeof(TrailRenderer); break; default: entity.propertyType = typeof(SkinnedMeshRenderer); break; } } } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "Material Properties"); } public void RunCollapsedSetup() { foreach (var materialColorTarget in materialColorTargets) { switch (materialColorTarget.propertyTypeIdentifier) { case "SMR": materialColorTarget.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": materialColorTarget.propertyType = typeof(MeshRenderer); break; case "PTR": materialColorTarget.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": materialColorTarget.propertyType = typeof(LineRenderer); break; case "TLR": materialColorTarget.propertyType = typeof(TrailRenderer); break; default: materialColorTarget.propertyType = typeof(SkinnedMeshRenderer); break; } } } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingSlider : CVRAdvancesAvatarSettingBase { public float defaultValue; public List materialPropertyTargets = new List(); private CVRAdvancedSettingsTargetEntryMaterialProperty entity; #if UNITY_EDITOR public bool useAnimationClip; public AnimationClip minAnimationClip; public AnimationClip maxAnimationClip; private ReorderableList gameObjectList; private CVRAvatar target; public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue }; controller.AddParameter(animatorParameter); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName; var minClip = new AnimationClip(); var maxClip = new AnimationClip(); foreach (var target in materialPropertyTargets) { if(target.gameObject == null || target.propertyName == "" || target.treePath == null) continue; AnimationCurve animationCurve0 = new AnimationCurve(); animationCurve0.AddKey(0, target.minValue); animationCurve0.AddKey(1f/60, target.minValue); AnimationCurve animationCurve1 = new AnimationCurve(); animationCurve1.AddKey(0, target.maxValue); animationCurve1.AddKey(1f/60, target.maxValue); minClip.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName, animationCurve0); maxClip.SetCurve(target.treePath, target.propertyType, "material." + target.propertyName, animationCurve1); } if (useAnimationClip) { minClip = minAnimationClip; maxClip = maxAnimationClip; } else { AssetDatabase.CreateAsset(minClip, folderPath + "/Anim_" + machineName + "_Slider_Min.anim"); AssetDatabase.CreateAsset(maxClip, folderPath + "/Anim_" + machineName + "_Slider_Max.anim"); } blendTree.AddChild(minClip, 0f); blendTree.AddChild(maxClip, 1f); animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; } private void generateReorderableList() { gameObjectList = new ReorderableList(materialPropertyTargets, typeof(CVRAdvancedSettingsTargetEntryMaterialProperty), true, true, true, true); gameObjectList.drawHeaderCallback = OnDrawHeader; gameObjectList.drawElementCallback = OnDrawElement; gameObjectList.elementHeightCallback = OnHeightElement; gameObjectList.onAddCallback = OnAdd; gameObjectList.onChangedCallback = OnChanged; } public ReorderableList GetReorderableList(CVRAvatar avatar) { target = avatar; if (gameObjectList == null) generateReorderableList(); return gameObjectList; } private void OnChanged(ReorderableList list) { EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { materialPropertyTargets.Add(new CVRAdvancedSettingsTargetEntryMaterialProperty()); } private float OnHeightElement(int index) { if (!materialPropertyTargets[index].isCollapsed) { return EditorGUIUtility.singleLineHeight * 1.25f; } else { return EditorGUIUtility.singleLineHeight * 5 * 1.25f; } } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > materialPropertyTargets.Count) return; entity = materialPropertyTargets[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); entity.isCollapsed = EditorGUI.Foldout(_rect, entity.isCollapsed, "Game Object", true); _rect.x += 100; _rect.width = rect.width - 100; var propertyList = new Dictionary(); var targetGameObject = (GameObject) EditorGUI.ObjectField(_rect, entity.gameObject, typeof(GameObject), true); if (targetGameObject != null && targetGameObject.transform.GetComponentInParent(typeof(CVRAvatar)) == target) { var meshRenderer = (MeshRenderer) targetGameObject.GetComponent(typeof(MeshRenderer)); var skinnedMeshRenderer = (SkinnedMeshRenderer) targetGameObject.GetComponent(typeof(SkinnedMeshRenderer)); var particleRenderer = (ParticleSystemRenderer) targetGameObject.GetComponent(typeof(ParticleSystemRenderer)); var lineRenderer = (LineRenderer) targetGameObject.GetComponent(typeof(LineRenderer)); var trailRenderer = (TrailRenderer) targetGameObject.GetComponent(typeof(TrailRenderer)); var rendererFound = false; if (meshRenderer != null) { for (var i = 0; i < meshRenderer.sharedMaterials.Length; i++) { var material = meshRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range) { var propertyKey = "MeshRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "MSR:" + shader.GetPropertyName(j) ); } } } } rendererFound = true; } if (skinnedMeshRenderer != null) { for (var i = 0; i < skinnedMeshRenderer.sharedMaterials.Length; i++) { var material = skinnedMeshRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range) { var propertyKey = "SkinnedMeshRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "SMR:" + shader.GetPropertyName(j) ); } } } } rendererFound = true; } if (particleRenderer != null) { for (var i = 0; i < particleRenderer.sharedMaterials.Length; i++) { var material = particleRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range) { var propertyKey = "ParticleRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "PTR:" + shader.GetPropertyName(j) ); } } } } rendererFound = true; } if (lineRenderer != null) { for (var i = 0; i < lineRenderer.sharedMaterials.Length; i++) { var material = lineRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range) { var propertyKey = "LineRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "LNR:" + shader.GetPropertyName(j) ); } } } } rendererFound = true; } if (trailRenderer != null) { for (var i = 0; i < trailRenderer.sharedMaterials.Length; i++) { var material = trailRenderer.sharedMaterials[i]; if (material == null) continue; var shader = material.shader; for (var j = 0; j < shader.GetPropertyCount(); j++) { if (shader.GetPropertyType(j) == ShaderPropertyType.Float || shader.GetPropertyType(j) == ShaderPropertyType.Range) { var propertyKey = "TrailRenderer: " + shader.GetPropertyDescription(j) + "(" + shader.GetPropertyName(j) + ")"; if (!propertyList.ContainsKey(propertyKey)) { propertyList.Add( propertyKey, "TLR:" + shader.GetPropertyName(j) ); } } } } rendererFound = true; } if (rendererFound) { entity.gameObject = targetGameObject; entity.treePath = AnimationUtility.CalculateTransformPath(targetGameObject.transform, target.transform); } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } // is Collapsed if (!entity.isCollapsed) { switch (entity.propertyTypeIdentifier) { case "SMR": entity.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": entity.propertyType = typeof(MeshRenderer); break; case "PTR": entity.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": entity.propertyType = typeof(LineRenderer); break; case "TLR": entity.propertyType = typeof(TrailRenderer); break; default: entity.propertyType = typeof(SkinnedMeshRenderer); break; } return; } rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Path"); _rect.x += 100; _rect.width = rect.width - 100; EditorGUI.LabelField(_rect, entity.treePath); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); var propertyNames = new string[propertyList.Count]; propertyList.Values.CopyTo(propertyNames, 0); var propertyDescriptions = new string[propertyList.Count]; propertyList.Keys.CopyTo(propertyDescriptions, 0); EditorGUI.LabelField(_rect, "Property"); _rect.x += 100; _rect.width = rect.width - 100; var propertyIndex = EditorGUI.Popup(_rect, Array.IndexOf(propertyNames, entity.propertyTypeIdentifier + ":" + entity.propertyName), propertyDescriptions); if (propertyIndex >= 0) { var property = propertyNames[propertyIndex]; entity.propertyName = property.Substring(4); entity.propertyTypeIdentifier = property.Substring(0, 3); switch (entity.propertyTypeIdentifier) { case "SMR": entity.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": entity.propertyType = typeof(MeshRenderer); break; case "PTR": entity.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": entity.propertyType = typeof(LineRenderer); break; case "TLR": entity.propertyType = typeof(TrailRenderer); break; default: entity.propertyType = typeof(SkinnedMeshRenderer); break; } } rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Min Value"); _rect.x += 100; _rect.width = rect.width - 100; entity.minValue = EditorGUI.FloatField(_rect, entity.minValue); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Max Value"); _rect.x += 100; _rect.width = rect.width - 100; entity.maxValue = EditorGUI.FloatField(_rect, entity.maxValue); } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "Material Properties"); } public void RunCollapsedSetup() { foreach (var materialPropertyTarget in materialPropertyTargets) { switch (materialPropertyTarget.propertyTypeIdentifier) { case "SMR": materialPropertyTarget.propertyType = typeof(SkinnedMeshRenderer); break; case "MSR": materialPropertyTarget.propertyType = typeof(MeshRenderer); break; case "PTR": materialPropertyTarget.propertyType = typeof(ParticleSystemRenderer); break; case "LNR": materialPropertyTarget.propertyType = typeof(LineRenderer); break; case "TLR": materialPropertyTarget.propertyType = typeof(TrailRenderer); break; default: materialPropertyTarget.propertyType = typeof(SkinnedMeshRenderer); break; } } } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingJoystick2D : CVRAdvancesAvatarSettingBase { public Vector2 defaultValue = Vector2.zero; public Vector2 rangeMin = new Vector2(0, 0); public Vector2 rangeMax = new Vector2(1, 1); #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameterX = new AnimatorControllerParameter { name = machineName + "-x", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.x }; controller.AddParameter(animatorParameterX); var animatorParameterY = new AnimatorControllerParameter { name = machineName + "-y", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.y }; controller.AddParameter(animatorParameterY); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName + "-x"; blendTree.useAutomaticThresholds = false; var blendTreeXMin = new BlendTree(); blendTreeXMin.name = machineName + " Blend Tree X Min"; blendTreeXMin.blendParameter = machineName + "-y"; blendTreeXMin.useAutomaticThresholds = false; var blendTreeXMax = new BlendTree(); blendTreeXMax.name = machineName + " Blend Tree X Max"; blendTreeXMax.blendParameter = machineName + "-y"; blendTreeXMax.useAutomaticThresholds = false; blendTree.AddChild(blendTreeXMin, rangeMin.x); blendTree.AddChild(blendTreeXMax, rangeMax.x); var X0Y0Clip = new AnimationClip(); var X0Y1Clip = new AnimationClip(); var X1Y0Clip = new AnimationClip(); var X1Y1Clip = new AnimationClip(); blendTreeXMin.AddChild(X0Y0Clip, rangeMin.y); AssetDatabase.CreateAsset(X0Y0Clip, folderPath + "/Anim_" + machineName + "_Joystick2D_X0Y0.anim"); blendTreeXMin.AddChild(X0Y1Clip, rangeMax.y); AssetDatabase.CreateAsset(X0Y1Clip, folderPath + "/Anim_" + machineName + "_Joystick2D_X0Y1.anim"); blendTreeXMax.AddChild(X1Y0Clip, rangeMin.y); AssetDatabase.CreateAsset(X1Y0Clip, folderPath + "/Anim_" + machineName + "_Joystick2D_X1Y0.anim"); blendTreeXMax.AddChild(X1Y1Clip, rangeMax.y); AssetDatabase.CreateAsset(X1Y1Clip, folderPath + "/Anim_" + machineName + "_Joystick2D_X1Y1.anim"); animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMax.hideFlags = HideFlags.HideInHierarchy; } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingJoystick3D : CVRAdvancesAvatarSettingBase { public Vector3 defaultValue = Vector3.zero; public Vector2 rangeMin = new Vector2(0, 0); public Vector2 rangeMax = new Vector2(1, 1); #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameterX = new AnimatorControllerParameter { name = machineName + "-x", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.x }; controller.AddParameter(animatorParameterX); var animatorParameterY = new AnimatorControllerParameter { name = machineName + "-y", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.y }; controller.AddParameter(animatorParameterY); var animatorParameterZ = new AnimatorControllerParameter { name = machineName + "-z", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.z }; controller.AddParameter(animatorParameterZ); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTreeX = new BlendTree(); blendTreeX.name = machineName + " Blend Tree x"; blendTreeX.blendParameter = machineName + "-x"; blendTreeX.useAutomaticThresholds = false; var blendTreeXMin = new BlendTree(); blendTreeXMin.name = machineName + " Blend Tree X Min"; blendTreeXMin.blendParameter = machineName + "-y"; blendTreeXMin.useAutomaticThresholds = false; var blendTreeXMax = new BlendTree(); blendTreeXMax.name = machineName + " Blend Tree X Max"; blendTreeXMax.blendParameter = machineName + "-y"; blendTreeXMax.useAutomaticThresholds = false; blendTreeX.AddChild(blendTreeXMin, rangeMin.x); blendTreeX.AddChild(blendTreeXMax, rangeMax.x); var blendTreeXMinYMin = new BlendTree(); blendTreeXMinYMin.name = machineName + " Blend Tree X Min Y Min"; blendTreeXMinYMin.blendParameter = machineName + "-z"; blendTreeXMinYMin.useAutomaticThresholds = false; var blendTreeXMinYMax = new BlendTree(); blendTreeXMinYMax.name = machineName + " Blend Tree X Min Y Max"; blendTreeXMinYMax.blendParameter = machineName + "-z"; blendTreeXMinYMax.useAutomaticThresholds = false; blendTreeXMin.AddChild(blendTreeXMinYMin, rangeMin.y); blendTreeXMin.AddChild(blendTreeXMinYMax, rangeMax.y); var blendTreeXMaxYMin = new BlendTree(); blendTreeXMaxYMin.name = machineName + " Blend Tree X Max Y Min"; blendTreeXMaxYMin.blendParameter = machineName + "-z"; blendTreeXMaxYMin.useAutomaticThresholds = false; var blendTreeXMaxYMax = new BlendTree(); blendTreeXMaxYMax.name = machineName + " Blend Tree X Max Y Max"; blendTreeXMaxYMax.blendParameter = machineName + "-z"; blendTreeXMaxYMax.useAutomaticThresholds = false; blendTreeXMax.AddChild(blendTreeXMaxYMin, rangeMin.y); blendTreeXMax.AddChild(blendTreeXMaxYMax, rangeMax.y); var clipX0Y0Z0 = new AnimationClip(); var clipX0Y0Z1 = new AnimationClip(); var clipX0Y1Z0 = new AnimationClip(); var clipX0Y1Z1 = new AnimationClip(); var clipX1Y0Z0 = new AnimationClip(); var clipX1Y0Z1 = new AnimationClip(); var clipX1Y1Z0 = new AnimationClip(); var clipX1Y1Z1 = new AnimationClip(); blendTreeXMinYMin.AddChild(clipX0Y0Z0, 0f); AssetDatabase.CreateAsset(clipX0Y0Z0, folderPath + "/Anim_" + machineName + "_Joystick3D_X0Y0Z0.anim"); blendTreeXMinYMin.AddChild(clipX0Y0Z1, 1f); AssetDatabase.CreateAsset(clipX0Y0Z1, folderPath + "/Anim_" + machineName + "_Joystick3D_X0Y0Z1.anim"); blendTreeXMinYMax.AddChild(clipX0Y1Z0, 0f); AssetDatabase.CreateAsset(clipX0Y1Z0, folderPath + "/Anim_" + machineName + "_Joystick3D_X0Y1Z0.anim"); blendTreeXMinYMax.AddChild(clipX0Y1Z1, 1f); AssetDatabase.CreateAsset(clipX0Y1Z1, folderPath + "/Anim_" + machineName + "_Joystick3D_X0Y1Z1.anim"); blendTreeXMaxYMin.AddChild(clipX1Y0Z0, 0f); AssetDatabase.CreateAsset(clipX1Y0Z0, folderPath + "/Anim_" + machineName + "_Joystick3D_X1Y0Z0.anim"); blendTreeXMaxYMin.AddChild(clipX1Y0Z1, 1f); AssetDatabase.CreateAsset(clipX1Y0Z1, folderPath + "/Anim_" + machineName + "_Joystick3D_X1Y0Z1.anim"); blendTreeXMaxYMax.AddChild(clipX1Y1Z0, 0f); AssetDatabase.CreateAsset(clipX1Y1Z0, folderPath + "/Anim_" + machineName + "_Joystick3D_X1Y1Z0.anim"); blendTreeXMaxYMax.AddChild(clipX1Y1Z1, 1f); AssetDatabase.CreateAsset(clipX1Y1Z1, folderPath + "/Anim_" + machineName + "_Joystick3D_X1Y1Z1.anim"); animatorState.motion = blendTreeX; AssetDatabase.AddObjectToAsset(blendTreeX, AssetDatabase.GetAssetPath(controller)); blendTreeX.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMinYMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMinYMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMinYMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMinYMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMaxYMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMaxYMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMaxYMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMaxYMax.hideFlags = HideFlags.HideInHierarchy; } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingInputSingle : CVRAdvancesAvatarSettingBase { public float defaultValue; #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameter = new AnimatorControllerParameter { name = machineName, type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue }; controller.AddParameter(animatorParameter); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName; blendTree.useAutomaticThresholds = false; var minClip = new AnimationClip(); var maxClip = new AnimationClip(); blendTree.AddChild(minClip, -9999f); AssetDatabase.CreateAsset(minClip, folderPath + "/Anim_" + machineName + "_InputSingle_Min.anim"); blendTree.AddChild(maxClip, 9999f); AssetDatabase.CreateAsset(maxClip, folderPath + "/Anim_" + machineName + "_InputSingle_Max.anim"); animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingInputVector2 : CVRAdvancesAvatarSettingBase { public Vector2 defaultValue = Vector2.zero; #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameterX = new AnimatorControllerParameter { name = machineName + "-x", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.x }; controller.AddParameter(animatorParameterX); var animatorParameterY = new AnimatorControllerParameter { name = machineName + "-y", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.y }; controller.AddParameter(animatorParameterY); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTree = new BlendTree(); blendTree.name = machineName + " Blend Tree"; blendTree.blendParameter = machineName + "-x"; blendTree.useAutomaticThresholds = false; var blendTreeXMin = new BlendTree(); blendTreeXMin.name = machineName + " Blend Tree X Min"; blendTreeXMin.blendParameter = machineName + "-y"; blendTreeXMin.useAutomaticThresholds = false; var blendTreeXMax = new BlendTree(); blendTreeXMax.name = machineName + " Blend Tree X Max"; blendTreeXMax.blendParameter = machineName + "-y"; blendTreeXMax.useAutomaticThresholds = false; blendTree.AddChild(blendTreeXMin, -9999f); blendTree.AddChild(blendTreeXMax, 9999f); var X0Y0Clip = new AnimationClip(); var X0Y1Clip = new AnimationClip(); var X1Y0Clip = new AnimationClip(); var X1Y1Clip = new AnimationClip(); blendTreeXMin.AddChild(X0Y0Clip, -9999f); AssetDatabase.CreateAsset(X0Y0Clip, folderPath + "/Anim_" + machineName + "_InputVector2_X0Y0.anim"); blendTreeXMin.AddChild(X0Y1Clip, 9999f); AssetDatabase.CreateAsset(X0Y1Clip, folderPath + "/Anim_" + machineName + "_InputVector2_X0Y1.anim"); blendTreeXMax.AddChild(X1Y0Clip, -9999f); AssetDatabase.CreateAsset(X1Y0Clip, folderPath + "/Anim_" + machineName + "_InputVector2_X1Y0.anim"); blendTreeXMax.AddChild(X1Y1Clip, 9999f); AssetDatabase.CreateAsset(X1Y1Clip, folderPath + "/Anim_" + machineName + "_InputVector2_X1Y1.anim"); animatorState.motion = blendTree; AssetDatabase.AddObjectToAsset(blendTree, AssetDatabase.GetAssetPath(controller)); blendTree.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMax.hideFlags = HideFlags.HideInHierarchy; } #endif } [System.Serializable] public class CVRAdvancesAvatarSettingInputVector3 : CVRAdvancesAvatarSettingBase { public Vector3 defaultValue = Vector3.zero; #if UNITY_EDITOR public override void SetupAnimator(ref AnimatorController controller, string machineName, string folderPath) { var animatorLayer = new UnityEditor.Animations.AnimatorControllerLayer { name = machineName, defaultWeight = 1f, stateMachine = new AnimatorStateMachine() }; animatorLayer.stateMachine.name = machineName; AssetDatabase.AddObjectToAsset(animatorLayer.stateMachine, AssetDatabase.GetAssetPath(controller)); animatorLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy; controller.AddLayer(animatorLayer); var animatorParameterX = new AnimatorControllerParameter { name = machineName + "-x", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.x }; controller.AddParameter(animatorParameterX); var animatorParameterY = new AnimatorControllerParameter { name = machineName + "-y", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.y }; controller.AddParameter(animatorParameterY); var animatorParameterZ = new AnimatorControllerParameter { name = machineName + "-z", type = AnimatorControllerParameterType.Float, defaultFloat = defaultValue.z }; controller.AddParameter(animatorParameterZ); var animatorState = animatorLayer.stateMachine.AddState(machineName + " Blend Tree"); var blendTreeX = new BlendTree(); blendTreeX.name = machineName + " Blend Tree x"; blendTreeX.blendParameter = machineName + "-x"; blendTreeX.useAutomaticThresholds = false; var blendTreeXMin = new BlendTree(); blendTreeXMin.name = machineName + " Blend Tree X Min"; blendTreeXMin.blendParameter = machineName + "-y"; blendTreeXMin.useAutomaticThresholds = false; var blendTreeXMax = new BlendTree(); blendTreeXMax.name = machineName + " Blend Tree X Max"; blendTreeXMax.blendParameter = machineName + "-y"; blendTreeXMax.useAutomaticThresholds = false; blendTreeX.AddChild(blendTreeXMin, -9999f); blendTreeX.AddChild(blendTreeXMax, 9999f); var blendTreeXMinYMin = new BlendTree(); blendTreeXMinYMin.name = machineName + " Blend Tree X Min Y Min"; blendTreeXMinYMin.blendParameter = machineName + "-z"; blendTreeXMinYMin.useAutomaticThresholds = false; var blendTreeXMinYMax = new BlendTree(); blendTreeXMinYMax.name = machineName + " Blend Tree X Min Y Max"; blendTreeXMinYMax.blendParameter = machineName + "-z"; blendTreeXMinYMax.useAutomaticThresholds = false; blendTreeXMin.AddChild(blendTreeXMinYMin, -9999f); blendTreeXMin.AddChild(blendTreeXMinYMax, 9999f); var blendTreeXMaxYMin = new BlendTree(); blendTreeXMaxYMin.name = machineName + " Blend Tree X Max Y Min"; blendTreeXMaxYMin.blendParameter = machineName + "-z"; blendTreeXMaxYMin.useAutomaticThresholds = false; var blendTreeXMaxYMax = new BlendTree(); blendTreeXMaxYMax.name = machineName + " Blend Tree X Max Y Max"; blendTreeXMaxYMax.blendParameter = machineName + "-z"; blendTreeXMaxYMax.useAutomaticThresholds = false; blendTreeXMax.AddChild(blendTreeXMaxYMin, -9999f); blendTreeXMax.AddChild(blendTreeXMaxYMax, 9999f); var clipX0Y0Z0 = new AnimationClip(); var clipX0Y0Z1 = new AnimationClip(); var clipX0Y1Z0 = new AnimationClip(); var clipX0Y1Z1 = new AnimationClip(); var clipX1Y0Z0 = new AnimationClip(); var clipX1Y0Z1 = new AnimationClip(); var clipX1Y1Z0 = new AnimationClip(); var clipX1Y1Z1 = new AnimationClip(); blendTreeXMinYMin.AddChild(clipX0Y0Z0, -9999f); AssetDatabase.CreateAsset(clipX0Y0Z0, folderPath + "/Anim_" + machineName + "_InputVector3_X0Y0Z0.anim"); blendTreeXMinYMin.AddChild(clipX0Y0Z1, 9999f); AssetDatabase.CreateAsset(clipX0Y0Z1, folderPath + "/Anim_" + machineName + "_InputVector3_X0Y0Z1.anim"); blendTreeXMinYMax.AddChild(clipX0Y1Z0, -9999f); AssetDatabase.CreateAsset(clipX0Y1Z0, folderPath + "/Anim_" + machineName + "_InputVector3_X0Y1Z0.anim"); blendTreeXMinYMax.AddChild(clipX0Y1Z1, 9999f); AssetDatabase.CreateAsset(clipX0Y1Z1, folderPath + "/Anim_" + machineName + "_InputVector3_X0Y1Z1.anim"); blendTreeXMaxYMin.AddChild(clipX1Y0Z0, -9999f); AssetDatabase.CreateAsset(clipX1Y0Z0, folderPath + "/Anim_" + machineName + "_InputVector3_X1Y0Z0.anim"); blendTreeXMaxYMin.AddChild(clipX1Y0Z1, 9999f); AssetDatabase.CreateAsset(clipX1Y0Z1, folderPath + "/Anim_" + machineName + "_InputVector3_X1Y0Z1.anim"); blendTreeXMaxYMax.AddChild(clipX1Y1Z0, -9999f); AssetDatabase.CreateAsset(clipX1Y1Z0, folderPath + "/Anim_" + machineName + "_InputVector3_X1Y1Z0.anim"); blendTreeXMaxYMax.AddChild(clipX1Y1Z1, 9999f); AssetDatabase.CreateAsset(clipX1Y1Z1, folderPath + "/Anim_" + machineName + "_InputVector3_X1Y1Z1.anim"); animatorState.motion = blendTreeX; AssetDatabase.AddObjectToAsset(blendTreeX, AssetDatabase.GetAssetPath(controller)); blendTreeX.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMinYMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMinYMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMinYMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMinYMax.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMaxYMin, AssetDatabase.GetAssetPath(controller)); blendTreeXMaxYMin.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(blendTreeXMaxYMax, AssetDatabase.GetAssetPath(controller)); blendTreeXMaxYMax.hideFlags = HideFlags.HideInHierarchy; } #endif } [System.Serializable] public class CVRAdvancedSettingsTargetEntryGameObject { #if UNITY_EDITOR public bool isCollapsed; #endif public GameObject gameObject; public string treePath; public bool onState = true; } [System.Serializable] public class CVRAdvancedSettingsDropDownEntry { public string name; #if UNITY_EDITOR public bool isCollapsed; public bool useAnimationClip; public AnimationClip animationClip; public List gameObjectTargets = new List(); private ReorderableList gameObjectList; private CVRAvatar target; private void generateReorderableList() { gameObjectList = new ReorderableList(gameObjectTargets, typeof(CVRAdvancedSettingsTargetEntryGameObject), true, true, true, true); gameObjectList.drawHeaderCallback = OnDrawHeader; gameObjectList.drawElementCallback = OnDrawElement; gameObjectList.elementHeightCallback = OnHeightElement; gameObjectList.onAddCallback = OnAdd; gameObjectList.onChangedCallback = OnChanged; } public ReorderableList GetReorderableList(CVRAvatar avatar) { target = avatar; if (gameObjectList == null) generateReorderableList(); return gameObjectList; } private void OnChanged(ReorderableList list) { EditorUtility.SetDirty(target); } private void OnAdd(ReorderableList list) { gameObjectTargets.Add(new CVRAdvancedSettingsTargetEntryGameObject()); } private float OnHeightElement(int index) { CVRAdvancedSettingsTargetEntryGameObject entity = gameObjectTargets[index]; if (!entity.isCollapsed) { return EditorGUIUtility.singleLineHeight * 1.25f; } else { return EditorGUIUtility.singleLineHeight * 3 * 1.25f; } } private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused) { if (index > gameObjectTargets.Count) return; CVRAdvancedSettingsTargetEntryGameObject entity = gameObjectTargets[index]; rect.y += 2; rect.x += 12; rect.width -= 12; Rect _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); entity.isCollapsed = EditorGUI.Foldout(_rect, entity.isCollapsed, "Name", true); _rect.x += 100; _rect.width = rect.width - 100; var targetGameObject = (GameObject) EditorGUI.ObjectField(_rect, entity.gameObject, typeof(GameObject), true); if (targetGameObject != null && targetGameObject.transform.GetComponentInParent(typeof(CVRAvatar)) == target) { entity.gameObject = targetGameObject; entity.treePath = AnimationUtility.CalculateTransformPath(targetGameObject.transform, target.transform); } else if (entity.gameObject != targetGameObject) { entity.gameObject = null; entity.treePath = ""; } // is Collapsed if (!entity.isCollapsed) return; rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, "Path"); _rect.x += 100; _rect.width = rect.width - 100; EditorGUI.LabelField(_rect, entity.treePath); rect.y += EditorGUIUtility.singleLineHeight * 1.25f; _rect = new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight); EditorGUI.LabelField(_rect, new GUIContent("Set to", "If checked, the object will be active once the toggle was pressed. If unchecked the object " + "will be deactivated when the toggle is pressed.")); _rect.x += 100; _rect.width = rect.width - 100; entity.onState = EditorGUI.Toggle(_rect, entity.onState); } private void OnDrawHeader(Rect rect) { Rect _rect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); GUI.Label(_rect, "GameObjects"); } #endif } [System.Serializable] public class CVRAdvancedSettingsTargetEntryMaterialColor { #if UNITY_EDITOR public bool isCollapsed; #endif public GameObject gameObject; public string treePath; [SerializeField] public Type propertyType; public string propertyTypeIdentifier; public string propertyName; } [System.Serializable] public class CVRAdvancedSettingsTargetEntryMaterialProperty { #if UNITY_EDITOR public bool isCollapsed; #endif public GameObject gameObject; public string treePath; [SerializeField] public Type propertyType; public string propertyTypeIdentifier; public string propertyName; public float minValue; public float maxValue; } }