/// <summary> /// The ability has started. /// </summary> protected override void AbilityStarted() { // If a handler exists then the ability is interested in updates when the axis value changes. This for example allows the lean to switch // between the left and right lean without having to stop and start again. if (m_Handler != null) { m_LeanInput = GenericObjectPool.Get <ActiveInputEvent>(); m_LeanInput.Initialize(ActiveInputEvent.Type.Axis, InputNames[InputIndex], "OnLeanInputUpdate"); m_Handler.RegisterInputEvent(m_LeanInput); } EventHandler.RegisterEvent <float>(m_GameObject, "OnLeanInputUpdate", OnInputUpdate); base.AbilityStarted(); // The collider should be activated when the ability starts. The collider detects when the character would be clipping with a wall // and also allows the character to be shot at while leaning. if (m_ColliderGameObject != null) { m_ColliderGameObject.SetActive(true); } // Start leaning. m_AxisValue = InputAxisValue; UpdateLean(true); }
/// <summary> /// Perform the impact action. /// </summary> /// <param name="castID">The ID of the cast.</param> /// <param name="source">The object that caused the cast.</param> /// <param name="target">The object that was hit by the cast.</param> /// <param name="hit">The raycast that caused the impact.</param> protected override void ImpactInternal(uint castID, GameObject source, GameObject target, RaycastHit hit) { var targetAttributeManager = target.GetCachedParentComponent <AttributeManager>(); if (targetAttributeManager == null) { return; } // The impact action can collide with multiple objects. Use a pooled version of the AttributeModifier for each collision. var attributeModifier = GenericObjectPool.Get <AttributeModifier>(); if (!attributeModifier.Initialize(m_AttributeModifier, targetAttributeManager)) { GenericObjectPool.Return(attributeModifier); return; } // The attribute exists. Enable the modifier. Return the modifier as soon as it is complete (which may be immediate). attributeModifier.EnableModifier(true); if (attributeModifier.AutoUpdating && attributeModifier.AutoUpdateDuration > 0) { EventHandler.RegisterEvent <AttributeModifier, bool>(attributeModifier, "OnAttributeModifierAutoUpdateEnable", ModifierAutoUpdateEnabled); } else { GenericObjectPool.Return(attributeModifier); } }
/// <summary> /// Initialize the default values. /// </summary> public override void Awake() { base.Awake(); m_Handler = m_GameObject.GetCachedComponent <UltimateCharacterLocomotionHandler>(); // Work with the handler to listen for any input events. if (m_Handler != null) { m_StartRotateInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_StartRotateInputEvent.Initialize(ActiveInputEvent.Type.ButtonDown, m_RotateInputName, "OnRPGMovementTypeStartRotate"); m_StopRotateInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_StopRotateInputEvent.Initialize(ActiveInputEvent.Type.ButtonUp, m_RotateInputName, "OnRPGMovementTypeStopRotate"); m_TurnInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_TurnInputEvent.Initialize(ActiveInputEvent.Type.Axis, m_TurnInputName, "OnRPGMovementTypeTurn"); m_AutoMoveInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_AutoMoveInputEvent.Initialize(ActiveInputEvent.Type.ButtonDown, m_AutoMoveInputName, "OnRPGMovementTypeAutoMove"); m_Handler.RegisterInputEvent(m_StartRotateInputEvent); m_Handler.RegisterInputEvent(m_TurnInputEvent); m_Handler.RegisterInputEvent(m_AutoMoveInputEvent); } EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeStartRotate", OnStartRotate); EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeStopRotate", OnStopRotate); EventHandler.RegisterEvent <float>(m_GameObject, "OnRPGMovementTypeTurn", OnTurn); EventHandler.RegisterEvent(m_GameObject, "OnRPGMovementTypeAutoMove", OnToggleAutoMove); }
/// <summary> /// The object has been damaged. /// </summary> /// <param name="amount">The amount of damage taken.</param> /// <param name="position">The position of the damage.</param> /// <param name="direction">The direction that the object took damage from.</param> /// <param name="forceMagnitude">The magnitude of the force that is applied to the object.</param> /// <param name="frames">The number of frames to add the force to.</param> /// <param name="radius">The radius of the explosive damage. If 0 then a non-explosive force will be used.</param> /// <param name="attacker">The GameObject that did the damage.</param> /// <param name="attackerObject">The object that did the damage.</param> /// <param name="hitCollider">The Collider that was hit.</param> public void Damage(float amount, Vector3 position, Vector3 direction, float forceMagnitude, int frames, float radius, GameObject attacker, object attackerObject, Collider hitCollider) { var pooledDamageData = GenericObjectPool.Get <DamageData>(); pooledDamageData.SetDamage(amount, position, direction, forceMagnitude, frames, radius, attacker, attackerObject, hitCollider); Damage(pooledDamageData); GenericObjectPool.Return(pooledDamageData); }
/// <summary> /// Initializes the object. /// </summary> /// <param name="characterLocomotion">The character that is being managed by the KinematicObjectManager.</param> public void Initialize(UltimateCharacterLocomotion characterLocomotion) { m_CharacterLocomotion = characterLocomotion; OnAttachLookSource(m_CharacterLocomotion.LookSource); EventHandler.RegisterEvent <ILookSource>(m_CharacterLocomotion.gameObject, "OnCharacterAttachLookSource", OnAttachLookSource); EventHandler.RegisterEvent <bool>(m_CharacterLocomotion.gameObject, "OnCharacterChangeUpdateLocation", OnChangeUpdateLocation); // The class is pooled so reset any variables. m_HorizontalMovement = m_ForwardMovement = m_DeltaYawRotation = 0; Initialize(characterLocomotion.transform); m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>(); m_CharacterIK = m_CharacterLocomotion.GetComponent <CharacterIKBase>(); // Wait a moment before finishing with the initialization. This allows the character to be created at runtime. m_CompleteInitEvent = Scheduler.ScheduleFixed(Time.fixedDeltaTime / 2, () => { if (m_CharacterHandler == null) { m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>(); } if (m_CharacterIK == null) { m_CharacterIK = m_CharacterLocomotion.GetComponent <CharacterIKBase>(); } var smoothedBones = m_CharacterLocomotion.SmoothedBones; if (smoothedBones != null && smoothedBones.Length > 0) { var validBones = 0; for (int i = 0; i < smoothedBones.Length; ++i) { if (smoothedBones[i] != null) { validBones++; } } if (validBones > 0) { m_SmoothedBones = new SmoothFixedLocation[validBones]; var index = 0; for (int i = 0; i < smoothedBones.Length; ++i) { if (smoothedBones[i] == null) { continue; } m_SmoothedBones[index] = GenericObjectPool.Get <SmoothFixedLocation>(); m_SmoothedBones[index].Initialize(smoothedBones[i]); index++; } } } m_CompleteInitEvent = null; }); }
/// <summary> /// Internal method which registers the character to be managed by the KinematicObjectManager. /// </summary> /// <param name="characterLocomotion">The character that should be managed by the KinematicObjectManager.</param> /// <returns>The index of the character registered.</returns> private int RegisterCharacterInternal(UltimateCharacterLocomotion characterLocomotion) { if (m_CharacterCount == m_Characters.Length) { System.Array.Resize(ref m_Characters, m_Characters.Length + 1); Debug.LogWarning($"Characters array resized. For best performance increase the size of the Start Character Count variable " + $"within the Kinematic Object Manager to a value of at least {(m_CharacterCount + 1)}."); } m_Characters[m_CharacterCount] = GenericObjectPool.Get <KinematicCharacter>(); m_Characters[m_CharacterCount].Initialize(characterLocomotion); m_CharacterCount++; return(m_CharacterCount - 1); }
/// <summary> /// Intenral method which registers the camera to be managed by the KinematicObjectManager. /// </summary> /// <param name="cameraController">The camera that should be managed by the KinematicObjectManager.</param> /// <returns>The index of the camera registered.</returns> private int RegisterCameraInternal(CameraController cameraController) { if (m_CameraCount == m_Cameras.Length) { System.Array.Resize(ref m_Cameras, m_Cameras.Length + 1); Debug.LogWarning($"Cameras array resized. For best performance increase the size of the Start Camera Count variable " + $"within the Kinematic Object Manager to a value of at least {(m_CameraCount + 1)}."); } m_Cameras[m_CameraCount] = GenericObjectPool.Get <KinematicCamera>(); m_Cameras[m_CameraCount].Initialize(cameraController); m_CameraCount++; return(m_CameraCount - 1); }
/// <summary> /// Internal method which registers the kinematic object that should be managed by the KinematicObjectManager. /// </summary> /// <param name="kinematicObject">The kinematic object that should be managed by the KinematicObjectManager.</param> /// <returns>The index of the kinematci object registered.</returns> private int RegisterKinematicObjectInternal(IKinematicObject kinematicObject) { if (m_KinematicObjectCount == m_KinematicObjects.Length) { System.Array.Resize(ref m_KinematicObjects, m_KinematicObjects.Length + 1); Debug.LogWarning($"Kinematic objects array resized. For best performance increase the size of the Start Kinematic Object Count variable " + $"within the Kinematic Object Manager to a value of at least {(m_KinematicObjectCount + 1)}."); } m_KinematicObjects[m_KinematicObjectCount] = GenericObjectPool.Get <KinematicObject>(); m_KinematicObjects[m_KinematicObjectCount].Initialize(kinematicObject); m_KinematicObjectCount++; return(m_KinematicObjectCount - 1); }
public TimerInstance AddTimer( float intervalInSec, float totalInSec, TimerEventHandler intervalCallback, TimerEventHandler endCallback, object userdata) { int index = m_IndexCreator.NextID; TimerTask task = m_TaskPool.Get(); task.SetData(index, intervalInSec, totalInSec, intervalCallback, endCallback, userdata); return(AddTask(task, null)); }
public void SendMessage(int messageID, MessageCompressType compressType, MessageCryptoType cryptoType, byte[] dataBytes) { lock (cachedWillSendMessageLocker) { var willSendMessage = willSendMessagePool.Get(); willSendMessage.ID = messageID; willSendMessage.CompressType = compressType; willSendMessage.CryptoType = cryptoType; willSendMessage.DataBytes = dataBytes; cachedWillSendMessages.Add(willSendMessage); } DoSend(); }
/// <summary> /// Enables fading on the renderers. /// </summary> private void EnableRendererFade() { // Fade all of the active renderers. var renderers = m_Character.GetComponentsInChildren <Renderer>(false); for (int i = 0; i < renderers.Length; ++i) { // The fade can be ignored. if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null) { continue; } var materials = renderers[i].materials; for (int j = 0; j < materials.Length; ++j) { var material = materials[j]; if (m_ActiveMaterials.Contains(material) || !material.HasProperty(m_ColorID)) { continue; } m_Materials.Add(material); m_ActiveMaterials.Add(material); // Cache the original values so they can be reverted. var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>(); originalMaterialValues.Initialize(material, m_ColorID, material.HasProperty(OriginalMaterialValue.ModeID)); m_OriginalMaterialValuesMap.Add(material, originalMaterialValues); // The material should be able to fade. material.SetFloat(OriginalMaterialValue.ModeID, 2); material.SetInt(OriginalMaterialValue.SrcBlendID, (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt(OriginalMaterialValue.DstBlendID, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.EnableKeyword(OriginalMaterialValue.AlphaBlendString); material.renderQueue = 3000; // If the action is already active then the material is being faded when the perspective is switching. Set the alpha to the // same alpha value as the rest of the materials. if (m_Active) { var color = material.GetColor(m_ColorID); color.a = m_Materials[0].GetColor(m_ColorID).a; material.SetColor(m_ColorID, color); } } } }
/// <summary> /// The object has taken damage. /// </summary> /// <param name="amount">The amount of damage taken.</param> /// <param name="position">The position of the damage.</param> /// <param name="force">The amount of force applied to the object while taking the damage.</param> /// <param name="attacker">The GameObject that did the damage.</param> /// <param name="hitCollider">The Collider that was hit.</param> private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider) { // Don't show a hit indicator if the force is 0 or there is no attacker. This prevents damage such as fall damage from showing the damage indicator. if ((!m_AlwaysShowIndicator && force.sqrMagnitude == 0) || attacker == null || m_ActiveDamageIndicatorCount == m_ActiveDamageIndicators.Length) { return; } var attackerPosition = (m_FollowAttacker && m_CharacterTransform != attacker) ? attacker.transform.position : position; // Adjust the hit position. var localHitPosition = attacker.transform.InverseTransformPoint(position); localHitPosition.x = localHitPosition.z = 0; attackerPosition += attacker.transform.TransformDirection(localHitPosition); var screenPoint = m_Camera.WorldToScreenPoint(attackerPosition); var centerScreenPoint = ((new Vector2(screenPoint.x, screenPoint.y) - (new Vector2(m_Camera.pixelWidth, m_Camera.pixelHeight) / 2)) * Mathf.Sign(screenPoint.z)).normalized; // Determine the angle of the damage position to determine if a new damage indicator should be shown. var angle = Vector2.SignedAngle(centerScreenPoint, Vector2.right); // Do not show a new damage indicator if the angle is less than a threshold compared to the already displayed indicators. DamageIndicator damageIndicator; for (int i = 0; i < m_ActiveDamageIndicatorCount; ++i) { damageIndicator = m_ActiveDamageIndicators[i]; if (Mathf.Abs(angle - damageIndicator.Angle) < m_IndicatorAngleThreshold) { damageIndicator.DisplayTime = Time.time; m_ActiveDamageIndicators[i] = damageIndicator; return; } } // Add the indicator to the active hit indicators list and enable the component. damageIndicator = GenericObjectPool.Get <DamageIndicator>(); damageIndicator.Initialize(attacker.transform, position, angle, m_StoredIndicators[m_DamageIndicatorIndex]); m_ActiveDamageIndicators[m_ActiveDamageIndicatorCount] = damageIndicator; m_ActiveDamageIndicatorCount++; m_DamageIndicatorIndex = (m_DamageIndicatorIndex + 1) % m_StoredIndicators.Length; // Allow the indicators to move/fade. m_GameObject.SetActive(true); }
/// <summary> /// The view type has changed. /// </summary> /// <param name="activate">Should the current view type be activated?</param> /// <param name="pitch">The pitch of the camera (in degrees).</param> /// <param name="yaw">The yaw of the camera (in degrees).</param> /// <param name="characterRotation">The rotation of the character.</param> public override void ChangeViewType(bool activate, float pitch, float yaw, Quaternion characterRotation) { base.ChangeViewType(activate, pitch, yaw, characterRotation); if (activate) { // Work with the handler to listen for any input events. if (m_Handler != null) { m_StartFreeMovementInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_StartFreeMovementInputEvent.Initialize(ActiveInputEvent.Type.ButtonDown, m_CameraFreeMovementInputName, "OnRPGViewTypeStartFreeMovement"); m_StopFreeMovementInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_StopFreeMovementInputEvent.Initialize(ActiveInputEvent.Type.ButtonUp, m_CameraFreeMovementInputName, "OnRPGViewTypeStopFreeMovement"); m_Handler.RegisterInputEvent(m_StartFreeMovementInputEvent); } EventHandler.RegisterEvent(m_GameObject, "OnRPGViewTypeStartFreeMovement", OnStartFreeMovement); EventHandler.RegisterEvent(m_GameObject, "OnRPGViewTypeStopFreeMovement", OnStopFreeMovement); EventHandler.RegisterEvent(m_Character, "OnRPGMovementTypeStartRotate", OnStartCharacterRotate); EventHandler.RegisterEvent(m_Character, "OnRPGMovementTypeStopRotate", OnStopCharacterRotate); } else { // The ViewType no longer needs to listen for input events when to ViewType is no longer active. if (m_Handler != null) { if (m_FreeMovement) { m_Handler.UnregisterAbilityInputEvent(m_StopFreeMovementInputEvent); } else { m_Handler.UnregisterAbilityInputEvent(m_StartFreeMovementInputEvent); } GenericObjectPool.Return(m_StartFreeMovementInputEvent); GenericObjectPool.Return(m_StopFreeMovementInputEvent); } EventHandler.UnregisterEvent(m_GameObject, "OnRPGViewTypeStartFreeMovement", OnStartFreeMovement); EventHandler.UnregisterEvent(m_GameObject, "OnRPGViewTypeStopFreeMovement", OnStopFreeMovement); EventHandler.UnregisterEvent(m_Character, "OnRPGMovementTypeStartRotate", OnStartCharacterRotate); EventHandler.UnregisterEvent(m_Character, "OnRPGMovementTypeStopRotate", OnStopCharacterRotate); } }
/// <summary> /// The ability has started. /// </summary> protected override void AbilityStarted() { m_ApplyHoldForce = true; m_HoldForce = 0; // If the jump has already been applied then it is a repeated jump. if (m_JumpApplied) { OnAirborneJump(); } else { if (!m_JumpEvent.WaitForAnimationEvent || m_ForceImmediateJump) { Scheduler.ScheduleFixed(m_ForceImmediateJump ? 0 : m_JumpEvent.Duration, ApplyJumpForce); } } if (m_ForceHold > 0) { if (m_Handler != null && InputIndex != -1) { m_HoldInput = GenericObjectPool.Get <ActiveInputEvent>(); m_HoldInput.Initialize(ActiveInputEvent.Type.ButtonUp, InputNames[InputIndex], "OnJumpAbilityReleaseHold"); m_Handler.RegisterInputEvent(m_HoldInput); } EventHandler.RegisterEvent(m_GameObject, "OnJumpAbilityReleaseHold", OnReleaseHold); } // The character can do a repeated jump after the character is already in the air. if (!m_AirborneJumpRegistered) { if (m_Handler != null && InputIndex != -1) { m_AirborneJumpInput = GenericObjectPool.Get <ActiveInputEvent>(); m_AirborneJumpInput.Initialize(ActiveInputEvent.Type.ButtonDown, InputNames[InputIndex], "OnJumpAbilityAirborneJump"); m_Handler.RegisterInputEvent(m_AirborneJumpInput); } EventHandler.RegisterEvent(m_GameObject, "OnJumpAbilityAirborneJump", OnPerformAirborneJump); m_AirborneJumpRegistered = true; } m_ForceImmediateJump = false; base.AbilityStarted(); }
public virtual void DoFixedUpdate() { //TODO moveStep skillStep etc... unitFrameInfo = GenericObjectPool <UnitFrameInfo> .Get(); unitFrameInfo.frame = FrameManager.currentNetworkFrame; unitFrameInfo.canMove = canMove; unitFrameInfo.canRotate = canRotation; if (canMove) { unitFrameInfo.position = position; } if (canRotation) { unitFrameInfo.rotation = rotation; } Debug.Log("DoFixedUpdate..."); }
/// <summary> /// Updates the shader to support a fade. /// </summary> /// <param name="material">The material to update.</param> private void EnableFadeMaterial(Material material) { // If the character's materials change at runtime then the values need to be saved every time fading is enabled. if (!m_CacheCharacterMaterials && !m_OriginalMaterialValuesMap.ContainsKey(material)) { var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>(); originalMaterialValues.Initialize(material, m_ColorID, m_MaterialModeSet.Contains(material)); m_OriginalMaterialValuesMap.Add(material, originalMaterialValues); } if (m_MaterialModeSet.Contains(material)) { material.SetFloat(OriginalMaterialValue.ModeID, 2); material.SetInt(OriginalMaterialValue.SrcBlendID, (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt(OriginalMaterialValue.DstBlendID, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } material.EnableKeyword(OriginalMaterialValue.AlphaBlendString); material.renderQueue = 3000; }
/// <summary> /// The object has taken damage. /// </summary> /// <param name="amount">The amount of damage taken.</param> /// <param name="position">The position of the damage.</param> /// <param name="force">The amount of force applied to the object while taking the damage.</param> /// <param name="attacker">The GameObject that did the damage.</param> /// <param name="hitCollider">The Collider that was hit.</param> private void OnDamage(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider) { // Don't show a hit indicator if the force is 0 or there is no attacker. This prevents damage such as fall damage from showing the damage indicator. if ((!m_AlwaysShowIndicator && force.sqrMagnitude == 0) || attacker == null || m_ActiveDamageIndicatorCount == m_ActiveDamageIndicators.Length) { return; } var direction = Vector3.ProjectOnPlane(m_CharacterTransform.position - ((m_FollowAttacker && m_Character != attacker) ? attacker.transform.position : position), m_CharacterLocomotion.Up); // The hit indicator is shown on a 2D canvas so the y direction should be ignored. direction.y = 0; direction.Normalize(); // Determine the angle of the damage position to determine if a new damage indicator should be shown. var angle = Vector3.Angle(direction, m_CameraTransform.forward) * Mathf.Sign(Vector3.Dot(direction, m_CameraTransform.right)); // Do not show a new damage indicator if the angle is less than a threshold compared to the already displayed indicators. DamageIndicator damageIndicator; for (int i = 0; i < m_ActiveDamageIndicatorCount; ++i) { damageIndicator = m_ActiveDamageIndicators[i]; if (Mathf.Abs(angle - damageIndicator.Angle) < m_IndicatorAngleThreshold) { damageIndicator.DisplayTime = Time.time; m_ActiveDamageIndicators[i] = damageIndicator; return; } } // Add the indicator to the active hit indicators list and enable the component. damageIndicator = GenericObjectPool.Get <DamageIndicator>(); damageIndicator.Initialize(attacker.transform, position, angle, m_StoredIndicators[m_DamageIndicatorIndex]); m_ActiveDamageIndicators[m_ActiveDamageIndicatorCount] = damageIndicator; m_ActiveDamageIndicatorCount++; m_DamageIndicatorIndex = (m_DamageIndicatorIndex + 1) % m_StoredIndicators.Length; // Allow the indicators to move/fade. m_GameObject.SetActive(true); }
private void OnReceived(object sender, ReceiveEventArgs e) { lock (m_MessageLocker) { ServerLogMessage message = m_MessagePool.Get(); int id = BitConverter.ToInt32(e.bytes, 0); byte[] contentBytes = new byte[0]; if (e.bytes.Length > sizeof(int)) { contentBytes = new byte[e.bytes.Length - sizeof(int)]; Array.Copy(e.bytes, sizeof(int), contentBytes, 0, contentBytes.Length); } message.ID = id; message.Client = e.client; message.Message = contentBytes; m_ReceivedMessages.Add(message); } }
/// <summary> /// The view type has changed. /// </summary> /// <param name="activate">Should the current view type be activated?</param> /// <param name="pitch">The pitch of the camera (in degrees).</param> /// <param name="yaw">The yaw of the camera (in degrees).</param> /// <param name="characterRotation">The rotation of the character.</param> public override void ChangeViewType(bool activate, float pitch, float yaw, Quaternion characterRotation) { if (activate) { m_Pitch = pitch; m_Yaw = yaw; m_CharacterRotation = characterRotation; if (m_CharacterLocomotion.Platform != null) { UpdatePlatformRotationOffset(m_CharacterLocomotion.Platform); } if (m_Camera.fieldOfView != m_FieldOfView) { m_FieldOfViewChangeTime = Time.time + m_FieldOfViewDamping / m_CharacterLocomotion.TimeScale; } if (m_StepZoomSensitivity > 0) { if (m_Handler != null) { m_StepZoomInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_StepZoomInputEvent.Initialize(ActiveInputEvent.Type.Axis, m_StepZoomInputName, "OnThirdPersonViewTypeStepZoom"); m_Handler.RegisterInputEvent(m_StepZoomInputEvent); } EventHandler.RegisterEvent <float>(m_GameObject, "OnThirdPersonViewTypeStepZoom", OnStepZoom); } } else { if (m_StepZoomSensitivity > 0) { if (m_Handler != null) { m_StepZoomInputEvent = GenericObjectPool.Get <ActiveInputEvent>(); m_Handler.UnregisterAbilityInputEvent(m_StepZoomInputEvent); GenericObjectPool.Return(m_StepZoomInputEvent); } EventHandler.UnregisterEvent <float>(m_GameObject, "OnThirdPersonViewTypeStepZoom", OnStepZoom); } } }
/// <summary> /// Perform the impact action. /// </summary> /// <param name="castID">The ID of the cast.</param> /// <param name="source">The object that caused the cast.</param> /// <param name="target">The object that was hit by the cast.</param> /// <param name="hit">The raycast that caused the impact.</param> protected override void ImpactInternal(uint castID, GameObject source, GameObject target, RaycastHit hit) { var damageTarget = DamageUtility.GetDamageTarget(target); if (damageTarget == null || !damageTarget.IsAlive()) { if (m_InterruptImpactOnNullHealth) { m_MagicItem.InterruptImpact(); } return; } var pooledDamageData = GenericObjectPool.Get <DamageData>(); pooledDamageData.SetDamage(m_Amount, source.transform.position, (source.transform.position - target.transform.position), m_ForceMagnitude, m_ForceFrames, 0, source, this, null); if (m_DamageProcessor == null) { m_DamageProcessor = DamageProcessor.Default; } m_DamageProcessor.Process(damageTarget, pooledDamageData); GenericObjectPool.Return(pooledDamageData); }
/// <summary> /// The object has collided with another object. /// </summary> /// <param name="hit">The RaycastHit of the object. Can be null.</param> protected override void OnCollision(RaycastHit?hit) { base.OnCollision(hit); var forceDestruct = false; if (m_CollisionMode == CollisionMode.Collide) { // When there is a collision the object should move to the position that was hit so if it's not destroyed then it looks like it // is penetrating the hit object. if (hit != null && hit.HasValue && m_Collider != null) { var closestPoint = m_Collider.ClosestPoint(hit.Value.point); m_Transform.position += (hit.Value.point - closestPoint); // Only set the parent to the hit transform on uniform objects to prevent stretching. if (MathUtility.IsUniform(hit.Value.transform.localScale)) { // The parent layer must be within the sticky layer mask. if (MathUtility.InLayerMask(hit.Value.transform.gameObject.layer, m_StickyLayers)) { m_Transform.parent = hit.Value.transform; // If the destructible sticks to a character then the object should be added as a sub collider so collisions will be ignored. m_StickyCharacterLocomotion = hit.Value.transform.gameObject.GetCachedComponent <UltimateCharacterLocomotion>(); if (m_StickyCharacterLocomotion != null) { m_StickyCharacterLocomotion.AddIgnoredCollider(m_Collider); } } else { forceDestruct = true; } } } if (m_TrailRenderer != null) { m_TrailRenderer.enabled = false; } } var destructionDelay = m_DestructionDelay; if (m_ParticleSystem != null && m_WaitForParticleStop) { destructionDelay = m_ParticleSystem.main.duration; m_ParticleSystem.Stop(true, ParticleSystemStopBehavior.StopEmitting); Stop(); } // The object may not have been initialized before it collides. if (m_GameObject == null) { InitializeComponentReferences(); } if (hit != null && hit.HasValue) { var hitValue = hit.Value; var hitGameObject = hitValue.collider.gameObject; // The shield can absorb some (or none) of the damage from the destructible. var damageAmount = m_DamageAmount; #if ULTIMATE_CHARACTER_CONTROLLER_MELEE ShieldCollider shieldCollider; if ((shieldCollider = hitGameObject.GetCachedComponent <ShieldCollider>()) != null) { damageAmount = shieldCollider.Shield.Damage(this, damageAmount); } #endif // Allow a custom event to be received. EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, object, Collider>(hitGameObject, "OnObjectImpact", damageAmount, hitValue.point, m_Velocity.normalized * m_ImpactForce, m_Originator, this, hitValue.collider); if (m_OnImpactEvent != null) { m_OnImpactEvent.Invoke(damageAmount, hitValue.point, m_Velocity.normalized * m_ImpactForce, m_Originator); } // If the shield didn't absorb all of the damage then it should be applied to the character. if (damageAmount > 0) { var damageTarget = DamageUtility.GetDamageTarget(hitGameObject); if (damageTarget != null) { var pooledDamageData = GenericObjectPool.Get <DamageData>(); pooledDamageData.SetDamage(this, damageAmount, hitValue.point, -hitValue.normal, m_ImpactForce, m_ImpactForceFrames, 0, hitValue.collider); var damageProcessorModule = hitGameObject.GetCachedComponent <DamageProcessorModule>(); if (damageProcessorModule != null) { damageProcessorModule.ProcessDamage(m_DamageProcessor, damageTarget, pooledDamageData); } else { if (m_DamageProcessor == null) { m_DamageProcessor = DamageProcessor.Default; } m_DamageProcessor.Process(damageTarget, pooledDamageData); } GenericObjectPool.Return(pooledDamageData); } else if (m_ImpactForce > 0) { // If the damage target exists it will apply a force to the rigidbody in addition to procesing the damage. Otherwise just apply the force to the rigidbody. var collisionRigidbody = hitGameObject.GetCachedParentComponent <Rigidbody>(); if (collisionRigidbody != null && !collisionRigidbody.isKinematic) { collisionRigidbody.AddForceAtPosition(m_ImpactForce * MathUtility.RigidbodyForceMultiplier * -hitValue.normal, hitValue.point); } else { var forceObject = hitGameObject.GetCachedParentComponent <IForceObject>(); if (forceObject != null) { forceObject.AddForce(m_Transform.forward * m_ImpactForce); } } } } // An optional state can be activated on the hit object. if (!string.IsNullOrEmpty(m_ImpactStateName)) { StateManager.SetState(hitGameObject, m_ImpactStateName, true); // If the timer isn't -1 then the state should be disabled after a specified amount of time. If it is -1 then the state // will have to be disabled manually. if (m_ImpactStateDisableTimer != -1) { StateManager.DeactivateStateTimer(hitGameObject, m_ImpactStateName, m_ImpactStateDisableTimer); } } } // The object can destroy itself after a small delay. if (m_DestroyEvent == null && (m_DestroyOnCollision || forceDestruct || destructionDelay > 0)) { m_DestroyEvent = SchedulerBase.ScheduleFixed(destructionDelay, Destruct, hit); } }
/// <summary> /// Do the explosion. /// </summary> /// <param name="damageAmount">The amount of damage to apply to the hit objects.</param> /// <param name="impactForce">The amount of force to apply to the hit object.</param> /// <param name="impactForceFrames">The number of frames to add the force to.</param> /// <param name="originator">The originator of the object.</param> public void Explode(float damageAmount, float impactForce, int impactForceFrames, GameObject originator) { Rigidbody colliderRigidbody = null; IForceObject forceObject = null; var hitCount = Physics.OverlapSphereNonAlloc(m_Transform.position, m_Radius, m_CollidersHit, m_ImpactLayers, QueryTriggerInteraction.Ignore); #if UNITY_EDITOR if (hitCount == m_MaxCollisionCount) { Debug.LogWarning("Warning: The maximum number of colliders have been hit by " + m_GameObject.name + ". Consider increasing the Max Collision Count value."); } #endif for (int i = 0; i < hitCount; ++i) { // A GameObject can contain multiple colliders. Prevent the explosion from occurring on the same GameObject multiple times. if (m_ObjectExplosions.Contains(m_CollidersHit[i].gameObject)) { continue; } m_ObjectExplosions.Add(m_CollidersHit[i].gameObject); // The base character GameObject should only be checked once. if ((forceObject = m_CollidersHit[i].gameObject.GetCachedParentComponent <IForceObject>()) != null) { if (m_ObjectExplosions.Contains(forceObject)) { continue; } m_ObjectExplosions.Add(forceObject); } // OverlapSphere can return objects that are in a different room. Perform a cast to ensure the object is within the explosion range. if (m_LineOfSight) { // Add a slight vertical offset to prevent a floor collider from getting in the way of the cast. var position = m_Transform.TransformPoint(0, 0.1f, 0); var direction = m_CollidersHit[i].transform.position - position; if (Physics.Raycast(position - direction.normalized * 0.1f, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) && !(m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform) #if FIRST_PERSON_CONTROLLER // The cast should not hit any colliders who are a child of the camera. || m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() != null #endif )) { // If the collider is part of a character then ensure the head can't be hit. var parentAnimator = m_CollidersHit[i].transform.gameObject.GetCachedParentComponent <Animator>(); if (parentAnimator != null && parentAnimator.isHuman) { var head = parentAnimator.GetBoneTransform(HumanBodyBones.Head); direction = head.position - position; if (Physics.Raycast(position, direction, out m_RaycastHit, direction.magnitude, m_ImpactLayers, QueryTriggerInteraction.Ignore) && !m_RaycastHit.transform.IsChildOf(m_CollidersHit[i].transform) && !m_CollidersHit[i].transform.IsChildOf(m_RaycastHit.transform) && m_RaycastHit.transform.IsChildOf(m_Transform) #if FIRST_PERSON_CONTROLLER // The cast should not hit any colliders who are a child of the camera. && m_RaycastHit.transform.gameObject.GetCachedParentComponent <FirstPersonController.Character.FirstPersonObjects>() == null #endif ) { continue; } } else { continue; } } } // The shield can absorb some (or none) of the damage from the explosion. var hitDamageAmount = damageAmount; #if ULTIMATE_CHARACTER_CONTROLLER_MELEE ShieldCollider shieldCollider; if ((shieldCollider = m_CollidersHit[i].transform.gameObject.GetCachedComponent <ShieldCollider>()) != null) { hitDamageAmount = shieldCollider.Shield.Damage(this, hitDamageAmount); } #endif // ClosestPoint only works with a subset of collider types. Vector3 closestPoint; if (m_CollidersHit[i] is BoxCollider || m_CollidersHit[i] is SphereCollider || m_CollidersHit[i] is CapsuleCollider || (m_CollidersHit[i] is MeshCollider && (m_CollidersHit[i] as MeshCollider).convex)) { closestPoint = m_CollidersHit[i].ClosestPoint(m_Transform.position); } else { closestPoint = m_CollidersHit[i].ClosestPointOnBounds(m_Transform.position); } var hitDirection = closestPoint - m_Transform.position; // Allow a custom event to be received. EventHandler.ExecuteEvent <float, Vector3, Vector3, GameObject, object, Collider>(m_CollidersHit[i].transform.gameObject, "OnObjectImpact", hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator, this, m_CollidersHit[i]); if (m_OnImpactEvent != null) { m_OnImpactEvent.Invoke(hitDamageAmount, closestPoint, hitDirection * m_ImpactForce, originator); } // If the shield didn't absorb all of the damage then it should be applied to the character. if (hitDamageAmount > 0) { var damageTarget = DamageUtility.GetDamageTarget(m_CollidersHit[i].gameObject); if (damageTarget != null) { // If the Damage Target exists it will apply an explosive force to the character/character in addition to deducting the health. // Otherwise just apply the force to the character/rigidbody. var pooledDamageData = GenericObjectPool.Get <DamageData>(); var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f); pooledDamageData.SetDamage(hitDamageAmount * damageModifier, m_Transform.position, hitDirection.normalized, impactForce * damageModifier, impactForceFrames, m_Radius, originator, this, null); if (m_DamageProcessor == null) { m_DamageProcessor = DamageProcessor.Default; } m_DamageProcessor.Process(damageTarget, pooledDamageData); GenericObjectPool.Return(pooledDamageData); } else if (forceObject != null) { var damageModifier = Mathf.Max(1 - (hitDirection.magnitude / m_Radius), 0.01f); forceObject.AddForce(impactForce * damageModifier * hitDirection.normalized); } else if ((colliderRigidbody = m_CollidersHit[i].gameObject.GetCachedComponent <Rigidbody>()) != null) { colliderRigidbody.AddExplosionForce(impactForce * MathUtility.RigidbodyForceMultiplier, m_Transform.position, m_Radius); } } } m_ObjectExplosions.Clear(); // An audio clip can play when the object explodes. m_ExplosionAudioClipSet.PlayAudioClip(m_GameObject); m_DestructionEvent = SchedulerBase.Schedule(m_Lifespan, Destroy); }
private void RecalculateNormals(Mesh mesh, float angle, int[] triangles, Vector3[] vertices, bool instant = false) { if (triangles == null) { if (meshInfoCache == null) { meshInfoCache = new Dictionary <Mesh, KeyValuePair <int[], Vector3[]> >(); } if (meshInfoCache.ContainsKey(mesh)) { triangles = meshInfoCache[mesh].Key; vertices = meshInfoCache[mesh].Value; } else { triangles = mesh.GetTriangles(0); vertices = mesh.vertices; meshInfoCache.Add(mesh, new KeyValuePair <int[], Vector3[]>(triangles, vertices)); } } var triNormals = AllocatedArray <Vector3> .Get(triangles.Length / 3); var normals = AllocatedArray <Vector3> .Get(vertices.Length); angle = angle * Mathf.Deg2Rad; var dictionary = PooledDictionary <Vector3, VertexEntry> .Get(vertices.Length, VectorComparer); //Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; //VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(vertices[i1], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i1], entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(vertices[i2], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i2], entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(vertices[i3], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i3], entry); } entry.Add(i3, triIndex); } foreach (var kvp in dictionary) { var value = kvp.Value; for (var i = 0; i < value.Count; ++i) { var sum = new Vector3(); for (var j = 0; j < value.Count; ++j) { if (value.VertexIndex[i] == value.VertexIndex[j]) { sum += triNormals[value.TriangleIndex[j]]; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { sum += triNormals[value.TriangleIndex[j]]; } } } normals[value.VertexIndex[i]] = sum.normalized; } value.Clear(); GenericObjectPool <VertexEntry> .Return(value); } dictionary.ReturnToPool(); if (instant == false) { if (mainThreadActions == null) { mainThreadActions = new Queue <System.Action>(); } mainThreadActions.Enqueue(() => { if (mesh) { mesh.normals = normals; } AllocatedArray <Vector3> .Return(normals, false); }); } else { mesh.normals = normals; AllocatedArray <Vector3> .Return(normals, false); } }
internal static List <IQuadObject> GetObjectList() { return(sm_ObjectListPool.Get()); }
internal static List <QuadNode> GetNodeList() { return(sm_NodeListPool.Get()); }
/// <summary> /// Attaches the component to the specified character. /// </summary> /// <param name="character">The handler to attach the camera to.</param> protected virtual void OnAttachCharacter(GameObject character) { enabled = character != null && !m_CameraController.ActiveViewType.FirstPersonPerspective; // Disable the fade on the previous active character. if (m_CharacterFade) { if (m_Character != null && m_Character != character) { DisableFades(); // Clear the previous mappings. if (m_CharacterFadeMaterials != null) { if (m_CacheCharacterMaterials) { for (int i = 0; i < m_CharacterFadeMaterials.Length; ++i) { if (!m_OriginalMaterialValuesMap.ContainsKey(m_CharacterFadeMaterials[i])) { continue; } GenericObjectPool.Return(m_OriginalMaterialValuesMap[m_CharacterFadeMaterials[i]]); m_OriginalMaterialValuesMap.Remove(m_CharacterFadeMaterials[i]); } } m_CharacterFadeMaterials = null; } m_OriginalMaterialValuesMap.Clear(); EventHandler.UnregisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives); EventHandler.UnregisterEvent <bool, bool>(m_Character, "OnCharacterIndependentFade", OnIndependentFade); EventHandler.UnregisterEvent <Item>(m_Character, "OnInventoryAddItem", OnAddItem); EventHandler.UnregisterEvent <GameObject, bool>(m_Character, "OnShootableWeaponShowProjectile", OnShowProjectile); EventHandler.UnregisterEvent(m_Character, "OnRespawn", OnRespawn); } } m_Character = character; if (m_Character != null) { m_CharacterTransform = m_Character.transform; m_CharacterLocomotion = m_Character.GetCachedComponent <UltimateCharacterLocomotion>(); m_CharacterLayerManager = m_Character.GetCachedComponent <CharacterLayerManager>(); if (m_CharacterFade) { // Determine the number of renderers that will be faded so their materials can be cached. m_RegisteredMaterial.Clear(); var count = 0; var renderers = m_Character.GetComponentsInChildren <Renderer>(true); for (int i = 0; i < renderers.Length; ++i) { // The renderer fade can be ignored. if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null) { continue; } var materials = renderers[i].materials; for (int j = 0; j < materials.Length; ++j) { if (materials[j].HasProperty(m_ColorID)) { count++; } } } if (count > 0) { if (m_CharacterFadeMaterials == null) { m_CharacterFadeMaterials = new Material[count]; } else if (m_CharacterFadeMaterials.Length != count) { if (m_CacheCharacterMaterials) { // The mapping may exist from a previous character. for (int i = 0; i < m_CharacterFadeMaterials.Length; ++i) { GenericObjectPool.Return(m_OriginalMaterialValuesMap[m_CharacterFadeMaterials[i]]); m_OriginalMaterialValuesMap.Remove(m_CharacterFadeMaterials[i]); } } System.Array.Resize(ref m_CharacterFadeMaterials, count); } // Cache a reference to all of the faded materials. m_CharacterFadeMaterialsCount = 0; for (int i = 0; i < renderers.Length; ++i) { // The renderer fade can be ignored. if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null) { continue; } var materials = renderers[i].materials; for (int j = 0; j < materials.Length; ++j) { if (m_RegisteredMaterial.Contains(materials[j])) { continue; } if (materials[j].HasProperty(m_ColorID)) { if (materials[j].HasProperty(OriginalMaterialValue.ModeID)) { m_MaterialModeSet.Add(materials[j]); } m_CharacterFadeMaterials[m_CharacterFadeMaterialsCount] = materials[j]; m_RegisteredMaterial.Add(materials[j]); m_CharacterFadeMaterialsCount++; if (m_CacheCharacterMaterials) { var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>(); originalMaterialValues.Initialize(materials[j], m_ColorID, m_MaterialModeSet.Contains(materials[j])); m_OriginalMaterialValuesMap.Add(materials[j], originalMaterialValues); } } } } } EventHandler.RegisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives); EventHandler.RegisterEvent <Item>(m_Character, "OnInventoryAddItem", OnAddItem); EventHandler.RegisterEvent <GameObject, bool>(m_Character, "OnShootableWeaponShowProjectile", OnShowProjectile); EventHandler.RegisterEvent <bool, bool>(m_Character, "OnCharacterIndependentFade", OnIndependentFade); EventHandler.RegisterEvent(m_Character, "OnRespawn", OnRespawn); } // Fade the obstructing objects immediately after the character has been assigned. if (m_ObstructingObjectsFade) { FadeObstructingObjects(true); } } }
/// <summary> /// Fade any objects that get in the way between the character and the camera. /// </summary> /// <param name="immediateFade">Should the fade material be changed immediately?</param> private void FadeObstructingObjects(bool immediateFade) { if (!m_ObstructingObjectsFade) { return; } // Disable any obstructing colliders so the sphere cast can detect which objects are obstructing. for (int i = 0; i < m_ObstructingCollidersCount; ++i) { m_ObstructingColliders[i].enabled = true; } m_ObstructingCollidersCount = 0; var characterPosition = m_CharacterTransform.TransformPoint(m_TransformOffset); var direction = (m_Transform.position - characterPosition); var start = characterPosition - direction.normalized * m_CollisionRadius; m_CharacterLocomotion.EnableColliderCollisionLayer(false); // Fire a sphere to prevent the camera from colliding with other objects. var hitCount = Physics.SphereCastNonAlloc(start, m_CollisionRadius, direction.normalized, m_RaycastsHit, direction.magnitude, m_CharacterLayerManager.IgnoreInvisibleCharacterWaterLayers, QueryTriggerInteraction.Ignore); m_CharacterLocomotion.EnableColliderCollisionLayer(true); m_ObstructionHitSet.Clear(); if (hitCount > 0) { // Loop through all of the hit colliders. For any collider that has been hit get all of the renderers. The materials that are used on the // renderers then need to be checked to determine if they can be faded. If the material can be faded place it in a set which will then // be checked in the next block to determine if the material should be faded. for (int i = 0; i < hitCount; ++i) { var renderers = m_RaycastsHit[i].transform.gameObject.GetCachedComponents <Renderer>(); var obstructing = false; for (int j = 0; j < renderers.Length; ++j) { var materials = renderers[j].materials; for (int k = 0; k < materials.Length; ++k) { if (!m_CanObstructionFade.TryGetValue(materials[k], out var canFade)) { // Objects can fade if they have the color property and can be transparent. canFade = materials[k].HasProperty(m_ColorID) && (m_AutoSetMode || materials[k].renderQueue >= (int)UnityEngine.Rendering.RenderQueue.Transparent); m_CanObstructionFade.Add(materials[k], canFade); } if (canFade) { var material = materials[k]; // Any material contained within the hit set should be faded. m_ObstructionHitSet.Add(material); if (m_DisableCollider && !obstructing) { obstructing = CanMaterialFade(material); } // The same material may be applied to multiple renderers. if (!m_OriginalMaterialValuesMap.ContainsKey(material)) { // Don't set the mode automatically just because it has the property - not all objects in the environment should fade. if (m_AutoSetMode && material.HasProperty(OriginalMaterialValue.ModeID)) { m_MaterialModeSet.Add(material); } var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>(); originalMaterialValues.Initialize(material, m_ColorID, m_MaterialModeSet.Contains(material)); m_OriginalMaterialValuesMap.Add(material, originalMaterialValues); m_ObstructingMaterials[m_ObstructingMaterialsCount] = material; m_ObstructingMaterialsCount++; EnableFadeMaterial(material); } } } } // If the object is faded then the collider has the option of being disabled to prevent it from causing collisions. if (m_DisableCollider && obstructing) { m_RaycastsHit[i].collider.enabled = false; m_ObstructingColliders[m_ObstructingCollidersCount] = m_RaycastsHit[i].collider; m_ObstructingCollidersCount++; } } } // Once the obstructing objects have been found they should be faded. Note that this can cause a lot of overdraw so the FadeObject method can be // overridden to provide a custom effect such as the one described on https://madewith.unity.com/stories/dissolving-the-world-part-1. for (int i = m_ObstructingMaterialsCount - 1; i >= 0; --i) { if (!FadeMaterial(m_ObstructingMaterials[i], m_ObstructionHitSet.Contains(m_ObstructingMaterials[i]), immediateFade)) { RemoveObstructingMaterial(i); } } }
public static ShapeList New() { return(Pool.Get()); }
public static EventDispatcher GetDispatcher() { return(sm_DispatcherPool.Get()); }
/// <summary> /// Initializes the materials on the renderers for character fade. /// </summary> /// <param name="renderers">The renderers that should be initilaizes for character fade.</param> private void InitializeCharacterFadeRenderers(Renderer[] renderers) { var count = 0; for (int i = 0; i < renderers.Length; ++i) { // The renderer fade can be ignored. if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null) { continue; } var materials = renderers[i].materials; for (int j = 0; j < materials.Length; ++j) { if (!m_RegisteredMaterial.Contains(materials[j]) && materials[j].HasProperty(m_ColorID)) { count++; } } } if (count > 0) { var totalCount = m_CharacterFadeMaterialsCount + count; if (m_CharacterFadeMaterials == null) { m_CharacterFadeMaterials = new Material[totalCount]; } else if (totalCount >= m_CharacterFadeMaterials.Length) { System.Array.Resize(ref m_CharacterFadeMaterials, totalCount); } // Cache a reference to all of the faded materials. for (int i = 0; i < renderers.Length; ++i) { // The renderer fade can be ignored. if (renderers[i].gameObject.GetCachedComponent <IgnoreFadeIdentifier>() != null) { continue; } var materials = renderers[i].materials; for (int j = 0; j < materials.Length; ++j) { if (!m_RegisteredMaterial.Contains(materials[j]) && materials[j].HasProperty(m_ColorID)) { if (materials[j].HasProperty(OriginalMaterialValue.ModeID)) { m_MaterialModeSet.Add(materials[j]); } m_CharacterFadeMaterials[m_CharacterFadeMaterialsCount] = materials[j]; m_RegisteredMaterial.Add(materials[j]); m_CharacterFadeMaterialsCount++; if (m_CacheCharacterMaterials && !m_OriginalMaterialValuesMap.ContainsKey(materials[j])) { var originalMaterialValues = GenericObjectPool.Get <OriginalMaterialValue>(); originalMaterialValues.Initialize(materials[j], m_ColorID, m_MaterialModeSet.Contains(materials[j])); m_OriginalMaterialValuesMap.Add(materials[j], originalMaterialValues); } } } } } }