예제 #1
0
    public void CloneTo(Unit unit)
    {
        base.CloneTo(unit as UnitBase);
        //copy character controller
        CharacterController cc = unit.gameObject.AddComponent <CharacterController> ();

        cc.center = this.GetComponent <CharacterController> ().center;
        cc.radius = this.GetComponent <CharacterController> ().radius;
        cc.height = this.GetComponent <CharacterController> ().height;

        //copy animation
        foreach (AnimationState ani in this.animation)
        {
            AnimationClip clip = ani.clip;
            unit.animation.AddClip(clip, ani.name);
        }
        //copy idledata
        foreach (IdleData idleData in this.IdleData)
        {
            IdleData clone = idleData.GetClone();
            unit.IdleData = Util.AddToArray <IdleData> (clone, unit.IdleData);
        }
        //copy movedata
        foreach (MoveData moveData in this.MoveData)
        {
            MoveData clone = moveData.GetClone();
            unit.MoveData = Util.AddToArray <MoveData> (clone, unit.MoveData);
        }
        //copy attackdata
        foreach (AttackData attackData in this.AttackData)
        {
            AttackData clone = attackData.GetClone();
            unit.AttackData = Util.AddToArray <AttackData> (clone, unit.AttackData);
        }
        //copy ReceiveDamageData
        foreach (ReceiveDamageData receiveDamageData in this.ReceiveDamageData)
        {
            ReceiveDamageData clone = receiveDamageData.GetClone();
            unit.ReceiveDamageData = Util.AddToArray <ReceiveDamageData> (clone, unit.ReceiveDamageData);
        }
        //copy DeathData
        foreach (DeathData deathData in this.DeathData)
        {
            DeathData clone = deathData.GetClone();
            unit.DeathData = Util.AddToArray <DeathData> (clone, unit.DeathData);
        }
        //copy AudioData
        foreach (AudioData audioData in this.AudioData)
        {
            AudioData clone = audioData.GetClone();
            unit.AudioData = Util.AddToArray <AudioData> (clone, unit.AudioData);
        }
        //copy DecalData
        foreach (DecalData decalData in this.DecalData)
        {
            DecalData clone = decalData.GetClone();
            unit.DecalData = Util.AddToArray <DecalData> (clone, unit.DecalData);
        }
    }
예제 #2
0
    public IdleData GetClone()
    {
        IdleData clone = new IdleData();

        base.CloneBasic(clone);
        clone.KeepFacingTarget = this.KeepFacingTarget;
        clone.SmoothRotate     = this.SmoothRotate;
        clone.RotateDataName   = this.RotateDataName;
        return(clone);
    }
예제 #3
0
 public IdleData GetClone()
 {
     IdleData clone = new IdleData();
     base.CloneBasic(clone);
     clone.KeepFacingTarget = this.KeepFacingTarget;
     clone.SmoothRotate = this.SmoothRotate;
     clone.RotateDataName = this.RotateDataName;
     return clone;
 }
예제 #4
0
        // ReSharper disable once MemberCanBePrivate.Global
        // public constructor required for akka
        public CompetitionSlot(
            IActorRef competitorSource
            , ICompetitionActorPropsFactory competitionActorPropsFactory)
        {
            StartWith(CompetitionSlotState.Idle, IdleData.FromReason(IdleReason.JustStarted));

            When(CompetitionSlotState.Idle, state =>
            {
                if (state.FsmEvent is RunCompetition runCompetition)
                {
                    return(GoToLobby(competitorSource));
                }

                return(null);
            });

            When(CompetitionSlotState.Lobby, state =>
            {
                if (state.FsmEvent is TypedAskResult <RoomCreated> agentsOrderCompleted)
                {
                    var competitorActorProps = competitionActorPropsFactory.Build(agentsOrderCompleted.Answer.ActorPlayers);
                    var competitorActor      = Context.ActorOf(competitorActorProps);

                    return(GoTo(CompetitionSlotState.Game)
                           .Using(
                               new ActiveGameData(
                                   competitorActor
                                   , agentsOrderCompleted.Answer.ActorPlayers)));
                }

                if (state.FsmEvent is NotEnoughPlayers)
                {
                    return(GoTo(CompetitionSlotState.Idle)
                           .Using(IdleData.FromReason(IdleReason.NotEnoughPlayers)));
                }

                return(null);
            });

            When(CompetitionSlotState.Game, state =>
            {
                if (state.FsmEvent is LobbyGameTerminated competitionResult)
                {
                    return(GoToLobby(competitorSource));
                }

                return(null);
            });


            OnTransition((initialState, nextState) =>
            {
                _logger.Info("Changed state from {0} to {1}", initialState, nextState);
                switch (initialState)
                {
                case CompetitionSlotState.Lobby when StateData is QueryData queryStateData:
                    Context.Stop(queryStateData.Query);
                    break;

                case CompetitionSlotState.Game when StateData is ActiveGameData activeGameData:
                    Context.Stop(activeGameData.Game);
                    break;

                case CompetitionSlotState.Idle:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(initialState), initialState, null);
                }

                switch (nextState)
                {
                case CompetitionSlotState.Game when NextStateData is ActiveGameData nextStateGameData:
                    Context.WatchWith(nextStateGameData.Game, new LobbyGameTerminated(nextStateGameData.Game));
                    nextStateGameData.Game.Tell(new Competition.RunCompetitionMessage());
                    break;

                case CompetitionSlotState.Idle when NextStateData is IdleData idleData:
                    Context.System.Scheduler.ScheduleTellOnce(
                        idleData.RestartAfter,
                        Self,
                        RunCompetition.Instance,
                        Self);
                    break;

                case CompetitionSlotState.Lobby:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(nextState), nextState, null);
                }
            });


            Initialize();
        }
