/// <summary> /// Awake is called after all of the actions have been initialized. /// </summary> public override void Awake() { base.Awake(); if (!string.IsNullOrEmpty(m_EffectName)) { m_Effect = m_CharacterLocomotion.GetEffect(UnityEngineUtility.GetType(m_EffectName), m_EffectIndex); } if (m_Effect == null) { Debug.LogError($"Error: Unable to find effect {m_EffectName}."); } }
/// <summary> /// Initialize the collider layers after the UltimateCharacterLocomotion has been initialized. /// </summary> private void Start() { m_ColliderGameObjects = new GameObject[m_CharacterLocomotion.ColliderCount]; for (int i = 0; i < m_ColliderGameObjects.Length; ++i) { m_ColliderGameObjects[i] = m_CharacterLocomotion.Colliders[i].gameObject; } m_ColliderLayers = new int[m_CharacterLocomotion.ColliderCount]; if (!string.IsNullOrEmpty(m_DamagedEffectName)) { m_DamagedEffect = m_CharacterLocomotion.GetEffect(UnityEngineUtility.GetType(m_DamagedEffectName), m_DamagedEffectIndex); } }
/// <summary> /// Deserialize the view types. /// </summary> /// <param name="forceDeserialization">Should the view types be force deserialized?</param> /// <returns>Were any view types removed?</returns> public bool DeserializeViewTypes(bool forceDeserialization) { // The View Types only need to be deserialized once. if (m_ViewTypes != null && !forceDeserialization) { return(false); } var dirty = false; if (m_ViewTypeData != null && m_ViewTypeData.Length > 0) { m_ViewTypes = new ViewType[m_ViewTypeData.Length]; m_ViewTypeNameMap.Clear(); for (int i = 0; i < m_ViewTypeData.Length; ++i) { m_ViewTypes[i] = m_ViewTypeData[i].DeserializeFields(MemberVisibility.Public) as ViewType; if (m_ViewTypes[i] == null) { dirty = true; continue; } // The transitioning view type is saved separately. if (m_ViewTypes[i] is Transition) { m_Transitioner = m_ViewTypes[i] as Transition; } else { m_ViewTypeNameMap.Add(m_ViewTypes[i].GetType().FullName, i); } if (Application.isPlaying) { m_ViewTypes[i].Initialize(this); } } } if (UnityEngineUtility.GetType(m_ViewTypeFullName) != null) { SetViewType(m_ViewTypeFullName); } else { SetViewType(m_ViewTypes[0].GetType(), false); } return(dirty); }
/// <summary> /// Initializes the avialable property array. Can be called at any point if the array may have changed. /// </summary> private void InitializeAvailablePropertyArray() { m_AvailableProperies.Clear(); var availablePropertyNames = new List <string>(); // The properties name list should always show "Add Property..." first. availablePropertyNames.Add("Add Property..."); // Get a list of all available property types on the current preset. var preset = target as PersistablePreset; var objType = UnityEngineUtility.GetType(preset.Data.ObjectType); if (objType != null) { var valuePositionMap = new Dictionary <int, int>(preset.Data.ValueHashes.Length); for (int i = 0; i < preset.Data.ValueHashes.Length; ++i) { valuePositionMap.Add(preset.Data.ValueHashes[i], i); } var properties = Serialization.GetSerializedProperties(objType, m_Visiblity); // Add to the available property names list based on the property types that have not already been added. for (int i = 0; i < properties.Length; ++i) { var hash = Serialization.StringHash(properties[i].PropertyType.FullName) + Serialization.StringHash(properties[i].Name); // The property is not currently being serialized. if (!valuePositionMap.ContainsKey(hash)) { // The property may not be valid. if (Serialization.GetValidGetMethod(properties[i], m_Visiblity) == null) { continue; } // The property is valid. Add it to the list. availablePropertyNames.Add(InspectorUtility.SplitCamelCase(properties[i].Name)); m_AvailableProperies.Add(properties[i]); } } } // Save the list to an array. m_AvailablePropertyNames = availablePropertyNames.ToArray(); }
/// <summary> /// Sets the view type to the object with the specified type. /// </summary> /// <param name="typeName">The type name of the ViewType which should be set.</param> private void SetViewType(string typeName) { SetViewType(UnityEngineUtility.GetType(typeName), false); }
/// <summary> /// If the specified classes exist then the compiler symbol should be defined, otherwise the symbol should be removed. /// </summary> static DefineCompilerSymbols() { // The First Person Controller Combat MovementType will exist when the First Person Controller asset is imported. var firstPersonControllerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Character.MovementTypes.Combat") != null; #if FIRST_PERSON_CONTROLLER if (!firstPersonControllerExists) { RemoveSymbol(s_FirstPersonControllerSymbol); } #else if (firstPersonControllerExists) { AddSymbol(s_FirstPersonControllerSymbol); } #endif // The Third Person Controller Combat MovementType will exist when the Third Person Controller asset is imported. var thirdPersonControllerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Combat") != null; #if THIRD_PERSON_CONTROLLER if (!thirdPersonControllerExists) { RemoveSymbol(s_ThirdPersonControllerSymbol); } #else if (thirdPersonControllerExists) { AddSymbol(s_ThirdPersonControllerSymbol); } #endif // Shootable Weapon will exist if the shooter controller is imported. var shootableWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon") != null; #if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER if (!shootableWeaponExists) { RemoveSymbol(s_ShooterSymbol); } #else if (shootableWeaponExists) { AddSymbol(s_ShooterSymbol); } #endif // First Person Shootable Weapon Properties will exist if the first person shootable controller is imported. var firstPersonShootableWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonShootableWeaponProperties") != null; #if FIRST_PERSON_SHOOTER if (!firstPersonShootableWeaponExists) { RemoveSymbol(s_FirstPersonShooterSymbol); } #else if (firstPersonShootableWeaponExists) { AddSymbol(s_FirstPersonShooterSymbol); } #endif // Melee Weapon will exist if the melee controller is imported. var meleeWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.Items.Actions.MeleeWeapon") != null; #if ULTIMATE_CHARACTER_CONTROLLER_MELEE if (!meleeWeaponExists) { RemoveSymbol(s_MeleeSymbol); } #else if (meleeWeaponExists) { AddSymbol(s_MeleeSymbol); } #endif // First Person Melee Weapon Properties will exist if the first person melee controller is imported. var firstPersonMeleeWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonMeleeWeaponProperties") != null; #if FIRST_PERSON_MELEE if (!firstPersonMeleeWeaponExists) { RemoveSymbol(s_FirstPersonMeleeSymbol); } #else if (firstPersonMeleeWeaponExists) { AddSymbol(s_FirstPersonMeleeSymbol); } #endif // INetworkCharacter will exist if the multiplayer add-on is imported. var multiplayerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.AddOns.Multiplayer.Character.NetworkCharacterLocomotionHandler") != null; #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER if (!multiplayerExists) { RemoveSymbol(s_MultiplayerSymbol); } #else if (multiplayerExists) { AddSymbol(s_MultiplayerSymbol); } #endif // VRViewType will exist if the VR add-on is imported. var VRExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.AddOns.VR.Editor.VRAddOnInspector") != null; #if ULTIMATE_CHARACTER_CONTROLLER_VR if (!VRExists) { RemoveSymbol(s_VRSymbol); } #else if (VRExists) { AddSymbol(s_VRSymbol); } #endif #if ULTIMATE_CHARACTER_CONTROLLER_CINEMACHINE // TODO: CinemachineBrain will exist if Cinemachine is imported. As of 2.1.2 Cinemachine is a separate integration so this can be removed later. var cinemachineExists = UnityEngineUtility.GetType("Cinemachine.CinemachineBrain") != null; if (!cinemachineExists) { RemoveSymbol(s_CinemachineSymbol); } #endif }
/// <summary> /// If the specified classes exist then the compiler symbol should be defined, otherwise the symbol should be removed. /// </summary> static DefineCompilerSymbols() { // The First Person Controller Combat MovementType will exist when the First Person Controller asset is imported. var firstPersonControllerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Character.MovementTypes.Combat") != null; #if FIRST_PERSON_CONTROLLER if (!firstPersonControllerExists) { RemoveSymbol(s_FirstPersonControllerSymbol); } #else if (firstPersonControllerExists) { AddSymbol(s_FirstPersonControllerSymbol); } #endif // The Third Person Controller Combat MovementType will exist when the Third Person Controller asset is imported. var thirdPersonControllerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Combat") != null; #if THIRD_PERSON_CONTROLLER if (!thirdPersonControllerExists) { RemoveSymbol(s_ThirdPersonControllerSymbol); } #else if (thirdPersonControllerExists) { AddSymbol(s_ThirdPersonControllerSymbol); } #endif // Shootable Weapon will exist if the shooter controller is imported. var shootableWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon") != null; #if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER if (!shootableWeaponExists) { RemoveSymbol(s_ShooterSymbol); } #else if (shootableWeaponExists) { AddSymbol(s_ShooterSymbol); } #endif // First Person Shootable Weapon Properties will exist if the first person shootable controller is imported. var firstPersonShootableWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonShootableWeaponProperties") != null; #if FIRST_PERSON_SHOOTER if (!firstPersonShootableWeaponExists) { RemoveSymbol(s_FirstPersonShooterSymbol); } #else if (firstPersonShootableWeaponExists) { AddSymbol(s_FirstPersonShooterSymbol); } #endif // Melee Weapon will exist if the melee controller is imported. var meleeWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.Items.Actions.MeleeWeapon") != null; #if ULTIMATE_CHARACTER_CONTROLLER_MELEE if (!meleeWeaponExists) { RemoveSymbol(s_MeleeSymbol); } #else if (meleeWeaponExists) { AddSymbol(s_MeleeSymbol); } #endif // First Person Melee Weapon Properties will exist if the first person melee controller is imported. var firstPersonMeleeWeaponExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.FirstPersonController.Items.FirstPersonMeleeWeaponProperties") != null; #if FIRST_PERSON_MELEE if (!firstPersonMeleeWeaponExists) { RemoveSymbol(s_FirstPersonMeleeSymbol); } #else if (firstPersonMeleeWeaponExists) { AddSymbol(s_FirstPersonMeleeSymbol); } #endif // INetworkCharacter will exist if the multiplayer add-on is imported. var multiplayerExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.AddOns.Multiplayer.Character.NetworkCharacterLocomotionHandler") != null; #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER if (!multiplayerExists) { RemoveSymbol(s_MultiplayerSymbol); } #else if (multiplayerExists) { AddSymbol(s_MultiplayerSymbol); } #endif // VRViewType will exist if the VR add-on is imported. var vrExists = UnityEngineUtility.GetType("Opsive.UltimateCharacterController.AddOns.VR.Editor.VRAddOnInspector") != null; #if ULTIMATE_CHARACTER_CONTROLLER_VR if (!vrExists) { RemoveSymbol(s_VRSymbol); } #else if (vrExists) { AddSymbol(s_VRSymbol); } #endif // The LWRP/URP data will exists when the LWRP or URP is imported. This assembly definition must be added to the Opsive.UltimateCaracterController.Editor assembly definition. #if UNITY_2019_2 var lwrpExists = UnityEngineUtility.GetType("UnityEngine.Rendering.LWRP.ForwardRendererData") != null; #if ULTIMATE_CHARACTER_CONTROLLER_LWRP if (!lwrpExists) { RemoveSymbol(s_LWRPSymbol); } #else if (lwrpExists) { AddSymbol(s_LWRPSymbol); } #endif #elif UNITY_2019_3_OR_NEWER var universalrpExists = UnityEngineUtility.GetType("UnityEngine.Rendering.Universal.ForwardRendererData") != null; #if ULTIMATE_CHARACTER_CONTROLLER_UNIVERSALRP if (!universalrpExists) { RemoveSymbol(s_UniversalRPSymbol); } #else if (universalrpExists) { AddSymbol(s_UniversalRPSymbol); } #endif #endif }
/// <summary> /// Updates the default first/third view type based on the view types availabe on the camera controller. /// </summary> private void UpdateDefaultViewTypes() { // The view type may not exist anymore. if (UnityEngineUtility.GetType(m_CameraController.FirstPersonViewTypeFullName) == null) { m_CameraController.FirstPersonViewTypeFullName = string.Empty; InspectorUtility.SetDirty(target); } if (UnityEngineUtility.GetType(m_CameraController.ThirdPersonViewTypeFullName) == null) { m_CameraController.ThirdPersonViewTypeFullName = string.Empty; InspectorUtility.SetDirty(target); } var hasSelectedViewType = false; var firstPersonViewTypes = new List <Type>(); var thirdPersonViewTypes = new List <Type>(); var firstPersonViewTypeNames = new List <string>(); var thirdPersonViewTypeNames = new List <string>(); var viewTypes = m_CameraController.ViewTypes; if (viewTypes != null) { for (int i = 0; i < viewTypes.Length; ++i) { if (viewTypes[i] == null) { continue; } // Transition view types are not limited to one perspective. if (viewTypes[i] is UltimateCharacterController.Camera.ViewTypes.Transition) { continue; } if (viewTypes[i].FirstPersonPerspective) { // Use the view type if the type is currently empty. if (string.IsNullOrEmpty(m_CameraController.FirstPersonViewTypeFullName)) { m_CameraController.FirstPersonViewTypeFullName = viewTypes[i].GetType().FullName; } firstPersonViewTypes.Add(viewTypes[i].GetType()); firstPersonViewTypeNames.Add(InspectorUtility.DisplayTypeName(viewTypes[i].GetType(), false)); } else // Third Person. // Use the view type if the type is currently empty. { if (string.IsNullOrEmpty(m_CameraController.ThirdPersonViewTypeFullName)) { m_CameraController.ThirdPersonViewTypeFullName = viewTypes[i].GetType().FullName; } thirdPersonViewTypes.Add(viewTypes[i].GetType()); thirdPersonViewTypeNames.Add(InspectorUtility.DisplayTypeName(viewTypes[i].GetType(), false)); } if (m_CameraController.ViewTypeFullName == viewTypes[i].GetType().FullName) { hasSelectedViewType = true; } } } m_FirstPersonViewTypes = firstPersonViewTypes.ToArray(); m_ThirdPersonViewTypes = thirdPersonViewTypes.ToArray(); m_FirstPersonViewTypeNames = firstPersonViewTypeNames.ToArray(); m_ThirdPersonViewTypeNames = thirdPersonViewTypeNames.ToArray(); // If the selected ViewType no longer exists in the list then select the next view type. if (!hasSelectedViewType) { m_CameraController.ViewTypeFullName = string.Empty; if (viewTypes != null && viewTypes.Length > 0) { for (int i = 0; i < viewTypes.Length; ++i) { // Transition ViewTypes cannot be selected. if (viewTypes[i] is UltimateCharacterController.Camera.ViewTypes.Transition) { continue; } m_CameraController.ViewTypeFullName = viewTypes[i].GetType().FullName; break; } } } }
/// <summary> /// Draws all of the added states. /// </summary> public static void OnStateListDraw(object obj, UltimateCharacterController.StateSystem.State[] states, SerializedProperty statesProperty, Rect rect, int index) { if (rect.width < 0) { return; } // States cannot be edited at runtime, nor can the Default state ever be edited. GUI.enabled = !Application.isPlaying && index != states.Length - 1; rect.x -= EditorGUI.indentLevel * InspectorUtility.IndentWidth; // Ensure the default state doesn't get changed. var state = states[index]; var stateProperty = (statesProperty != null ? statesProperty.GetArrayElementAtIndex(index) : null); if (!Application.isPlaying && index == states.Length - 1) { if (statesProperty != null && stateProperty == null) { statesProperty.InsertArrayElementAtIndex(index); stateProperty = statesProperty.GetArrayElementAtIndex(index); stateProperty.FindPropertyRelative("m_Name").stringValue = "Default"; stateProperty.FindPropertyRelative("m_Default").boolValue = true; } else if (statesProperty == null && state == null) { states[index] = state = new UltimateCharacterController.StateSystem.State("Default", true); GUI.changed = true; } if (state.Name != "Default") { if (stateProperty != null) { stateProperty.FindPropertyRelative("m_Name").stringValue = "Default"; } else { state.Name = "Default"; } GUI.changed = true; } if (!state.Default) { if (stateProperty != null) { stateProperty.FindPropertyRelative("m_Default").boolValue = true; } else { state.Default = true; } GUI.changed = true; } } // Setup the field sizings. var fieldWidth = rect.width / 5; var blockedByWidth = Mathf.Max(c_MinBlockedByWidth, Mathf.Min(c_MaxBlockedByWidth, fieldWidth)) + EditorGUI.indentLevel * InspectorUtility.IndentWidth; fieldWidth = rect.width / 7; var persistWidth = Mathf.Max(c_MinPersistWidth, Mathf.Min(c_MaxPersistWidth, fieldWidth)); var activateWidth = Mathf.Max(c_MinActivateWidth, Mathf.Min(c_MaxActivateWidth, fieldWidth)); fieldWidth = (rect.width - blockedByWidth - persistWidth - activateWidth) / 2 - (c_WidthBuffer * 3); var presetWidth = Mathf.Min(c_MaxPresetWidth, fieldWidth) + EditorGUI.indentLevel * 30; var nameWidth = Mathf.Max(0, rect.width - presetWidth - blockedByWidth - persistWidth - activateWidth - (c_WidthBuffer * 6)) + EditorGUI.indentLevel * 45; var startRectX = rect.x; // The state name has to be unique. var active = state.Active && !state.IsBlocked(); var desiredName = EditorGUI.TextField(new Rect(startRectX, rect.y + 1, nameWidth, EditorGUIUtility.singleLineHeight), state.Name + (active ? " (Active)" : string.Empty), (active ? InspectorStyles.BoldTextField : EditorStyles.textField)); if (!Application.isPlaying && desiredName != state.Name && IsUniqueName(states, desiredName)) { // The name of the state that is blocking the current state should be updated. for (int i = 0; i < states.Length; ++i) { if (states[i] == state) { continue; } if (states[i].BlockList != null) { for (int j = 0; j < states[i].BlockList.Length; ++j) { if (states[i].BlockList[j] == state.Name) { if (stateProperty != null) { stateProperty.FindPropertyRelative("m_BlockList").GetArrayElementAtIndex(j).stringValue = desiredName; } else { states[i].BlockList[j] = desiredName; } } } } } if (stateProperty != null) { stateProperty.FindPropertyRelative("m_Name").stringValue = desiredName; } else { state.Name = desiredName; } } startRectX += nameWidth + c_WidthBuffer - EditorGUI.indentLevel * InspectorUtility.IndentWidth; // The preset cannot be null. var desiredPreset = EditorGUI.ObjectField(new Rect(startRectX, rect.y + 1, presetWidth, EditorGUIUtility.singleLineHeight), string.Empty, state.Preset, typeof(PersistablePreset), false) as PersistablePreset; if (desiredPreset != null) { if (UnityEngineUtility.GetType(desiredPreset.Data.ObjectType).IsAssignableFrom(obj.GetType())) { if (stateProperty != null) { stateProperty.FindPropertyRelative("m_Preset").objectReferenceValue = desiredPreset; } else { state.Preset = desiredPreset; } } else { Debug.LogError("Error: Unable to add preset " + desiredPreset.name + " - the preset doesn't use the same object type."); } } startRectX += presetWidth + c_WidthBuffer - EditorGUI.indentLevel * InspectorUtility.IndentWidth; // Create a popup of the states that can block the current state. There are several conditions which would prevent a state from being able to block // another state so this popup has to first be filtered. var stateName = state.Name; var blockList = state.BlockList; var allStates = new List <string>(); var selected = 0; for (int i = 0; i < states.Length; ++i) { var currentState = states[i]; if (currentState == null) { states[i] = currentState = new UltimateCharacterController.StateSystem.State(); } // The current state cannot block the default state. if (currentState.Default) { continue; } string name; // The current state cannot block itself. if ((name = currentState.Name) == stateName) { continue; } // The selected state cannot block the current state if the current state blocks the selected state. var currentStateBlockList = currentState.BlockList; var canAdd = true; if (currentStateBlockList != null) { for (int j = 0; j < currentStateBlockList.Length; ++j) { if (stateName == currentStateBlockList[j]) { canAdd = false; break; } } } // canAdd will be false if the current state is blocking the selected state. if (!canAdd) { continue; } // The current state can block the selected state. Add the name to the popup and determine if the state is selected. A mask is used // to allow multiple selected states. allStates.Add(name); if (blockList != null) { for (int j = 0; j < blockList.Length; ++j) { if (allStates[allStates.Count - 1] == blockList[j]) { selected |= 1 << (allStates.Count - 1); break; } } } } // At least one value needs to exist. if (allStates.Count == 0) { allStates.Add("Nothing"); } // Draw the actual popup. var blockMask = EditorGUI.MaskField(new Rect(startRectX, rect.y + 1, blockedByWidth, EditorGUIUtility.singleLineHeight), string.Empty, selected, allStates.ToArray()); if (blockMask != selected) { var stateNames = new List <string>(); var blockListProperty = (stateProperty != null ? stateProperty.FindPropertyRelative("m_BlockList") : null); if (blockListProperty != null) { blockListProperty.ClearArray(); } for (int i = 0; i < allStates.Count; ++i) { // If the state index is within the block mask then that state should be added to the list. A blockMask of -1 indicates Everything. if (((1 << i) & blockMask) != 0 || blockMask == -1) { if (blockListProperty != null) { blockListProperty.InsertArrayElementAtIndex(blockListProperty.arraySize); blockListProperty.GetArrayElementAtIndex(blockListProperty.arraySize - 1).stringValue = allStates[i]; } else { stateNames.Add(allStates[i]); } } } if (blockListProperty == null) { state.BlockList = stateNames.ToArray(); } } startRectX += blockedByWidth + c_WidthBuffer; GUI.enabled = index < states.Length - 1; if (GUI.Button(new Rect(startRectX + persistWidth / 2, rect.y + 1, 18, EditorGUIUtility.singleLineHeight), InspectorStyles.PersistIcon, InspectorStyles.NoPaddingButtonStyle)) { // Populate the position map so ObjectInspector.DrawProperties to know which properties already exist. var valuePositionMap = new Dictionary <int, int>(desiredPreset.Data.ValueHashes.Length); for (int i = 0; i < desiredPreset.Data.ValueHashes.Length; ++i) { valuePositionMap.Add(desiredPreset.Data.ValueHashes[i], i); } // Loop through all of the properties on the object. var properties = Serialization.GetSerializedProperties(obj.GetType(), MemberVisibility.Public); // Remove and add the properties that are being serialized. for (int i = 0; i < properties.Length; ++i) { var hash = Serialization.StringHash(properties[i].PropertyType.FullName) + Serialization.StringHash(properties[i].Name); // The property is currently being serialized. if (valuePositionMap.ContainsKey(hash)) { // Add the new property to the serialization. object value = null; var property = properties[i]; if (!typeof(Object).IsAssignableFrom(property.PropertyType)) { var unityObjectIndexes = new List <int>(); Serialization.GetUnityObjectIndexes(ref unityObjectIndexes, property.PropertyType, property.Name, 0, valuePositionMap, desiredPreset.Data.ValueHashes, desiredPreset.Data.ValuePositions, desiredPreset.Data.Values, false, MemberVisibility.Public); Serialization.RemoveProperty(i, unityObjectIndexes, desiredPreset.Data, MemberVisibility.Public); // Get the current value of the active object. var getMethod = property.GetGetMethod(); if (getMethod != null) { value = getMethod.Invoke(obj, null); } // Add the property back with the updated value. Serialization.AddProperty(property, value, unityObjectIndexes, desiredPreset.Data, MemberVisibility.Public); } } } } startRectX += persistWidth + c_WidthBuffer; GUI.enabled = Application.isPlaying && index < states.Length - 1; if (GUI.Button(new Rect(startRectX + activateWidth / 2, rect.y + 1, 18, EditorGUIUtility.singleLineHeight), InspectorStyles.ActivateIcon, InspectorStyles.NoPaddingButtonStyle)) { StateManager.ActivateState(states[index], !states[index].Active, states); } GUI.enabled = true; }
/// <summary> /// Sets up the camera if it hasn't already been setup. /// </summary> private void SetupCamera() { // Setup the camera. GameObject cameraGameObject; var addedCameraController = false; var camera = UnityEngine.Camera.main; if (camera == null) { // If the main camera can't be found then use the first available camera. var cameras = UnityEngine.Camera.allCameras; if (cameras != null && cameras.Length > 0) { // Prefer cameras that are at the root level. for (int i = 0; i < cameras.Length; ++i) { if (cameras[i].transform.parent == null) { camera = cameras[i]; break; } } // No cameras are at the root level. Set the first available camera. if (camera == null) { camera = cameras[0]; } } // A new camera should be created if there isn't a valid camera. if (camera == null) { cameraGameObject = new GameObject("Camera"); cameraGameObject.tag = "MainCamera"; camera = cameraGameObject.AddComponent <UnityEngine.Camera>(); cameraGameObject.AddComponent <AudioListener>(); } } // The near clip plane should adjusted for viewing close objects. camera.nearClipPlane = 0.01f; // Add the CameraController if it isn't already added. cameraGameObject = camera.gameObject; if (cameraGameObject.GetComponent <CameraController>() == null) { var cameraController = cameraGameObject.AddComponent <CameraController>(); if (m_Perspective == Perspective.Both) { ViewTypeBuilder.AddViewType(cameraController, typeof(UltimateCharacterController.Camera.ViewTypes.Transition)); } if (m_StartFirstPersonPerspective) { if (!string.IsNullOrEmpty(m_ThirdPersonViewType)) { ViewTypeBuilder.AddViewType(cameraController, UnityEngineUtility.GetType(m_ThirdPersonViewType)); } if (!string.IsNullOrEmpty(m_FirstPersonViewType)) { ViewTypeBuilder.AddViewType(cameraController, UnityEngineUtility.GetType(m_FirstPersonViewType)); } } else { if (!string.IsNullOrEmpty(m_FirstPersonViewType)) { ViewTypeBuilder.AddViewType(cameraController, UnityEngineUtility.GetType(m_FirstPersonViewType)); } if (!string.IsNullOrEmpty(m_ThirdPersonViewType)) { ViewTypeBuilder.AddViewType(cameraController, UnityEngineUtility.GetType(m_ThirdPersonViewType)); } } // Detect if a character exists in the scene. Automatically add the character if it does. var characters = GameObject.FindObjectsOfType <UltimateCharacterController.Character.CharacterLocomotion>(); if (characters != null && characters.Length == 1) { cameraController.InitCharacterOnAwake = true; cameraController.Character = characters[0].gameObject; } // Setup the components which help the Camera Controller. Shared.Editor.Utility.InspectorUtility.AddComponent <CameraControllerHandler>(cameraGameObject); #if THIRD_PERSON_CONTROLLER if (m_Perspective != Perspective.First) { Shared.Editor.Utility.InspectorUtility.AddComponent <ThirdPersonController.Camera.ObjectFader>(cameraGameObject); } #endif addedCameraController = true; if (m_StateConfiguration != null) { if (m_ProfileIndex > 0) { m_StateConfiguration.AddStatesToGameObject(m_ProfileName, cameraGameObject); InspectorUtility.SetDirty(cameraGameObject); } } } if (addedCameraController) { Debug.Log("The Camera Controller has been added."); } else { Debug.LogWarning("Warning: No action was performed, the Camera Controller component has already been added."); } }
/// <summary> /// Draws the preset values within the inspector. /// </summary> public override void OnInspectorGUI() { // Show all of the fields. serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var preset = target as PersistablePreset; var fullName = preset.Data.ObjectType; var splitName = fullName.Split('.'); GUILayout.Label(splitName[splitName.Length - 1] + " Preset", EditorStyles.boldLabel); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); // Show the property values within a table. var objType = UnityEngineUtility.GetType(preset.Data.ObjectType); if (objType != null) { // Populate the position map so ObjectInspector.DrawProperties to know which properties to draw. var valuePositionMap = new Dictionary <int, int>(preset.Data.ValueHashes.Length); for (int i = 0; i < preset.Data.ValueHashes.Length; ++i) { valuePositionMap.Add(preset.Data.ValueHashes[i], i); } // Draw all of the serialized properties. Implement the start and end callbacks so the delete button can be drawn next to a foldout in the case of a list, class, or struct. ObjectInspector.DrawProperties(objType, null, 0, valuePositionMap, preset.Data, m_Visiblity, () => { GUILayout.BeginHorizontal(); }, (int index, List <int> unityObjectIndexes) => { InspectorUtility.RecordUndoDirtyObject(preset, "Change Value"); var removed = false; if (GUILayout.Button(InspectorStyles.DeleteIcon, InspectorStyles.NoPaddingButtonStyle, GUILayout.Width(16))) { RemoveElement(index, unityObjectIndexes); removed = true; } serializedObject.ApplyModifiedProperties(); GUILayout.EndHorizontal(); return(removed); }); } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUI.enabled = m_AvailableProperies.Count > 0 && !Application.isPlaying; // Only allow the popup if properties can be selected. var selectedPropertyIndex = EditorGUILayout.Popup(0, m_AvailablePropertyNames, GUILayout.MaxWidth(150)); GUI.enabled = true; GUILayout.EndHorizontal(); // If the selected property index isn't 0 then a property should be added. if (selectedPropertyIndex != 0) { var property = m_AvailableProperies[selectedPropertyIndex - 1]; if (property != null) { // Add the new property to the serialization. object value = null; if (!typeof(UnityEngine.Object).IsAssignableFrom(property.PropertyType)) { // Lists require special handling. if (typeof(IList).IsAssignableFrom(property.PropertyType)) { if (property.PropertyType.IsArray) { var elementType = property.PropertyType.GetElementType(); value = Array.CreateInstance(elementType, 0); } else { var baseType = property.PropertyType; while (!baseType.IsGenericType) { baseType = baseType.BaseType; } var elementType = baseType.GetGenericArguments()[0]; if (property.PropertyType.IsGenericType) { value = Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)) as IList; } else { value = Activator.CreateInstance(property.PropertyType) as IList; } } } else { var getMethod = property.GetGetMethod(); if (getMethod != null) { // A new GameObject must be created so the component can be added to it. MonoBehaviours cannot use Activator.CreateInstance. GameObject gameObject = null; object obj; var objectType = UnityEngineUtility.GetType(preset.Data.ObjectType); if (typeof(MonoBehaviour).IsAssignableFrom(objectType)) { gameObject = new GameObject(); obj = gameObject.AddComponent(objectType); } else { obj = Activator.CreateInstance(objectType); } value = getMethod.Invoke(obj, null); if (value == null) { if (getMethod.ReturnType == typeof(string)) { value = string.Empty; } else { value = Activator.CreateInstance(getMethod.ReturnType); } } if (gameObject != null) { DestroyImmediate(gameObject); } } } } Serialization.AddProperty(property, value, null, preset.Data, m_Visiblity); InitializeAvailablePropertyArray(); } } if (EditorGUI.EndChangeCheck()) { InspectorUtility.RecordUndoDirtyObject(preset, "Change Value"); serializedObject.ApplyModifiedProperties(); } }