/// <summary> /// Sets the IK target. /// </summary> /// <param name="ikTarget">The IK target that should be set.</param> /// <param name="targetTransform">The transform target that should be set.</param> private void SetIKTarget(AbilityIKTarget ikTarget, Transform targetTransform) { m_CharacterIK.SetAbilityIKTarget(targetTransform, ikTarget.Goal, ikTarget.InterpolationDuration); // If the transform is not null then the end should be scheduled so it can be set to null. if (targetTransform != null) { if (m_DisableIKInteractionEvents == null) { m_DisableIKInteractionEvents = new ScheduledEventBase[m_Interactable.IKTargets.Length]; } else if (m_DisableIKInteractionEvents.Length < m_Interactable.IKTargets.Length) { System.Array.Resize(ref m_DisableIKInteractionEvents, m_Interactable.IKTargets.Length); } for (int i = 0; i < m_DisableIKInteractionEvents.Length; ++i) { if (m_DisableIKInteractionEvents[i] == null) { m_DisableIKInteractionEvents[i] = SchedulerBase.ScheduleFixed <AbilityIKTarget, Transform>(ikTarget.Duration, (AbilityIKTarget abilityIKTarget, Transform target) => { SetIKTarget(ikTarget, target); m_DisableIKInteractionEvents[i] = null; }, ikTarget, null); break; } } } }
/// <summary> /// Fades all of the materials which belong to the renderers. /// </summary> /// <param name="interval">The time interval which updates the fade.</param> /// <param name="targetAlpha">The target alpha value.</param> private void FadeMaterials(float interval, float targetAlpha) { var arrived = true; for (int i = 0; i < m_Renderers.Length; ++i) { if (!m_Renderers[i].material.HasProperty(m_MaterialColorID)) { continue; } var color = m_Renderers[i].material.GetColor(m_MaterialColorID); color.a = Mathf.MoveTowards(color.a, targetAlpha, m_FadeStep); m_Renderers[i].material.SetColor(m_MaterialColorID, color); // Schedule the method again if the material isn't at the desired fade value. if (color.a != targetAlpha) { arrived = false; } } if (arrived) { m_FadeEvent = null; } else { m_FadeEvent = SchedulerBase.Schedule(interval, FadeMaterials, interval, targetAlpha); } }
/// <summary> /// If the platform has arrived at the current waypoint then the next waypoint should be determined. /// </summary> private void UpdatePath() { if (GetRemainingDistance() < 0.01f && m_NextWaypointEvent == null && (m_MovementType != PathMovementType.Target || m_NextWaypoint != m_TargetWaypoint)) { m_NextWaypointEvent = SchedulerBase.ScheduleFixed(m_Waypoints[m_NextWaypoint].Delay, UpdateWaypoint); } }
/// <summary> /// Reduces the health by the damage amount. /// </summary> private void ReduceHealth() { m_Health.Damage(m_DamageAmount.RandomValue); if (m_Health.IsAlive()) { // Keep reducing the object's health until is is no longer alive. SchedulerBase.Schedule(m_HealthReductionInterval.RandomValue, ReduceHealth); } else { // After the object is no longer alive spawn some wood shreds. These shreds should be cleaned up after a random // amount of time. var crateTransform = transform; m_SpawnedCrate = ObjectPoolBase.Instantiate(m_DestroyedCrate, crateTransform.position, crateTransform.rotation); var maxDestroyTime = 0f; for (int i = 0; i < m_SpawnedCrate.transform.childCount; ++i) { var destroyTime = m_WoodShreadRemovalTime.RandomValue; if (destroyTime > maxDestroyTime) { maxDestroyTime = destroyTime; } Destroy(m_SpawnedCrate.transform.GetChild(i).gameObject, destroyTime); } m_StopEvent = SchedulerBase.Schedule(maxDestroyTime, StopParticles); } }
/// <summary> /// Picks up the object. /// </summary> private void DoPickup() { if ((m_AllowedPickups & AllowedPickups.Item) != 0) { if (m_ItemPickup == null) { return; } m_ItemPickup.DoItemIdentifierPickup(m_GameObject, m_Inventory, m_SlotID, true, true); } else { var objectPickup = m_DetectedObject.GetCachedComponent <IObjectPickup>(); if (objectPickup == null) { return; } objectPickup.DoPickup(m_GameObject); } if (!m_PickupCompleteEvent.WaitForAnimationEvent) { SchedulerBase.ScheduleFixed(m_PickupCompleteEvent.Duration, PickupComplete); } }
/// <summary> /// Updates the timescale according to the specified change speed. /// </summary> /// <param name="activate">Has the timescale been activated?</param> private void UpdateTimeScale(bool activate) { m_Time += m_TimeScaleChangeSpeed; var startTime = activate ? 1 : m_TimeScale; var endTime = activate ? m_TimeScale : 1; m_CharacterLocomotion.TimeScale = Mathf.SmoothStep(startTime, endTime, m_Time); if (m_Time > 1) { m_Time = 0; if (m_Active) { // Reset the time after the duration. m_Active = false; m_Time = 0; SchedulerBase.Schedule(m_Duration, UpdateTimeScale, !activate); } else { for (int i = 0; i < m_Children.Length; ++i) { m_Children[i].SetActive(true); } } } else { // Keep updating the timescale until the time is 1. SchedulerBase.Schedule(0.05f, UpdateTimeScale, activate); } }
/// <summary> /// The character should start the jump. /// </summary> private void ApplyJumpForce() { if (IsActive && !m_JumpApplied) { // A surface effect can optionally play when the character leaves the ground. if (m_JumpSurfaceImpact != null) { SurfaceManager.SpawnEffect(m_CharacterLocomotion.GroundRaycastHit, m_JumpSurfaceImpact, m_CharacterLocomotion.GravityDirection, m_CharacterLocomotion.TimeScale, m_GameObject); } // Do not set the Jumping variable because the ability should be active for at least one frame. If Jumping was set there is a chance // the ability could stop right away if the character jumps while moving down a slope. m_JumpApplied = true; m_JumpTime = Time.time; var force = m_Force; // Prevent the character from jumping as high when moving backwards or sideways. if (m_CharacterLocomotion.InputVector.y < 0) { force *= Mathf.Lerp(1, m_BackwardsForceMultiplier, Mathf.Abs(m_CharacterLocomotion.InputVector.y)); } else { // The character's forward movement will contribute to a full jump force. force *= Mathf.Lerp(1, m_SidewaysForceMultiplier, Mathf.Abs(m_CharacterLocomotion.InputVector.x) - Mathf.Abs(m_CharacterLocomotion.InputVector.y)); } AddForce(m_CharacterLocomotion.Up * force, m_Frames, false, true); // Ensure the character is in the air after jumping. SchedulerBase.ScheduleFixed(Time.deltaTime * 2, EnsureAirborne); } }
/// <summary> /// Sets the hit point that the tracer should move to. /// </summary> /// <param name="hitPoint">The hit point position.</param> public virtual void Initialize(Vector3 hitPoint) { m_LineRenderer.SetPosition(0, m_Transform.position); m_LineRenderer.SetPosition(1, hitPoint); SchedulerBase.Schedule(m_VisibleTime, DestroyObject); }
/// <summary> /// Stops reloading the item in the specified slot. /// </summary> /// <param name="slotID">The ID of the slot to stop reloading the item at.</param> public void StopItemReload(int slotID) { if (m_ReloadableItems[slotID] == null) { return; } m_ReloadableItems[slotID].ItemReloadComplete(false, false); m_ReloadableItems[slotID] = null; m_Reloaded[slotID] = false; SchedulerBase.Cancel(m_ReloadEvents[slotID]); m_ReloadEvents[slotID] = null; m_CharacterLocomotion.UpdateItemAbilityAnimatorParameters(); // The ability won't be active if CanStartAbility filled in the ReloadableItem but the ability hasn't started yet. if (!IsActive) { return; } // The ability should stop if no more items can be reloaded. var canStop = true; for (int i = 0; i < m_ReloadableItems.Length; ++i) { if (m_ReloadableItems[i] != null) { canStop = false; } } if (canStop) { StopAbility(true); } }
public static void DomainReset() { EventHandler.DomainReset(); GameObjectExtensions.DomainReset(); ObjectPoolBase.DomainReset(); SchedulerBase.DomainReset(); }
/// <summary> /// The ThrowableItem has been reequipped. /// </summary> private void ReequipThrowableItem() { if (!m_Reequipping) { return; } SchedulerBase.Cancel(m_ReequipEventBase); m_ReequipEventBase = null; m_Reequipping = false; m_Reequipped = true; m_ReequipFrame = Time.frameCount; // The item shouldn't be reequipped if it is out of ammo. if (m_Inventory != null && m_Inventory.GetItemIdentifierAmount(m_Item.ItemIdentifier) == 0) { return; } if (!m_DisableVisibleObject) { EnableObjectMeshRenderers(true); #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) { m_NetworkCharacter.EnableThrowableObjectMeshRenderers(this); } #endif } }
/// <summary> /// Internal method which activates the state and then deactivates the state after the specified amount of time. /// </summary> /// <param name="stateGameObject">The GameObject to set the state on.</param> /// <param name="stateName">The name of the state to activate and then deactivate.</param> /// <param name="time">The amount of time that should elapse before the state is disabled.</param> private void DeactivateStateTimerInternal(GameObject stateGameObject, string stateName, float time) { if (m_DisableStateTimerMap == null) { m_DisableStateTimerMap = new Dictionary <GameObject, Dictionary <string, ScheduledEventBase> >(); } if (m_DisableStateTimerMap.TryGetValue(stateGameObject, out var stateNameEventMap)) { if (stateNameEventMap.TryGetValue(stateName, out var disableEvent)) { // The state name exists. This means that the timer is currently active and should first been cancelled. SchedulerBase.Cancel(disableEvent); disableEvent = SchedulerBase.Schedule(time, DeactivateState, stateGameObject, stateName); } else { // The state name hasn't been added yet. Add it to the map. disableEvent = SchedulerBase.Schedule(time, DeactivateState, stateGameObject, stateName); stateNameEventMap.Add(stateName, disableEvent); } } else { // Neither the GameObject nor the state has been activated. Create the maps. stateNameEventMap = new Dictionary <string, ScheduledEventBase>(); var disableEvent = SchedulerBase.Schedule(time, DeactivateState, stateGameObject, stateName); stateNameEventMap.Add(stateName, disableEvent); m_DisableStateTimerMap.Add(stateGameObject, stateNameEventMap); } }
/// <summary> /// The ability has stopped running. /// </summary> /// <param name="force">Was the ability force stopped?</param> protected override void AbilityStopped(bool force) { base.AbilityStopped(force); // The item may require root motion to prevent sliding. for (int i = 0; i < m_UsableItems.Length; ++i) { if (m_UsableItems[i] != null) { if (m_UsableItems[i].ForceRootMotionPosition) { m_CharacterLocomotion.ForceRootMotionPosition = false; } if (m_UsableItems[i].ForceRootMotionRotation) { m_CharacterLocomotion.ForceRootMotionRotation = false; } m_UsableItems[i].StopItemUse(); EventHandler.ExecuteEvent(m_GameObject, "OnItemStartUse", m_UsableItems[i], false); m_UsableItems[i] = null; m_UseCompleted[i] = true; if (m_UseEvent[i] != null) { SchedulerBase.Cancel(m_UseEvent[i]); m_UseEvent[i] = null; } ResetCanStopEvent(i); } } m_Started = false; EventHandler.ExecuteEvent(m_GameObject, "OnUseAbilityStart", false, this); }
/// <summary> /// The ability has stopped running. /// </summary> /// <param name="force">Was the ability force stopped?</param> protected override void AbilityStopped(bool force) { base.AbilityStopped(force); if (m_ExitedTrigger) { m_Interactable = null; m_DetectedTriggerObjectsCount = 0; DetectedObject = null; m_ExitedTrigger = false; } // The ability may end before the interaction duration has elapsed. if (m_DisableIKInteractionEvents != null) { for (int i = 0; i < m_DisableIKInteractionEvents.Length; ++i) { if (m_DisableIKInteractionEvents[i] == null) { continue; } m_DisableIKInteractionEvents[i].Invoke(); SchedulerBase.Cancel(m_DisableIKInteractionEvents[i]); m_DisableIKInteractionEvents[i] = null; } } }
/// <summary> /// Determines if a controller is connected. /// </summary> private void CheckForController() { if (!CanCheckForController) { return; } var controllerConencted = Input.GetJoystickNames().Length > 0; if (m_ControllerConnected != controllerConencted) { m_ControllerConnected = controllerConencted; #if FIRST_PERSON_CONTROLLER || THIRD_PERSON_CONTROLLER if (!string.IsNullOrEmpty(m_ConnectedControllerState)) { StateManager.SetState(gameObject, m_ConnectedControllerState, m_ControllerConnected); } #endif EventHandler.ExecuteEvent <bool>(gameObject, "OnInputControllerConnected", m_ControllerConnected); } // Schedule the controller check event if the rate is positive. // UnityEngine.Input.GetJoystickNames generates garbage so limit the amount of time the controller is checked. if (m_ControllerConnectedCheckRate > 0 && (m_ControllerCheckEvent == null || !m_ControllerCheckEvent.Active)) { m_ControllerCheckEvent = SchedulerBase.Schedule(m_ControllerConnectedCheckRate, CheckForController); } }
/// <summary> /// The animator has finished playing the reload animation. /// </summary> /// <param name="slotID">The slot that is reloading the item.</param> private void ReloadItemComplete(int slotID) { var reloadableItem = m_ReloadableItems[slotID]; if (reloadableItem == null) { return; } m_ReloadableItems[slotID].ItemReloadComplete(true, false); m_ReloadableItems[slotID] = null; if (m_ReloadEvents[slotID] != null) { SchedulerBase.Cancel(m_ReloadEvents[slotID]); m_ReloadEvents[slotID] = null; } // Don't stop the ability unless all slots have been reloaded. var stopAbility = true; for (int i = 0; i < m_ReloadableItems.Length; ++i) { if (m_ReloadableItems[i] != null) { stopAbility = false; break; } } if (stopAbility) { StopAbility(); } }
/// <summary> /// Determines the location to respawn the object to and then does the respawn. /// </summary> public void Respawn() { m_ScheduledRespawnEvent = null; if (m_PositioningMode != SpawnPositioningMode.None) { Vector3 position; Quaternion rotation; if (m_PositioningMode == SpawnPositioningMode.SpawnPoint) { position = m_Transform.position; rotation = m_Transform.rotation; // If the object can't be spawned then try again in the future. if (!SpawnPointManager.GetPlacement(m_GameObject, m_Grouping, ref position, ref rotation)) { m_ScheduledRespawnEvent = SchedulerBase.Schedule(Random.Range(m_MinRespawnTime, m_MaxRespawnTime), Respawn); return; } } else // Spawn Location. { position = m_StartPosition; rotation = m_StartRotation; } Respawn(position, rotation, true); } else { Respawn(m_Transform.position, m_Transform.rotation, false); } }
/// <summary> /// Updates the action. /// </summary> public override void Update() { if (!m_Active) { return; } var active = false; for (int i = 0; i < m_Materials.Count; ++i) { var color = m_Materials[i].GetColor(m_ColorID); color.a = Mathf.MoveTowards(color.a, m_TargetAlpha, m_FadeSpeed); m_Materials[i].SetColor(m_ColorID, color); if (color.a != m_TargetAlpha) { active = true; } } #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER // Update isn't called automatically for the remote players. if (active && m_MagicItem.NetworkInfo != null && !m_MagicItem.NetworkInfo.IsLocalPlayer()) { m_UpdateEvent = SchedulerBase.Schedule(0.001f, Update); } #endif m_Active = active; }
/// <summary> /// The ability has stopped running. /// </summary> /// <param name="force">Was the ability force stopped?</param> protected override void AbilityStopped(bool force) { base.AbilityStopped(force); m_MoveTowardsLocation = null; if (force) { m_OnArriveAbility = null; } if (m_ForceStartEvent != null) { SchedulerBase.Cancel(m_ForceStartEvent); m_ForceStartEvent = null; } if (m_DisableGameplayInput) { EventHandler.ExecuteEvent(m_GameObject, "OnEnableGameplayInput", true); } if (m_PathfindingMovement != null && m_PathfindingMovement.IsActive) { m_PathfindingMovement.StopAbility(true); } // Reset the force independet look parameter set within StartAbility. EventHandler.ExecuteEvent(m_GameObject, "OnCharacterForceIndependentLook", false); // Start the OnArriveAbility after MoveTowards has stopped to prevent MoveTowards from affecting the arrive ability. if (m_OnArriveAbility != null) { m_CharacterLocomotion.TryStartAbility(m_OnArriveAbility, true, true); m_OnArriveAbility = null; } }
/// <summary> /// The ability has started. /// </summary> protected override void AbilityStarted() { base.AbilityStarted(); var waitForUnequip = false; // The ItemSetManager will be null when the items are managed by Slot ID rather than ItemSet (such as for first person VR). if (m_ItemSetManager != null && m_WaitForUnequip) { for (int i = 0; i < m_Items.Length; ++i) { if (m_Items[i] != null) { for (int j = 0; j < m_EquipUnequipAbilities.Length; ++j) { if (m_ItemSetManager.IsCategoryMember(m_Items[i].ItemIdentifier.GetItemDefinition(), m_EquipUnequipAbilities[j].ItemSetCategoryIndex)) { m_EquipUnequipAbilities[j].StartEquipUnequip(m_ItemSetManager.GetDefaultItemSetIndex(m_EquipUnequipAbilities[j].ItemSetCategoryIndex)); waitForUnequip = true; } } } } } if (!waitForUnequip && !m_DropEvent.WaitForAnimationEvent) { SchedulerBase.ScheduleFixed(m_DropEvent.Duration, DropItem); } }
/// <summary> /// Callback when the auto update event is executed. /// </summary> private void UpdateValue() { if (m_AutoUpdateValueType == AutoUpdateValue.None) { return; } m_AutoUpdateEvent = null; if (m_AutoUpdateValueType == AutoUpdateValue.Increase) { m_Value = Mathf.Min(m_Value + m_AutoUpdateAmount, m_MaxValue); if (m_Value < m_MaxValue) { m_AutoUpdateEvent = SchedulerBase.ScheduleFixed(m_AutoUpdateInterval, UpdateValue); } else { EventHandler.ExecuteEvent(this, "OnAttributeReachedDestinationValue"); } } else // Decrease. { m_Value = Mathf.Max(m_Value - m_AutoUpdateAmount, m_MinValue); if (m_Value > m_MinValue) { m_AutoUpdateEvent = SchedulerBase.ScheduleFixed(m_AutoUpdateInterval, UpdateValue); } else { EventHandler.ExecuteEvent(this, "OnAttributeReachedDestinationValue"); } } EventHandler.ExecuteEvent(m_GameObject, "OnAttributeUpdateValue", this); }
/// <summary> /// An object has entered the trigger. /// </summary> /// <param name="other">The object that entered the trigger.</param> private void OnTriggerEnter(Collider other) { if (m_Health != null) { return; } // A main character collider is required. if (!MathUtility.InLayerMask(other.gameObject.layer, 1 << LayerManager.Character)) { return; } // The object must be a character. var characterLocomotion = other.GetComponentInParent <UltimateCharacterLocomotion>(); if (characterLocomotion == null) { return; } // With a health component. var health = characterLocomotion.GetComponent <Health>(); if (health == null) { return; } m_Health = health; m_HealthTransform = health.transform; m_ScheduledDamageEvent = SchedulerBase.Schedule(m_InitialDamageDelay, Damage); }
/// <summary> /// Fades the message according to the fade speed. /// </summary> private void FadeMessage() { m_ObjectAlphaColor = Mathf.Max(m_ObjectAlphaColor - m_ObjectFadeSpeed, 0); if (m_ObjectAlphaColor == 0) { m_GameObject.SetActive(false); m_ShouldFade = false; m_ScheduledFade = null; m_ObjectPickup = null; return; } // Fade the text and icon. if (m_Text != null) { var color = m_Text.color; color.a = m_ObjectAlphaColor; m_Text.color = color; } if (m_Icon) { var color = m_Icon.color; color.a = m_ObjectAlphaColor; m_Icon.color = color; } // Keep fading until there is nothing left to fade. m_ScheduledFade = SchedulerBase.Schedule(0.01f, FadeMessage); }
/// <summary> /// Adjusts the collider's center position to the specified value. /// </summary> /// <param name="targetOffset">The desired offset value.</param> private void AdjustCenterOffset(Vector3 targetOffset) { var delta = targetOffset - m_CenterOffset; m_CapsuleCollider.center += delta; m_CapsuleCollider.height += delta.y / 2; m_ColliderOffsetEvent = null; if (!m_CharacterLocomotion.UsingHorizontalCollisionDetection) { m_CenterOffset = targetOffset; return; } // Apply the offset if there are no collisions. var collisionEnabled = m_CharacterLocomotion.CollisionLayerEnabled; m_CharacterLocomotion.EnableColliderCollisionLayer(false); Vector3 firstEndCap, secondEndCap; MathUtility.CapsuleColliderEndCaps(m_CapsuleCollider, m_Transform.position, m_Transform.rotation, out firstEndCap, out secondEndCap); if (Physics.OverlapCapsuleNonAlloc(firstEndCap, secondEndCap, m_CapsuleCollider.radius * MathUtility.ColliderRadiusMultiplier(m_CapsuleCollider), m_OverlapColliders, m_CharacterLayerManager.SolidObjectLayers, QueryTriggerInteraction.Ignore) > 0) { m_CapsuleCollider.center -= delta; m_CapsuleCollider.height -= delta.y / 2; m_ColliderOffsetEvent = SchedulerBase.Schedule(Time.fixedDeltaTime, AdjustCenterOffset, targetOffset); } else { m_CenterOffset = targetOffset; } m_CharacterLocomotion.EnableColliderCollisionLayer(collisionEnabled); }
/// <summary> /// Starts the item use. /// </summary> /// <param name="itemAbility">The item ability that is using the item.</param> public override void StartItemUse(ItemAbility itemAbility) { base.StartItemUse(itemAbility); // An Animator Audio State Set may prevent the item from being used. if (!IsItemInUse()) { return; } // Grenades can be cooked (and explode while still in the character's hands). m_InstantiatedGrenade = m_InstantiatedTrajectoryObject as Grenade; m_InstantiatedGrenade.StartCooking(m_Character); // If a pin is specified then it can optionally be removed when the grenade is being thrown. if (m_InstantiatedGrenade.Pin != null) { if (m_AnimatePinRemoval && !m_DisableVisibleObject) { if (m_RemovePinEvent.WaitForAnimationEvent) { EventHandler.RegisterEvent(m_Character, "OnAnimatorItemRemovePin", RemovePin); } else { SchedulerBase.ScheduleFixed(m_RemovePinEvent.Duration, RemovePin); } } } }
/// <summary> /// An object has entered the trigger. /// </summary> /// <param name="other">The object that entered the trigger.</param> private void OnTriggerEnter(Collider other) { if (m_ActiveObject != null || !MathUtility.InLayerMask(other.gameObject.layer, 1 << LayerManager.Character)) { return; } var characterLocomotion = other.GetComponentInParent <UltimateCharacterLocomotion>(); if (characterLocomotion == null) { return; } // The object is a character. Expand the trigger. if (m_Collider is BoxCollider) { AdjustBoxCollider(m_Collider as BoxCollider, m_BoxColliderCenterAdjustment, m_BoxColliderExpansion); } else if (m_Collider is MeshCollider) { // When the mesh is inflated it'll trigger an OnTriggerExit callback. Prevent this callback from doing anything until // after the inflated mesh has stabalized. m_AllowTriggerExit = false; SchedulerBase.ScheduleFixed(Time.fixedDeltaTime * 2, () => { m_AllowTriggerExit = true; }); (m_Collider as MeshCollider).sharedMesh = m_ExpandedMesh; } m_ActiveObject = other.gameObject; }
/// <summary> /// Stops the cast. /// </summary> public override void Stop() { if (!m_Active) { return; } m_ParticleSystem.Stop(true, ParticleSystemStopBehavior.StopEmitting); // Optionally fade the particle out of the world. if (m_FadeOutDuration > 0) { if (m_FadeEvent != null) { SchedulerBase.Cancel(m_FadeEvent); m_FadeEvent = null; } if (m_Renderers == null) { m_Renderers = m_ParticleSystem.GetComponentsInChildren <ParticleSystemRenderer>(); } var interval = m_FadeOutDuration / (1 / m_FadeStep); // Reset the alpha if the renderers have no fade in duration. if (m_FadeInDuration == 0) { SetRendererAlpha(1); } m_FadeEvent = SchedulerBase.Schedule(interval, FadeMaterials, interval, 0f); } m_Active = false; base.Stop(); }
/// <summary> /// Performs the cast. /// </summary> /// <param name="origin">The location that the cast should spawn from.</param> /// <param name="direction">The direction of the cast.</param> /// <param name="targetPosition">The target position of the cast.</param> public override void Cast(Transform origin, Vector3 direction, Vector3 targetPosition) { if (m_AudioSource != null && m_FadeEvent == null) { return; } if (m_AudioClips == null || m_AudioClips.Length == 0) { Debug.LogError("Error: An Audio Clip must be specified.", m_MagicItem); return; } var audioClip = m_AudioClips[Random.Range(0, m_AudioClips.Length)]; if (audioClip == null) { Debug.Log("Error: The Audio Clip array has a null value."); return; } m_AudioSource = AudioManager.PlayAtPosition(audioClip, m_PlayAtOrigin ? origin.position : m_GameObject.transform.position).AudioSource; if (m_AudioSource != null) { m_AudioSource.volume = 1; m_AudioSource.loop = m_Loop; } if (m_FadeEvent != null) { SchedulerBase.Cancel(m_FadeEvent); m_FadeEvent = null; } }
/// <summary> /// The effect has stopped running. /// </summary> protected override void EffectStopped() { base.EffectStopped(); SchedulerBase.Cancel(m_StopEvent); m_StopEvent = null; }
/// <summary> /// Change the spring types to the specified type. /// </summary> /// <param name="type">The type to change the value to.</param> private void ChangeSpringType(SpringType type) { // Don't switch types if the type is equal to the current type or if the enable state event is active. This will occur if a new button is pressed // within the time that it takes to invoke the scheduled event. if (m_SpringType == type || m_EnableStateEvent != null) { return; } // Reset the button color and deactivate the previous character. The same character may be activated again depending on the spring type. if (m_SpringType != SpringType.None) { SetButtonColor((int)m_SpringType, m_NormalColor); if (m_ActiveCharacter != null) { m_ActiveCharacter.SetActive(false); StateManager.SetState(m_ActiveCharacter, System.Enum.GetName(typeof(SpringType), m_SpringType), false); } } // Remember the old spring type and activate the new. The button should reflect the selected spring type. var prevSpringType = m_SpringType; m_SpringType = type; SetButtonColor((int)m_SpringType, m_PressedColor); // If the previous spring type isn't None then a button was pressed. Activate the new character. if (prevSpringType != SpringType.None) { var prevCharacter = m_ActiveCharacter; // The active character depends on the spring type. if (m_SpringType == SpringType.Astronaut || m_SpringType == SpringType.DrunkPerson) { m_ActiveCharacter = m_DrunkAstronautCharacter; } else if (m_SpringType == SpringType.Giant) { m_ActiveCharacter = m_GiantCharacter; } else { m_ActiveCharacter = m_Character; } // Activate the correct character and set the camera to the character if that character changed. This shouldn't be done if the character didn't // change so the camera doesn't snap into position. var characterChange = m_ActiveCharacter != prevCharacter; m_ActiveCharacter.SetActive(true); if (characterChange) { m_CameraController.Character = m_ActiveCharacter; } // Wait a small amount of time if the springs are off so the item can get back into the correct position while the springs are enabled. m_EnableStateEvent = SchedulerBase.Schedule(m_SpringType == SpringType.SpringsOff ? 0.4f : 0, EnableSpringState, characterChange); } EnableInput(); }