Ejemplo n.º 1
0
 private void OnTriggerComm(Collider other, SkillTriggerStyle skillTriggerStyle)
 {
     if (other.tag == "Monster" && skillProperties != null && skillProperties.Length > 0)
     {
         for (int i = 0; i < skillProperties.Length; i++)
         {
             if (skillProperties[i].skillTriggerStyle == skillTriggerStyle)
             {
                 skillProperties[i].TriggerEnter(other.GetComponent <Unit>());
             }
         }
     }
 }
        /// <summary>
        /// Perform a skill in response to some input trigger. This is the common method to which all input-driven skill plays funnel.
        /// </summary>
        /// <param name="actionType">The action you want to play. Note that "Skill1" may be overriden contextually depending on the target.</param>
        /// <param name="triggerStyle">What sort of input triggered this skill?</param>
        /// <param name="targetId">(optional) Pass in a specific networkID to target for this action</param>
        private void PerformSkill(ActionType actionType, SkillTriggerStyle triggerStyle, ulong targetId = 0)
        {
            Transform hitTransform = null;

            if (targetId != 0)
            {
                // if a targetId is given, try to find the object
                NetworkObject targetNetObj;
                if (NetworkSpawnManager.SpawnedObjects.TryGetValue(targetId, out targetNetObj))
                {
                    hitTransform = targetNetObj.transform;
                }
            }
            else
            {
                // otherwise try to find an object under the input position
                int numHits = 0;
                if (triggerStyle == SkillTriggerStyle.MouseClick)
                {
                    var ray = m_MainCamera.ScreenPointToRay(Input.mousePosition);
                    numHits = Physics.RaycastNonAlloc(ray, k_CachedHit, k_MouseInputRaycastDistance, k_ActionLayerMask);
                }

                int networkedHitIndex = -1;
                for (int i = 0; i < numHits; i++)
                {
                    if (k_CachedHit[i].transform.GetComponent <NetworkObject>())
                    {
                        networkedHitIndex = i;
                        break;
                    }
                }

                hitTransform = networkedHitIndex >= 0 ? k_CachedHit[networkedHitIndex].transform : null;
            }

            if (GetActionRequestForTarget(hitTransform, actionType, triggerStyle, out ActionRequestData playerAction))
            {
                //Don't trigger our move logic for another 500ms. This protects us from moving  just because we clicked on them to target them.
                m_LastSentMove = Time.time + k_TargetMoveTimeout;

                m_NetworkCharacter.RecvDoActionServerRPC(playerAction);
            }
            else if (actionType != ActionType.GeneralTarget)
            {
                // clicked on nothing... perform a "miss" attack on the spot they clicked on
                var data = new ActionRequestData();
                PopulateSkillRequest(k_CachedHit[0].point, actionType, ref data);
                m_NetworkCharacter.RecvDoActionServerRPC(data);
            }
        }
        /// <summary>
        /// Request an action be performed. This will occur on the next FixedUpdate.
        /// </summary>
        /// <param name="action">the action you'd like to perform. </param>
        /// <param name="triggerStyle">What input style triggered this action.</param>
        public void RequestAction(ActionType action, SkillTriggerStyle triggerStyle, ulong targetId = 0)
        {
            // do not populate an action request unless said action is valid
            if (action == ActionType.None)
            {
                return;
            }

            Assert.IsTrue(GameDataSource.Instance.ActionDataByType.ContainsKey(action),
                          $"Action {action} must be part of ActionData dictionary!");

            if (m_ActionRequestCount < m_ActionRequests.Length)
            {
                m_ActionRequests[m_ActionRequestCount].RequestedAction = action;
                m_ActionRequests[m_ActionRequestCount].TriggerStyle    = triggerStyle;
                m_ActionRequests[m_ActionRequestCount].TargetId        = targetId;
                m_ActionRequestCount++;
            }
        }
        /// <summary>
        /// When you right-click on something you will want to do contextually different things. For example you might attack an enemy,
        /// but revive a friend. You might also decide to do nothing (e.g. right-clicking on a friend who hasn't FAINTED).
        /// </summary>
        /// <param name="hit">The Transform of the entity we clicked on, or null if none.</param>
        /// <param name="actionType">The Action to build for</param>
        /// <param name="triggerStyle">How did this skill play get triggered? Mouse, Keyboard, UI etc.</param>
        /// <param name="resultData">Out parameter that will be filled with the resulting action, if any.</param>
        /// <returns>true if we should play an action, false otherwise. </returns>
        private bool GetActionRequestForTarget(Transform hit, ActionType actionType, SkillTriggerStyle triggerStyle, out ActionRequestData resultData)
        {
            resultData = new ActionRequestData();

            var targetNetObj = hit != null?hit.GetComponent <NetworkObject>() : null;

            //if we can't get our target from the submitted hit transform, get it from our stateful target in our NetworkCharacterState.
            if (!targetNetObj && actionType != ActionType.GeneralTarget)
            {
                ulong targetId = m_NetworkCharacter.TargetId.Value;
                NetworkSpawnManager.SpawnedObjects.TryGetValue(targetId, out targetNetObj);
            }

            //sanity check that this is indeed a valid target.
            if (targetNetObj == null || !ActionUtils.IsValidTarget(targetNetObj.NetworkObjectId))
            {
                return(false);
            }

            var targetNetState = targetNetObj.GetComponent <NetworkCharacterState>();

            if (targetNetState != null)
            {
                //Skill1 may be contextually overridden if it was generated from a mouse-click.
                if (actionType == CharacterData.Skill1 && triggerStyle == SkillTriggerStyle.MouseClick)
                {
                    if (!targetNetState.IsNpc && targetNetState.NetworkLifeState.Value == LifeState.Fainted)
                    {
                        //right-clicked on a downed ally--change the skill play to Revive.
                        actionType = ActionType.GeneralRevive;
                    }
                }
            }

            // record our target in case this action uses that info (non-targeted attacks will ignore this)
            resultData.ActionTypeEnum = actionType;
            resultData.TargetIds      = new ulong[] { targetNetObj.NetworkObjectId };
            PopulateSkillRequest(targetNetObj.transform.position, actionType, ref resultData);
            return(true);
        }