cvr-props/Assets/ABI.CCK/Scripts/CVRAdvancedAvatarSettings.cs

2377 lines
106 KiB
C#
Raw Normal View History

2023-01-22 16:38:23 +01:00
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<CVRAdvancedSettingsEntry> settings = new List<CVRAdvancedSettingsEntry>();
}
[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;
2023-07-30 01:20:46 +02:00
public AnimationClip offAnimationClip;
2023-01-22 16:38:23 +01:00
public List<CVRAdvancedSettingsTargetEntryGameObject> gameObjectTargets =
new List<CVRAdvancedSettingsTargetEntryGameObject>();
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;
2023-07-30 01:20:46 +02:00
if (offAnimationClip != null)
{
offClip = offAnimationClip;
}
else
{
AssetDatabase.CreateAsset(offClip, folderPath + "/Anim_" + machineName + "_Toggle_Off.anim");
}
2023-01-22 16:38:23 +01:00
}
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<CVRAdvancedSettingsDropDownEntry> options = new List<CVRAdvancedSettingsDropDownEntry>();
#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<AnimationClip> animations = new List<AnimationClip>();
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<CVRAdvancedSettingsTargetEntryGameObject>();
var inActiveGameobjects = new List<CVRAdvancedSettingsTargetEntryGameObject>();
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<CVRAdvancedSettingsTargetEntryMaterialColor> materialColorTargets =
new List<CVRAdvancedSettingsTargetEntryMaterialColor>();
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<string, string>();
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<CVRAdvancedSettingsTargetEntryMaterialProperty> materialPropertyTargets =
new List<CVRAdvancedSettingsTargetEntryMaterialProperty>();
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<string, string>();
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<CVRAdvancedSettingsTargetEntryGameObject> gameObjectTargets = new List<CVRAdvancedSettingsTargetEntryGameObject>();
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;
}
}