예제 #1
0
 /// <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;
             }
         }
     }
 }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
 /// <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);
     }
 }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        /// <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);
            }
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
            }
        }
예제 #10
0
 public static void DomainReset()
 {
     EventHandler.DomainReset();
     GameObjectExtensions.DomainReset();
     ObjectPoolBase.DomainReset();
     SchedulerBase.DomainReset();
 }
예제 #11
0
        /// <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
            }
        }
예제 #12
0
        /// <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);
            }
        }
예제 #13
0
파일: Use.cs 프로젝트: ridleytech/CAA-Unity
        /// <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);
        }
예제 #14
0
        /// <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;
                }
            }
        }
예제 #15
0
        /// <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);
            }
        }
예제 #16
0
        /// <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();
            }
        }
예제 #17
0
        /// <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);
            }
        }
예제 #18
0
        /// <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;
        }
예제 #19
0
        /// <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;
            }
        }
예제 #20
0
        /// <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);
            }
        }
예제 #21
0
        /// <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);
        }
예제 #22
0
        /// <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);
        }
예제 #23
0
        /// <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);
        }
예제 #25
0
        /// <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);
                    }
                }
            }
        }
예제 #26
0
        /// <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;
        }
예제 #27
0
        /// <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();
        }
예제 #28
0
        /// <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;
            }
        }
예제 #29
0
        /// <summary>
        /// The effect has stopped running.
        /// </summary>
        protected override void EffectStopped()
        {
            base.EffectStopped();

            SchedulerBase.Cancel(m_StopEvent);
            m_StopEvent = null;
        }
예제 #30
0
        /// <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();
        }