/// <summary> /// The character has entered from the zone. /// </summary> /// <param name="characterLocomotion">The character that entered the zone.</param> protected override void CharacterEnter(UltimateCharacterLocomotion characterLocomotion) { // The other collider is the main character. m_Character = characterLocomotion.gameObject; m_CameraController = UnityEngineUtility.FindCamera(m_Character).GetComponent<CameraController>(); // The character must have the primary item in order for it to be equipped. var inventory = m_Character.GetCachedComponent<InventoryBase>(); for (int i = 0; i < m_ItemTypes.Length; ++i) { if (m_ItemTypes[i] == null) { continue; } inventory.PickupItemType(m_ItemTypes[i], 1, 0, false, false); } // Ensure the primary weapon is equipped. var equipUnequipAbilities = characterLocomotion.GetAbilities<EquipUnequip>(); for (int i = 0; i < equipUnequipAbilities.Length; ++i) { if (equipUnequipAbilities[i].ItemSetCategoryIndex == m_CategoryIndex) { equipUnequipAbilities[i].StartEquipUnequip(m_ItemSetIndex, true); break; } } // Setup the character for the zone. StateManager.SetState(m_Character, "FirstPersonSpringZone", true); EventHandler.ExecuteEvent(m_Character, "OnShowUI", false); // First person perspective is required... m_CameraController.SetPerspective(true); // With the combat movement type. m_MovementTypeSwitcher.UpdateMovementType(true, (int)MovementTypesZone.MovementType.FirstPersonCombat); }
/// <summary> /// Sets the starting perspective on the character. /// </summary> /// <param name="firstPersonPerspective">Should the character start in a first person perspective?</param> /// <param name="teleport">Should the character be teleported to the demo zone?</param> protected void SelectStartingPerspective(bool firstPersonPerspective, bool teleport) { m_CharacterLocomotion.SetActive(true, true); // Set the starting position. m_LastZoneIndex = -1; ActiveDemoZone(m_DemoZones[0], teleport); // Set the perspective on the camera. var camera = UnityEngineUtility.FindCamera(null); var cameraController = camera.GetComponent <Camera.CameraController>(); // Ensure the camera starts with the correct view type. cameraController.FirstPersonViewTypeFullName = GetViewTypeFullName(true); cameraController.ThirdPersonViewTypeFullName = GetViewTypeFullName(false); cameraController.SetPerspective(firstPersonPerspective, true); cameraController.Character = m_Character; // The cursor should be hidden to start the demo. Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; enabled = false; // The character and camera are ready to go - disable the perspective selection panel. if (m_PerspectiveSelection != null) { m_PerspectiveSelection.SetActive(false); } }
/// <summary> /// Initialize the default values. /// </summary> protected override void Awake() { base.Awake(); var camera = UnityEngineUtility.FindCamera(m_Character); if (camera != null) { m_CameraGameObject = camera.gameObject; if (m_Character == null) { m_Character = m_CameraGameObject.GetCachedComponent <Camera.CameraController>().Character; } EventHandler.RegisterEvent <GameObject>(m_CameraGameObject, "OnCameraAttachCharacter", OnAttachCharacter); } // Start disabled - attaching the character will enabe the component. enabled = false; if (m_Character != null) { var character = m_Character; m_Character = null; OnAttachCharacter(character); } }
/// <summary> /// Attaches the monitor to the specified character. /// </summary> /// <param name="character">The character to attach the monitor to.</param> protected override void OnAttachCharacter(GameObject character) { if (m_Character != null) { EventHandler.UnregisterEvent <float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage); EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn); m_CameraTransform = null; } base.OnAttachCharacter(character); if (m_Character == null) { return; } // A camera must exist. var camera = UnityEngineUtility.FindCamera(m_Character); if (camera != null) { m_CameraTransform = camera.transform; } if (m_CameraTransform == null) { Debug.LogError("Error: The Damage Indicator Monitor must have a camera attached to the character."); return; } m_CharacterTransform = m_Character.transform; m_CharacterLocomotion = m_Character.GetCachedComponent <UltimateCharacterLocomotion>(); EventHandler.RegisterEvent <float, Vector3, Vector3, GameObject, Collider>(m_Character, "OnHealthDamage", OnDamage); EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn); }
/// <summary> /// An item has been equipped. /// </summary> /// <param name="item">The equipped item.</param> /// <param name="slotID">The slot that the item now occupies.</param> private void OnEquipItem(Items.Item item, int slotID) { if (item.IsActive() && item.DominantItem) { UnityEngineUtility.ClearUpdatedObjects(); item.Move(0, 0); } }
/// <summary> /// Reset the initialized variable when the scene is no longer loaded. /// </summary> /// <param name="scene">The scene that was unloaded.</param> private void SceneUnloaded(Scene scene) { s_Initialized = false; s_Instance = null; SceneManager.sceneUnloaded -= SceneUnloaded; UnityEngineUtility.ClearCache(); }
/// <summary> /// Attaches the monitor to the specified character. /// </summary> /// <param name="character">The character to attach the monitor to.</param> protected override void OnAttachCharacter(GameObject character) { if (m_Character != null) { EventHandler.UnregisterEvent <Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem); EventHandler.UnregisterEvent <Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem); EventHandler.UnregisterEvent <Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem); EventHandler.UnregisterEvent <Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem); EventHandler.UnregisterEvent <bool, bool>(m_Character, "OnAddCrosshairsSpread", OnAddCrosshairsSpread); EventHandler.UnregisterEvent <bool, bool>(m_Character, "OnAimAbilityStart", OnAim); EventHandler.UnregisterEvent <Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath); EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn); ResetMonitor(); } base.OnAttachCharacter(character); if (m_Character == null) { return; } m_Camera = UnityEngineUtility.FindCamera(m_Character); m_CameraController = m_Camera.gameObject.GetCachedComponent <CameraController>(); m_CameraController.SetCrosshairs(transform); m_AimAssist = m_Camera.GetComponent <AimAssist>(); m_CharacterTransform = m_Character.transform; m_CharacterLayerManager = m_Character.GetCachedComponent <CharacterLayerManager>(); m_CharacterLocomotion = m_Character.GetCachedComponent <UltimateCharacterLocomotion>(); m_EnableImage = false; gameObject.SetActive(CanShowUI()); EventHandler.RegisterEvent <Item, int>(m_Character, "OnAbilityWillEquipItem", OnEquipItem); EventHandler.RegisterEvent <Item, bool>(m_Character, "OnItemUpdateDominantItem", OnUpdateDominantItem); EventHandler.RegisterEvent <Item, int>(m_Character, "OnAbilityUnequipItemComplete", OnUnequipItem); EventHandler.RegisterEvent <Item, int>(m_Character, "OnInventoryRemoveItem", OnUnequipItem); EventHandler.RegisterEvent <bool, bool>(m_Character, "OnAddCrosshairsSpread", OnAddCrosshairsSpread); EventHandler.RegisterEvent <bool, bool>(m_Character, "OnAimAbilityStart", OnAim); EventHandler.RegisterEvent <Vector3, Vector3, GameObject>(m_Character, "OnDeath", OnDeath); EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn); // An item may already be equipped. var inventory = m_Character.GetCachedComponent <Inventory.InventoryBase>(); if (inventory != null) { for (int i = 0; i < inventory.SlotCount; ++i) { var item = inventory.GetActiveItem(i); if (item != null) { OnEquipItem(item, i); } } } }
/// <summary> /// An item has been equipped. /// </summary> /// <param name="item">The equipped item.</param> /// <param name="slotID">The slot that the item now occupies.</param> private void OnEquipItem(Item item, int slotID) { if (!item.DominantItem || item.UIMonitorID != m_ID) { return; } m_EquippedItem = item; m_ItemIcon.sprite = item.Icon; UnityEngineUtility.SizeSprite(m_ItemIcon.sprite, m_ItemRectTransform); m_GameObject.SetActive(m_ShowUI && m_ItemIcon.sprite != null); // Multiple item actions can be attached to the same item. ItemAction itemAction = null; if (m_ItemActionID < item.ItemActions.Length) { itemAction = item.ItemActions[m_ItemActionID]; } if (itemAction is IUsableItem) { var usableItem = itemAction as IUsableItem; if ((m_ConsumableItemIdentifier = usableItem.GetConsumableItemIdentifier()) != null) { var consumableItemIdentifierAmount = usableItem.GetConsumableItemIdentifierAmount(); // If the count is -1 then only the loaded should be shown. This is useful in cases like the grenade where there is only one count. if (consumableItemIdentifierAmount != -1) { m_LoadedCount.text = usableItem.GetConsumableItemIdentifierAmount().ToString(); m_UnloadedCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString(); m_LoadedCount.enabled = m_UnloadedCount.enabled = true; m_PrimaryCount.enabled = false; } else { m_PrimaryCount.text = m_CharacterInventory.GetItemIdentifierAmount(usableItem.GetConsumableItemIdentifier()).ToString(); m_PrimaryCount.enabled = true; m_LoadedCount.enabled = m_UnloadedCount.enabled = false; } if (m_CountParent != null) { m_CountParent.SetActive(true); } } else { DisableCountText(); } } else { DisableCountText(); } }
/// <summary> /// Initializes the inspector. /// </summary> protected virtual void OnEnable() { // If the inspector type isn't the current type then a custom inspector has been created for the target. if (GetType() != typeof(StateBehaviorInspector)) { return; } // Group the fields into foldouts. m_FoldoutFields.Clear(); m_FoldoutNames.Clear(); // Start the fields out with no foldout. m_FoldoutFields.Add(new List <FieldInfo>()); m_FoldoutNames.Add(string.Empty); // Populate the foldouts. var allFields = new List <FieldInfo>(Serialization.GetSerializedFields(target.GetType(), MemberVisibility.Public)); var foldoutMap = new Dictionary <string, int>(); var foldoutIndex = 0; for (int i = 0; i < allFields.Count; ++i) { // Do not show HideInInspector fields. if (UnityEngineUtility.HasAttribute(allFields[i], typeof(HideInInspector))) { continue; } // Create a new foldout if there is an InspectorFoldout Attribute. var foldoutAttribute = allFields[i].GetCustomAttributes(typeof(InspectorFoldout), false) as InspectorFoldout[]; if (foldoutAttribute.Length > 0) { if (!string.IsNullOrEmpty(foldoutAttribute[0].Title)) { if (!foldoutMap.TryGetValue(foldoutAttribute[0].Title, out foldoutIndex)) { foldoutIndex = foldoutMap.Count + 1; foldoutMap.Add(foldoutAttribute[0].Title, foldoutIndex); m_FoldoutFields.Add(new List <FieldInfo>()); m_FoldoutNames.Add(foldoutAttribute[0].Title); } } else { // Reset the index if the foldout title is blank. foldoutIndex = 0; } } // Add the field to the last foldout. m_FoldoutFields[foldoutIndex].Add(allFields[i]); } }
/// <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> /// Assigns the camera to the UI Monitor. /// </summary> private void AssignCamera() { var camera = UnityEngineUtility.FindCamera(m_Character); if (camera != null) { m_CameraGameObject = camera.gameObject; if (m_Character == null) { m_Character = m_CameraGameObject.GetCachedComponent <UltimateCharacterController.Camera.CameraController>().Character; } EventHandler.RegisterEvent <GameObject>(m_CameraGameObject, "OnCameraAttachCharacter", OnAttachCharacter); } }
/// <summary> /// Draws all of the serialized fields. /// </summary> /// <param name="obj">The object to draw all of the fields of.</param> /// <param name="drawNoFieldsNotice">Should a notice be drawn if no fields can be drawn?</param> /// <param name="hashPrefix">The prefix of the hash from the parent class. This value will prevent collisions with similarly named objects.</param> /// <returns>The updated object value based on the drawn fields.</returns> private static object DrawFields(object obj, bool drawNoFieldsNotice, int hashPrefix) { if (obj == null) { return(null); } // Only the serialized objects need to be drawn. var objType = obj.GetType(); var fieldsDrawn = false; var hash = hashPrefix + Serialization.StringHash(obj.GetType().FullName); var fields = Serialization.GetSerializedFields(objType, MemberVisibility.Public); for (int i = 0; i < fields.Length; ++i) { // Do not draw HideInInspector fields. if (UnityEngineUtility.HasAttribute(fields[i], typeof(HideInInspector))) { continue; } EditorGUI.BeginChangeCheck(); // Fields can have tooltips assocaited with them. Tooltips are visible when hovering over the field label within the inspector. GUIContent guiContent; var tooltip = InspectorUtility.GetTooltipAttribute(fields[i]); if (tooltip != null) { guiContent = new GUIContent(InspectorUtility.SplitCamelCase(fields[i].Name), tooltip.tooltip); } else { guiContent = new GUIContent(InspectorUtility.SplitCamelCase(fields[i].Name)); } var value = fields[i].GetValue(obj); value = DrawObject(guiContent, fields[i].FieldType, value, fields[i].Name, hash, null, null, fields[i], true); // Update the object if the value was changed. if (EditorGUI.EndChangeCheck()) { fields[i].SetValue(obj, value); } fieldsDrawn = true; } // Draw a notice if no fields were drawn. if (drawNoFieldsNotice && !fieldsDrawn) { EditorGUILayout.LabelField("(No Visible Fields)"); } return(obj); }
/// <summary> /// Moves the item in each slot. /// </summary> private void FixedUpdate() { var lookVector = m_PlayerInput.GetLookVector(false); for (int i = 0; i < m_Inventory.SlotCount; ++i) { var item = m_Inventory.GetActiveItem(i); if (item != null && item.IsActive() && item.DominantItem) { item.Move(lookVector.x, lookVector.y); } } // Each object should only be updated once. Clear the frame after execution to allow the objects to be updated again. UnityEngineUtility.ClearUpdatedObjects(); }
/// <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> /// An object has entered the trigger. /// </summary> /// <param name="other">The object that entered the trigger.</param> private void OnTriggerEnter(Collider other) { if (!MathUtility.InLayerMask(other.gameObject.layer, 1 << LayerManager.Character)) { return; } var characterLocomotion = other.GetComponentInParent <UltimateCharacterLocomotion>(); if (characterLocomotion == null) { return; } var cameraController = UnityEngineUtility.FindCamera(characterLocomotion.gameObject).GetComponent <Camera.CameraController>(); cameraController.SetPerspective(m_FirstPersonPerspective); }
/// <summary> /// Initialize the default values. /// </summary> protected virtual void Awake() { m_GameObject = gameObject; if (m_Character == null) { var camera = UnityEngineUtility.FindCamera(null); if (camera != null) { m_CameraGameObject = camera.gameObject; EventHandler.RegisterEvent <GameObject>(m_CameraGameObject, "OnCameraAttachCharacter", OnAttachCharacter); } } else { var character = m_Character; m_Character = null; // Set the character to null so the assignment will occur. OnAttachCharacter(character); } }
/// <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> /// Initialize the default values. /// </summary> protected override void Awake() { base.Awake(); m_GameObject = gameObject; m_RectTransform = GetComponent <RectTransform>(); if (m_CenterCrosshairsImage == null) { m_CenterCrosshairsImage = GetComponent <Image>(); } m_CenterCrosshairsImage.sprite = m_DefaultSprite; m_CenterRectTransform = m_CenterCrosshairsImage.GetComponent <RectTransform>(); if ((m_CenterCrosshairsImage.enabled = (m_DefaultSprite != null)) == true) { UnityEngineUtility.SizeSprite(m_CenterCrosshairsImage.sprite, m_CenterRectTransform); } if (m_LeftCrosshairsImage != null) { m_LeftRectTransform = m_LeftCrosshairsImage.GetComponent <RectTransform>(); } if (m_TopCrosshairsImage != null) { m_TopRectTransform = m_TopCrosshairsImage.GetComponent <RectTransform>(); } if (m_RightCrosshairsImage != null) { m_RightRectTransform = m_RightCrosshairsImage.GetComponent <RectTransform>(); } if (m_BottomCrosshairsImage != null) { m_BottomRectTransform = m_BottomCrosshairsImage.GetComponent <RectTransform>(); } m_RaycastHits = new RaycastHit[m_MaxCollisionCount]; // Setup the crosshairs defaults. ResetMonitor(); }
public override void ApplyData(string s) { if (string.IsNullOrEmpty(s)) { return; } var newData = SaveSystem.Deserialize <Data>(s); if (newData == null) { if (Debug.isDebugBuild) { Debug.LogWarning("UCC Saver on " + name + " received invalid data. Can't apply: " + s, this); } return; } data = newData; var character = GetComponent <UltimateCharacterLocomotion>(); // Restore attributes: if (saveAttributes) { var attributeManager = GetComponent <AttributeManager>(); if (attributeManager == null) { if (Debug.isDebugBuild) { Debug.LogWarning("UCC Saver can't load attributes. " + name + " doesn't have an Attribute Manager.", this); } } else { if (debug) { Debug.Log("UCC Saver on " + name + " restoring attributes", this); } var count = Mathf.Min(attributeManager.Attributes.Length, data.attributes.Count); for (int i = 0; i < count; i++) { attributeManager.Attributes[i].Value = data.attributes[i]; } } } // Restore inventory: if (saveInventory) { var inventory = GetComponent <InventoryBase>(); if (inventory == null) { if (Debug.isDebugBuild) { Debug.LogWarning("UCC Saver can't load inventory. " + name + " doesn't have an Inventory component.", this); } } else { // Clear inventory: var items = inventory.GetAllItems(); for (int i = 0; i < items.Count; i++) { var item = items[i]; if (item != null && item.ItemType != null) { for (int j = 0; j < item.ItemActions.Length; j++) { var usableItem = item.ItemActions[j] as UsableItem; if (usableItem != null) { var consumableItemType = usableItem.GetConsumableItemType(); if (consumableItemType != null) { var count = (int)inventory.GetItemTypeCount(consumableItemType); if (count > 0) { inventory.RemoveItem(consumableItemType, count, false); } } } } inventory.RemoveItem(item.ItemType, item.SlotID, false); } } var itemCollection = UCCUtility.FindItemCollection(character.gameObject); if (itemCollection == null) { Debug.LogError("Error: Unable to find ItemCollection."); return; } // Add saved items: (restore equipped items last so they end up equipped) HashSet <ItemType> alreadyAddedItemTypes = new HashSet <ItemType>(); RestoreItems(false, itemCollection, inventory, alreadyAddedItemTypes); RestoreItems(true, itemCollection, inventory, alreadyAddedItemTypes); } } // Restore position: if (savePosition) { if (CompareTag("Player") && SaveSystem.playerSpawnpoint != null) { if (debug) { Debug.Log("UCC Saver on " + name + " moving character to spawnpoint " + SaveSystem.playerSpawnpoint, this); } character.SetPositionAndRotation(SaveSystem.playerSpawnpoint.transform.position, SaveSystem.playerSpawnpoint.transform.rotation); } else { var currentScene = SceneManager.GetActiveScene().buildIndex; for (int i = 0; i < data.positions.Count; i++) { if (data.positions[i].scene == currentScene) { if (debug) { Debug.Log("UCC Saver on " + name + " (tag=" + tag + ") restoring saved position " + data.positions[i].position, this); } character.SetPositionAndRotation(data.positions[i].position, data.positions[i].rotation); break; } } } } // Restore perspective: if (savePerspective) { var camera = UnityEngineUtility.FindCamera(null); var cameraController = camera.GetComponent <Opsive.UltimateCharacterController.Camera.CameraController>(); if (cameraController != null && cameraController.CanChangePerspectives) { cameraController.SetPerspective(data.firstPerson, true); } } // Hide cursor: (In editor, UnityInput makes cursor visible when paused during scene transition.) var unityInput = GetComponent <UnityInput>(); if (unityInput != null) { unityInput.DisableCursor = true; } }
/// <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; }
public override string RecordData() { if (data == null) { data = new Data(); } // Save position: var currentScene = SceneManager.GetActiveScene().buildIndex; var found = false; for (int i = 0; i < data.positions.Count; i++) { if (data.positions[i].scene == currentScene) { found = true; data.positions[i].position = transform.position; data.positions[i].rotation = transform.rotation; break; } } if (!found) { data.positions.Add(new PositionData(currentScene, transform.position, transform.rotation)); } // Save perspective: if (savePerspective) { var camera = UnityEngineUtility.FindCamera(null); var cameraController = camera.GetComponent <Opsive.UltimateCharacterController.Camera.CameraController>(); if (cameraController != null && cameraController.CanChangePerspectives) { data.firstPerson = (cameraController.ActiveViewType.GetType().FullName == cameraController.FirstPersonViewTypeFullName); } } // Save attributes: if (saveAttributes) { data.attributes.Clear(); var attributeManager = GetComponent <AttributeManager>(); if (attributeManager == null) { if (Debug.isDebugBuild) { Debug.LogWarning("UCC Saver can't save attributes. " + name + " doesn't have an Attribute Manager.", this); } } else { for (int i = 0; i < attributeManager.Attributes.Length; i++) { data.attributes.Add(attributeManager.Attributes[i].Value); } } } // Save inventory: if (saveInventory) { data.items.Clear(); var inventory = GetComponent <InventoryBase>(); if (inventory == null) { if (Debug.isDebugBuild) { Debug.LogWarning("UCC Saver can't save inventory. " + name + " doesn't have an Inventory component.", this); } } else { // Record equipped items: var equipped = new ItemType[inventory.SlotCount]; for (int i = 0; i < inventory.SlotCount; i++) { var equippedItem = inventory.GetItem(i); equipped[i] = (equippedItem != null) ? equippedItem.ItemType : null; } // Save items: var items = inventory.GetAllItems(); for (int i = 0; i < items.Count; i++) { var item = items[i]; if (item == null || item.ItemType == null) { continue; } var itemCount = inventory.GetItemTypeCount(item.ItemType); if (itemCount <= 0) { continue; } var isDuplicateItem = data.items.Find(x => x.itemID == item.ItemType.ID) != null; var itemData = new ItemData(); itemData.itemID = item.ItemType.ID; itemData.slot = item.SlotID; itemData.count = 1; itemData.equipped = item.ItemType == equipped[item.SlotID]; for (int j = 0; j < item.ItemActions.Length; j++) { var usableItem = item.ItemActions[j] as UsableItem; if (usableItem == null) { continue; } var itemActionData = new ItemActionData(); itemData.itemActionData.Add(itemActionData); itemActionData.id = usableItem.ID; itemActionData.count = isDuplicateItem ? 0 : inventory.GetItemTypeCount(usableItem.GetConsumableItemType()); itemActionData.consumableCount = usableItem.GetConsumableItemTypeCount(); } data.items.Add(itemData); } } } if (debug) { Debug.Log(JsonUtility.ToJson(data, true)); // [DEBUG] } var s = SaveSystem.Serialize(data); if (debug) { Debug.Log("UCC Saver on " + name + " saving: " + s, this); } return(s); }
/// <summary> /// Initializes the Demo Manager with the specified character. /// </summary> /// <param name="character">The character that should be initialized/</param> /// <param name="selectStartingPerspective">Should the starting perspective be selected?</param> /// <param name="teleport">Should the character be teleported to the first demo zone?</param> protected void InitializeCharacter(GameObject character, bool selectStartingPerspective, bool teleport) { m_Character = character; if (m_Character == null) { return; } m_CharacterLocomotion = m_Character.GetComponent <UltimateCharacterLocomotion>(); m_CharacterHealth = m_Character.GetComponent <Health>(); m_CharacterRespawner = m_Character.GetComponent <Respawner>(); // Disable the demo components if the character is null. This allows for free roaming within the demo scene. if (m_FreeRoam) { m_FullAccess = true; if (m_PerspectiveSelection != null) { m_PerspectiveSelection.SetActive(false); } var uiZones = GetComponentsInChildren <UIZone>(); for (int i = 0; i < uiZones.Length; ++i) { uiZones[i].enabled = false; } // All of the doors should be opened with free roam. for (int i = 0; i < m_Doors.Count; ++i) { m_Doors[i].CloseOnTriggerExit = false; m_Doors[i].OpenClose(true, true, false); } // The enable objects should be enabled. for (int i = 0; i < m_DemoZones.Length; ++i) { for (int j = 0; j < m_DemoZones[i].EnableObjects.Length; ++j) { m_DemoZones[i].EnableObjects[j].enabled = true; } } // The character needs to be assigned to the camera. var camera = UnityEngineUtility.FindCamera(null); var cameraController = camera.GetComponent <Camera.CameraController>(); cameraController.SetPerspective(m_CharacterLocomotion.FirstPersonPerspective, true); cameraController.Character = m_Character; // The character doesn't start out with any items. if (m_FreeRoamItemTypeCounts != null && m_FreeRoamPickupItemTypes) { var inventory = m_Character.GetComponent <InventoryBase>(); if (inventory != null) { for (int i = 0; i < m_FreeRoamItemTypeCounts.Length; ++i) { if (m_FreeRoamItemTypeCounts[i].ItemType == null) { continue; } inventory.PickupItemType(m_FreeRoamItemTypeCounts[i].ItemType, m_FreeRoamItemTypeCounts[i].Count, -1, true, false); } } } if (m_Character.activeInHierarchy) { EventHandler.ExecuteEvent(m_Character, "OnCharacterSnapAnimator"); } enabled = false; return; } // The cursor needs to be visible. Cursor.lockState = CursorLockMode.None; Cursor.visible = true; if (!selectStartingPerspective) { return; } #if FIRST_PERSON_CONTROLLER && THIRD_PERSON_CONTROLLER // Show the perspective selection menu. if (m_PerspectiveSelection != null) { // The character should be disabled until the perspective is set. m_CharacterLocomotion.SetActive(false, true); m_PerspectiveSelection.SetActive(true); } else { SelectStartingPerspective(m_DefaultFirstPersonStart, teleport); } #elif FIRST_PERSON_CONTROLLER SelectStartingPerspective(true, teleport); #else SelectStartingPerspective(false, teleport); #endif }
/// <summary> /// An item has been equipped. /// </summary> /// <param name="itemType">The equipped item.</param> /// <param name="slotID">The slot that the item now occupies.</param> private void OnEquipItem(Item item, int slotID) { if (!item.DominantItem) { return; } m_CurrentCrosshairsSpread = m_TargetCrosshairsSpread = 0; m_EquippedItem = item; m_CenterCrosshairsImage.sprite = m_EquippedItem.CenterCrosshairs != null ? m_EquippedItem.CenterCrosshairs : m_DefaultSprite; if (m_CenterCrosshairsImage.sprite != null) { m_CenterCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim; UnityEngineUtility.SizeSprite(m_CenterCrosshairsImage.sprite, m_CenterRectTransform); } else { m_CenterCrosshairsImage.enabled = false; } if (m_LeftCrosshairsImage != null) { m_LeftCrosshairsImage.sprite = m_EquippedItem.LeftCrosshairs; if (m_LeftCrosshairsImage.sprite != null) { m_LeftCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim; PositionSprite(m_LeftRectTransform, -m_EquippedItem.QuadrantOffset, 0); UnityEngineUtility.SizeSprite(m_LeftCrosshairsImage.sprite, m_LeftRectTransform); } else { m_LeftCrosshairsImage.enabled = false; } } if (m_TopCrosshairsImage != null) { m_TopCrosshairsImage.sprite = m_EquippedItem.TopCrosshairs; if (m_TopCrosshairsImage.sprite != null) { m_TopCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim; PositionSprite(m_TopRectTransform, 0, m_EquippedItem.QuadrantOffset); UnityEngineUtility.SizeSprite(m_TopCrosshairsImage.sprite, m_TopRectTransform); } else { m_TopCrosshairsImage.enabled = false; } } if (m_RightCrosshairsImage != null) { m_RightCrosshairsImage.sprite = m_EquippedItem.RightCrosshairs; if (m_RightCrosshairsImage.sprite != null) { m_RightCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim; PositionSprite(m_RightRectTransform, m_EquippedItem.QuadrantOffset, 0); UnityEngineUtility.SizeSprite(m_RightCrosshairsImage.sprite, m_RightRectTransform); } else { m_RightCrosshairsImage.enabled = false; } } if (m_BottomCrosshairsImage != null) { m_BottomCrosshairsImage.sprite = m_EquippedItem.BottomCrosshairs; if (m_BottomCrosshairsImage.sprite != null) { m_BottomCrosshairsImage.enabled = !m_Aiming || m_EquippedItem.ShowCrosshairsOnAim; PositionSprite(m_BottomRectTransform, 0, -m_EquippedItem.QuadrantOffset); UnityEngineUtility.SizeSprite(m_BottomCrosshairsImage.sprite, m_BottomRectTransform); } else { m_BottomCrosshairsImage.enabled = false; } } m_EquippedItemCount++; }
/// <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> /// 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> /// 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> /// Initialize the camera to follow the character. /// </summary> /// <param name="character">The character to initialize. Can be null.</param> private void InitializeCharacter(GameObject character) { #if UNITY_EDITOR if (!Application.isPlaying) { return; } #endif if (character == m_Character) { return; } // If the character is not null then the previous character should be notified that there is no longer a camera attached. if (m_Character != null) { EventHandler.ExecuteEvent <CameraController>(m_Character, "OnCharacterAttachCamera", null); EventHandler.ExecuteEvent <ILookSource>(m_Character, "OnCharacterAttachLookSource", null); EventHandler.UnregisterEvent <Vector3>(m_Character, "OnCameraPositionalForce", AddPositionalForce); EventHandler.UnregisterEvent <Vector3>(m_Character, "OnCameraRotationalForce", AddRotationalForce); EventHandler.UnregisterEvent <Vector3, Vector3, float>(m_Character, "OnAddSecondaryCameraForce", OnAddSecondaryForce); EventHandler.UnregisterEvent <bool>(m_Character, "OnCharacterImmediateTransformChange", OnImmediateTransformChange); EventHandler.UnregisterEvent(m_Character, "OnAnimatorSnapped", PositionImmediately); EventHandler.UnregisterEvent <Ability, bool>(m_Character, "OnCharacterAbilityActive", OnAbilityActive); EventHandler.UnregisterEvent <ItemAbility, bool>(m_Character, "OnCharacterItemAbilityActive", OnItemAbilityActive); EventHandler.UnregisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives); StateManager.LinkGameObjects(m_Character, m_GameObject, false); } // The character should no longer be using the zoom state if the camera is no longer attached. if (m_Zoom && m_Character != null) { SetZoom(false); } // Set the character values. if (enabled = (character != null)) { m_Character = character; m_CharacterTransform = m_Character.transform; m_CharacterLocomotion = character.GetCachedComponent <UltimateCharacterLocomotion>(); m_CharacterInventory = character.GetCachedComponent <InventoryBase>(); InitializeAnchor(); } else { m_Character = null; m_CharacterTransform = null; m_CharacterLocomotion = null; m_CharacterInventory = null; } // Notify the view types of the character that is being attached. for (int i = 0; i < m_ViewTypes.Length; ++i) { m_ViewTypes[i].AttachCharacter(m_Character); } if (m_Character != null) { m_ViewType.ChangeViewType(true, 0, 0, m_CharacterTransform.rotation); if (m_ViewType.RotatePriority) { KinematicObjectManager.SetCameraRotation(m_KinematicObjectIndex, m_ViewType.Rotate(0, 0, true)); KinematicObjectManager.SetCameraPosition(m_KinematicObjectIndex, m_ViewType.Move(true)); } else { KinematicObjectManager.SetCameraPosition(m_KinematicObjectIndex, m_ViewType.Move(true)); KinematicObjectManager.SetCameraRotation(m_KinematicObjectIndex, m_ViewType.Rotate(0, 0, true)); } m_ViewType.UpdateFieldOfView(true); // Registered for any interested events. EventHandler.RegisterEvent <Vector3>(m_Character, "OnCameraPositionalForce", AddPositionalForce); EventHandler.RegisterEvent <Vector3>(m_Character, "OnCameraRotationalForce", AddRotationalForce); EventHandler.RegisterEvent <Vector3, Vector3, float>(m_Character, "OnAddSecondaryCameraForce", OnAddSecondaryForce); EventHandler.RegisterEvent <bool>(m_Character, "OnCharacterImmediateTransformChange", OnImmediateTransformChange); EventHandler.RegisterEvent(m_Character, "OnAnimatorSnapped", PositionImmediately); EventHandler.RegisterEvent <Ability, bool>(m_Character, "OnCharacterAbilityActive", OnAbilityActive); EventHandler.RegisterEvent <ItemAbility, bool>(m_Character, "OnCharacterItemAbilityActive", OnItemAbilityActive); EventHandler.RegisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives); // Notify the camera components of the attached character. EventHandler.ExecuteEvent <GameObject>(m_GameObject, "OnCameraAttachCharacter", character); // Notify the character of the attached camera. EventHandler.ExecuteEvent <CameraController>(m_Character, "OnCharacterAttachCamera", this); EventHandler.ExecuteEvent <ILookSource>(m_Character, "OnCharacterAttachLookSource", this); EventHandler.ExecuteEvent <bool>(m_Character, "OnCameraWillChangePerspectives", m_ViewType.FirstPersonPerspective); EventHandler.ExecuteEvent <bool>(m_Character, "OnCameraChangePerspectives", m_ViewType.FirstPersonPerspective); StateManager.LinkGameObjects(m_Character, m_GameObject, true); #if UNITY_EDITOR // Show a warning if the movement type isn't what is recommended for the current view type. Only show this when the character is initially attached // because a mismatch is most likely when initially setting up the character. var recommendedMovementTypes = m_ViewType.GetType().GetCustomAttributes(typeof(RecommendedMovementType), true); if (recommendedMovementTypes != null && recommendedMovementTypes.Length > 0) { var movementType = m_CharacterLocomotion.ActiveMovementType; var isRecommendedMovementType = false; for (int i = 0; i < recommendedMovementTypes.Length; ++i) { var recommendedMovementType = recommendedMovementTypes[0] as RecommendedMovementType; if (recommendedMovementType.Type.IsInstanceOfType(movementType)) { isRecommendedMovementType = true; break; } } if (!isRecommendedMovementType) { Debug.LogWarning($"Warning: The {UnityEngineUtility.GetFriendlyName(movementType.GetType())} MovementType is active while the ViewType " + $"recommends using {UnityEngineUtility.GetFriendlyName((recommendedMovementTypes[0] as RecommendedMovementType).Type)}."); } } #endif } else { // Notify the camera components of the attached character. EventHandler.ExecuteEvent <GameObject>(m_GameObject, "OnCameraAttachCharacter", character); } }
/// <summary> /// Initialize the default values. /// </summary> private void Start() { #if !FIRST_PERSON_CONTROLLER || !THIRD_PERSON_CONTROLLER var demoZones = new List <DemoZone>(m_DemoZones); for (int i = demoZones.Count - 1; i > -1; --i) { // The demo zone may belong to the other perspective. if (demoZones[i].DemoZoneTrigger == null) { demoZones.RemoveAt(i); } } m_DemoZones = demoZones.ToArray(); #endif for (int i = 0; i < m_DemoZones.Length; ++i) { if (m_DemoZones[i].TeleportLocation == null) { continue; } m_DemoZones[i].Initialize(i); m_DemoZoneTriggerDemoZoneMap.Add(m_DemoZones[i].DemoZoneTrigger, m_DemoZones[i]); } // Enable the UI after the character has spawned. m_TextPanel.SetActive(false); m_PreviousZoneArrow.SetActive(false); m_NextZoneArrow.SetActive(false); m_Action.enabled = false; m_CharacterLocomotion = m_Character.GetComponent <UltimateCharacterLocomotion>(); m_CharacterHealth = m_Character.GetComponent <Health>(); m_CharacterRespawner = m_Character.GetComponent <Respawner>(); // Disable the demo components if the character is null. This allows for free roaming within the demo scene. if (m_FreeRoam) { m_FullAccess = true; if (m_PerspectiveSelection != null) { m_PerspectiveSelection.SetActive(false); } var uiZones = GetComponentsInChildren <UIZone>(); for (int i = 0; i < uiZones.Length; ++i) { uiZones[i].enabled = false; } // All of the doors should be opened with free roam. for (int i = 0; i < m_Doors.Count; ++i) { m_Doors[i].CloseOnTriggerExit = false; m_Doors[i].OpenClose(true, true, false); } // The enable objects should be enabled. for (int i = 0; i < m_DemoZones.Length; ++i) { for (int j = 0; j < m_DemoZones[i].EnableObjects.Length; ++j) { m_DemoZones[i].EnableObjects[j].enabled = true; } } // The character needs to be assigned to the camera. var camera = UnityEngineUtility.FindCamera(null); var cameraController = camera.GetComponent <Camera.CameraController>(); cameraController.Character = m_Character; // The character doesn't start out with any items. if (m_FreeRoamItemTypeCounts != null && m_FreeRoamPickupItemTypes) { var inventory = m_Character.GetComponent <InventoryBase>(); if (inventory != null) { for (int i = 0; i < m_FreeRoamItemTypeCounts.Length; ++i) { if (m_FreeRoamItemTypeCounts[i].ItemType == null) { continue; } inventory.PickupItemType(m_FreeRoamItemTypeCounts[i].ItemType, m_FreeRoamItemTypeCounts[i].Count, -1, true, false); } } } EventHandler.ExecuteEvent(m_Character, "OnCharacterSnapAnimator"); enabled = false; return; } // The cursor needs to be visible. Cursor.lockState = CursorLockMode.None; Cursor.visible = true; #if FIRST_PERSON_CONTROLLER && THIRD_PERSON_CONTROLLER // Show the perspective selection menu. if (m_PerspectiveSelection != null) { // The character should be disabled until the perspective is set. m_CharacterLocomotion.SetActive(false, true); m_PerspectiveSelection.SetActive(true); } else { // Determine if the character is a first or third person character. var firstPersonPerspective = m_CharacterLocomotion.MovementTypeFullName.Contains("FirstPerson"); SelectStartingPerspective(firstPersonPerspective); } #elif FIRST_PERSON_CONTROLLER SelectStartingPerspective(true); #else SelectStartingPerspective(false); #endif }