예제 #5
0
 public IdleTask(IdleData dataPacket)
 {
     _general = dataPacket.General;
 }
예제 #6
0
    /// <summary>
    /// Start Idle.
    /// </summary>
    /// <returns></returns>
    public virtual IEnumerator Start_Idle(AIBehavior behavior)
    {
        if (PrintDebugMessage)
        {
            Debug.Log("Start behavior:" + behavior.Name + " .IdleDataName:" + behavior.IdleDataName);
        }

        IdleData _IdleData = Unit.IdleDataDict[behavior.IdleDataName];

        string IdleAnimationName        = _IdleData.AnimationName;
        float  lastScanEndConditionTime = Time.time;

        while (true)
        {
            if (Halt)
            {
                animation.Stop(IdleAnimationName);
                yield return(null);

                continue;
            }
            else
            {
                animation.CrossFade(IdleAnimationName);

                //if this behavior's end condition matches, end this behavior
                if ((Time.time - lastScanEndConditionTime) >= behavior.AlterBehaviorInterval)
                {
                    lastScanEndConditionTime = Time.time;
                    if (CheckAlternateBehaviorCondition(behavior))
                    {
                        if (PrintDebugMessage)
                        {
                            Debug.Log("Idle behavior:" + behavior.Name + " is end.");
                        }
                        break;
                    }
                }
                //if the current target is not null and idle data mean to be keep facing at the target, face to the target.
                if (CurrentTarget != null && _IdleData.KeepFacingTarget)
                {
                    Vector3 LookAtPosition = new Vector3(CurrentTarget.position.x, transform.position.y, CurrentTarget.position.z);
                    if (_IdleData.SmoothRotate)
                    {
                        RotateData rotateData = Unit.RotateDataDict[_IdleData.RotateDataName];
                        //Calculate angle distance of forward direction and face to target direction.
                        Vector3 toTargetDir = CurrentTarget.position - transform.position;
                        Vector3 faceDir     = transform.forward;
                        if (Vector3.Angle(toTargetDir, faceDir) >= rotateData.AngleDistanceToStartRotate)
                        {
                            Util.RotateToward(transform, LookAtPosition, true, rotateData.RotateAngularSpeed);
                        }
                    }
                    else
                    {
                        transform.LookAt(LookAtPosition);
                    }
                }
                yield return(null);
            }
        }
        animation.Stop(this.Unit.IdleDataDict[behavior.IdleDataName].AnimationName);
        StopBehavior(behavior);
    }
예제 #7
0
    /// <summary>
    /// Start behave attack
    /// </summary>
    /// <param name="behavior"></param>
    /// <returns></returns>
    public virtual IEnumerator Start_Attack(AIBehavior behavior)
    {
        AttackData attackData = null;
        float      lastScanEndConditionTime = Time.time;

        while (true)
        {
            //If no target is found, do nothing
            if (Halt || CurrentTarget == null)
            {
                yield return(null);

                continue;
            }
            //Get attack data
            if (behavior.UseRandomAttackData == false)
            {
                attackData = Unit.AttackDataDict[behavior.AttackDataName];
            }
            else
            {
                string attackDataName = Util.RandomFromArray <string>(behavior.AttackDataNameArray);
                attackData = Unit.AttackDataDict[attackDataName];
            }

            //if this behavior's end condition matches, end this behavior
            if ((Time.time - lastScanEndConditionTime) >= behavior.AlterBehaviorInterval)
            {
                lastScanEndConditionTime = Time.time;
                if (CheckAlternateBehaviorCondition(behavior))
                {
                    break;
                }
            }

            //Animating attack
            string AttackAnimationName = attackData.AnimationName;
            //If can see target, and target distance <= AttackableRange, do this:
            //1. Face to target
            //2. Check last attack time against attack interval
            //3. if #2 pass, animating, send hit message
            if (this.CanSeeCurrentTarget && CurrentTargetDistance <= attackData.AttackableRange)
            {
                if (attackData.LookAtTarget)
                {
                    transform.LookAt(new Vector3(CurrentTarget.position.x, transform.position.y, CurrentTarget.position.z));
                }
                //If hitTriggerType is HitTriggerType.ByAnimationEvent, the function will be invoked by animation event
                if (attackData.hitTriggerType == HitTriggerType.ByTime)
                {
                    SendMessage("_Attack", attackData.Name);
                }
                animation.CrossFade(attackData.AnimationName);
                yield return(new WaitForSeconds(animation[attackData.AnimationName].length));

                //If AttackInterrupt = true, means wait for a while, so execute the IdleData
                if (behavior.AttackInterrupt)
                {
                    IdleData idleData = this.Unit.IdleDataDict[behavior.IdleDataName];
                    float    interval = Random.Range(behavior.AttackIntervalMin, behavior.AttackIntervalMax);
                    animation.CrossFade(idleData.AnimationName);
                    yield return(new WaitForSeconds(interval));

                    animation.Stop(idleData.AnimationName);
                }
                else
                {
                    yield return(null);
                }
                continue;
            }
            //else if can't see target, navigating until CanSeeCurrentTarget = true & within AttackableRange
            else
            {
                MoveData moveData = Unit.MoveDataDict[behavior.MoveDataName];
                yield return(StartCoroutine(NavigateToTransform(CurrentTarget,
                                                                moveData, attackData.AttackableRange, 1)));

                continue;
            }
            yield return(null);
        }
        animation.Stop(attackData.AnimationName);
        StopBehavior(behavior);
    }