Inheritance: MonoBehaviour
 /// <summary>
 /// This function is called when the object is loaded.
 /// </summary>
 public new void OnEnable()
 {
     base.OnEnable();
     if (FuncNames == null)
     {
         FuncNames = AgentFunctions.GetConditionStrings(_conditionGroup);
     }
 }
        /// <summary>
        /// Create LoopNode from json string.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="jObj"></param>
        /// <returns></returns>
        private static Node Serialize(this LoopNode node, JsonObject jObj)
        {
            node.NodeName = jObj["type"].String;
            node.Id       = jObj["ID"].String;
            //node.FuncIndex = jObj["functionID"].Int;
            node.ConditionGroup = jObj["conditionGroup"].ConditionGroup;
            node.FuncNames      = AgentFunctions.GetConditionStrings(node.ConditionGroup);
            try
            { node.FunctionName = jObj["functionName"].String; }
            catch (Exception) { /*Debug.Log("Your behaviour has a deprecated format");*/ }

            try
            {
                node.MinTime = jObj["minTime"].Float;
                node.MaxTime = jObj["maxTime"].Float;
            }
            catch (Exception) { /*Debug.Log("Your behaviour has a deprecated format");*/ }

            var sortedFunctions = node.FuncNames;

            System.Array.Sort(sortedFunctions, StringComparer.InvariantCulture);

            if (node.FunctionName != null)
            {
                for (var i = 0; i < node.FuncNames.Length; i++)
                {
                    if (node.FuncNames[i] == node.FunctionName)
                    {
                        node.FuncIndex = i;
                    }
                }
            }

            if (node.FuncIndex == -1)
            {
                node.FuncIndex = jObj["functionID"].Int;
            }


            node.Reverse = jObj["reverse"] != null && jObj["reverse"].Bool;
            var x = jObj["rect"]["posX"].Float;
            var y = jObj["rect"]["posY"].Float;
            var w = jObj["rect"]["width"].Float;
            var h = jObj["rect"]["height"].Float;

            node.Rect = new Rect(x, y, w, h);

            return(node);
        }
Beispiel #3
0
    //All the checks the agent goes though.
    private void AgentChecks()
    {
        if (AgentFunctions.CheckTarget(Target))
        {
            Transition(FindTarget(), "No Target");
        }

        if (AgentFunctions.CheckTargetLocation(TargetLocation))
        {
            Transition(FindLocation(), "No Target Location");
        }

        if (AgentFunctions.CheckForDeath(transform, -1))
        {
            Transition(Death(), "Off Map");
        }

        if (AgentFunctions.CheckDistanceToLocation(transform, TargetLocation, 2.0f))
        {
            Transition(FindLocation(), "Arrived At Last Location");
        }
    }
Beispiel #4
0
        /// <summary>
        /// Get the array of method names for appropriate action group.
        /// </summary>
        private void GetFunctions()
        {
            switch (_actionGroup.enumValueIndex)
            {
            case 1:
                _skill   = false;
                _options = AgentFunctions.GetFunctions <InventoryActionInterface>();
                break;

            case 2:
                _skill              = true;
                _options            = new[] { _skillName };
                _funcIndex.intValue = 0;
                break;

            default:
                _skill   = false;
                _options = AgentFunctions.GetFunctions <MotionActionInterface>();
                break;
            }

            ((InvokerNode)target).FuncNames = _options;
        }
Beispiel #5
0
    IEnumerator Move()
    {
        while (NextState == null)
        {
            AgentChecks();

            if (Target == null)
            {
                continue;                 //If AI has no target then skip.
            }
            float Dir = AgentFunctions.AngleDir(transform.up, (transform.position - TargetLocation), transform.forward);


            //Because I am using torque and not calculating a direction force, everything is simplified.
            Body.AddForce((transform.forward * TankSpeed) * Time.deltaTime);
            Body.AddTorque((transform.up * TurnSpeed * Dir) * Time.deltaTime);

            //Finds the turret rotation ignores the y rotation.
            Quaternion TargetRotation = AgentFunctions.GetTargetRotation(Target, transform);
            Turret.transform.rotation = Quaternion.Lerp(Turret.transform.rotation, TargetRotation, AgentBehaviour.RotationSpeed * Time.deltaTime);

            //FramesCount uses Time.deltatime so that it works with TimeScale
            FrameCount -= Time.deltaTime;
            if (FrameCount <= 0)
            {
                bFire = false;
            }

            //If turret is in specified range, change to shoot state.
            if (AgentFunctions.GetTargetAngle(Turret, Target, transform, AgentBehaviour.RotationAccuracy) && !bFire)
            {
                Transition(Shoot(), "Target In Range");
            }

            yield return(null);
        }
    }
Beispiel #6
0
    private void OnTriggerStay(Collider other)
    {
        //Very simple Tank avoidance.
        if (other.gameObject.tag == "Tank")
        {
            float Dir = AgentFunctions.AngleDir(transform.up, (transform.position - other.transform.position), transform.forward);

            if (Dir == 1)
            {
                Body.AddTorque(transform.up * TurnSpeed * -0.50f);
                Debug.DrawLine(transform.position, transform.position + transform.right * TurnSpeed * -2);
            }
            else
            {
                Body.AddTorque(transform.up * TurnSpeed * 0.50f);
                Debug.DrawLine(transform.position, transform.position + transform.right * TurnSpeed * 2);
            }
        }

        //Very simple Mine avoidance.
        if (other.gameObject.tag == "Mine")
        {
            float Dir = AgentFunctions.AngleDir(transform.up, (transform.position - other.transform.position), transform.forward);

            if (Dir == 1)
            {
                Body.AddTorque(transform.up * TurnSpeed * -1.0f);
                Debug.DrawLine(transform.position, transform.position + transform.right * TurnSpeed * -2);
            }
            else
            {
                Body.AddTorque(transform.up * TurnSpeed * 1.0f);
                Debug.DrawLine(transform.position, transform.position + transform.right * TurnSpeed * 2);
            }
        }
    }
Beispiel #7
0
    //Tank Shoot
    IEnumerator Shoot()
    {
        bFire      = true;
        FrameCount = AgentBehaviour.ReloadTime;

        if (Target == null)
        {
            Transition(Move(), "No Target Return To Move");
        }

        // Create an instance of the shell and store a reference to it's rigidbody.
        Rigidbody ShellInstance = Instantiate(ShellActor, MuzzleLocation.position, MuzzleLocation.rotation) as Rigidbody;

        // Set the shell's velocity to the launch force in the fire position's forward direction.
        // I divide by a random value to simulate it's accuracy
        if (ShellInstance != null && Target != null)
        {
            ShellInstance.velocity = AgentFunctions.BallisticVel(transform, Target, 25.0f) / Random.Range(AgentBehaviour.MinDistAccuracy, AgentBehaviour.MaxDistAccuracy);
        }

        Transition(Move(), "Fired At Target");

        yield return(null);
    }
 /// <summary>
 /// Get the array of method names for appropriate action group.
 /// </summary>
 private void GetFunctions()
 {
     _options = AgentFunctions.GetConditionStrings(_conditionGroup.enumValueIndex);
     Array.Sort(_options, StringComparer.InvariantCulture);
     ((ObserverNode)target).FuncNames = _options;
 }
        /// <summary>
        /// Create InvokerNode from json string.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="jObj"></param>
        /// <returns></returns>
        private static Node Serialize(this InvokerNode node, JsonObject jObj)
        {
            node.NodeName    = jObj["type"].String;
            node.Id          = jObj["ID"].String;
            node.ActionGroup = jObj["actionGroup"].ActionGroup;
            if (node.ActionGroup == ActionGroup.Skill)
            {
                node.FuncIndex = 0;
                node.FuncNames = new[] { jObj["functionID"].String };
                try
                { node.FunctionName = jObj["functionName"].String; }
                catch (Exception) { /*Debug.Log("Your behaviour has a deprecated format");*/ }

                if (jObj["executeSkill"] != null)
                {
                    node.ExecuteSkill = jObj["executeSkill"].Bool;
                }
            }
            else if (node.ActionGroup == ActionGroup.Inventory)
            {
                //node.FuncIndex = jObj["functionID"].Int;
                node.FuncNames = AgentFunctions.GetFunctions <InventoryActionInterface>();
                try
                { node.FunctionName = jObj["functionName"].String; }
                catch (Exception) { /*Debug.Log("Your behaviour has a deprecated format");*/ }
            }
            else
            {
                //node.FuncIndex = jObj["functionID"].Int;
                node.FuncNames = AgentFunctions.GetFunctions <MotionActionInterface>();
                try
                { node.FunctionName = jObj["functionName"].String; }
                catch (Exception) { /*Debug.Log("Your behaviour has a deprecated format");*/ }
            }

            var sortedFunctions = node.FuncNames;

            System.Array.Sort(sortedFunctions, StringComparer.InvariantCulture);

            if (node.FunctionName != null)
            {
                for (var i = 0; i < node.FuncNames.Length; i++)
                {
                    if (node.FuncNames[i] == node.FunctionName)
                    {
                        node.FuncIndex = i;
                    }
                }
            }

            if (node.FuncIndex == -1)
            {
                node.FuncIndex = jObj["functionID"].Int;
            }

            var x = jObj["rect"]["posX"].Float;
            var y = jObj["rect"]["posY"].Float;
            var w = jObj["rect"]["width"].Float;
            var h = jObj["rect"]["height"].Float;

            node.Rect = new Rect(x, y, w, h);

            return(node);
        }
Beispiel #10
0
        /// <summary>
        /// Decipher the file and create methods and relations between them using reflection.
        /// </summary>
        /// <param name="behaviour"></param>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static BehaviourCore GetCore(EliotBehaviour behaviour, GameObject gameObject)
        {
            var core = new BehaviourCore();

            behaviour.Json = BehaviourVersionManager.UpdateJson(behaviour.Json);
            // See if there are any nodes in file.
            var jObj   = new JsonObject(behaviour.Json);
            var jNodes = jObj["nodes"].Objects;

            if (jNodes == null)
            {
                return(null);
            }

            Entry entry     = null;
            var   particles = new List <EliotComponent>();

            // If there are, create Behaviour Components from each piece of data.
            if (jNodes.Count > 0)
            {
                foreach (var node in jNodes)
                {
                    var nodeObj = (JsonObject)node;
                    var type    = nodeObj["type"].String;
                    switch (type)
                    {
                    case "Entry":
                    {
                        entry = new Entry(nodeObj["ID"].String);
                        particles.Add(entry);
                        break;
                    }

                    case "Invoker":
                    {
                        var      actionGroup = nodeObj["actionGroup"].ActionGroup;
                        string[] funcNames;
                        string   functionName;
                        int      funcIndex = -1;
                        var      execute   = true;
                        if (actionGroup == ActionGroup.Skill)
                        {
                            funcIndex    = 0;
                            funcNames    = new[] { nodeObj["functionID"].String };
                            functionName = nodeObj["functionName"].String;
                            if (nodeObj["executeSkill"] != null)
                            {
                                execute = nodeObj["executeSkill"].Bool;
                            }
                        }
                        else if (actionGroup == ActionGroup.Inventory)
                        {
                            //funcIndex = nodeObj["functionID"].Int;
                            funcNames    = AgentFunctions.GetFunctions <InventoryActionInterface>();
                            functionName = nodeObj["functionName"].String;
                        }
                        else
                        {
                            //funcIndex = nodeObj["functionID"].Int;
                            funcNames    = AgentFunctions.GetFunctions <MotionActionInterface>();
                            functionName = nodeObj["functionName"].String;
                        }

//_____________________________________CAUTION WORK IN PROGRESS________________________
                        //Array.Sort(funcNames, StringComparer.InvariantCulture);
                        for (var i = 0; i < funcNames.Length; i++)
                        {
                            if (funcNames[i] == functionName)
                            {
                                funcIndex = i;
                            }
                        }
                        if (funcIndex == -1)
                        {
                            funcIndex = nodeObj["functionID"].Int;
                        }
//_____________________________________________________________________________________

                        var inv = new Invoker(AgentFunctions.CreateAction(funcNames[funcIndex], gameObject,
                                                                          actionGroup, execute), nodeObj["ID"].String);
                        particles.Add(inv);
                        break;
                    }

                    case "Observer":
                    {
                        var funcIndex      = nodeObj["functionID"].Int;
                        var conditionGroup = nodeObj["conditionGroup"].ConditionGroup;
                        var funcNames      = AgentFunctions.GetConditionStrings(conditionGroup);
                        var functionName   = nodeObj["functionName"].String;
                        var obs            = new Observer(AgentFunctions.CreateCondition(functionName, gameObject,
                                                                                         conditionGroup, nodeObj["ID"].Int), nodeObj["ID"].String);
                        particles.Add(obs);
                        break;
                    }

                    case "Loop":
                    {
                        var funcIndex      = nodeObj["functionID"].Int;
                        var conditionGroup = nodeObj["conditionGroup"].ConditionGroup;
                        var funcNames      = AgentFunctions.GetConditionStrings(conditionGroup);
                        var functionName   = nodeObj["functionName"].String;
                        var reverse        = nodeObj["reverse"] != null && nodeObj["reverse"].Bool;
                        var loop           = new Loop(core, reverse,
                                                      AgentFunctions.CreateCondition(functionName, gameObject,
                                                                                     conditionGroup, nodeObj["ID"].Int), nodeObj["ID"].String);
                        particles.Add(loop);
                        break;
                    }
                    }
                }
            }

            // Now we need to connect the Components.
            var jTransitions = jObj["transitions"].Objects;

            foreach (var trans in jTransitions)
            {
                // Retrieve the needed information from data.
                var transition = (JsonObject)trans;

                var   startId = transition["startID"].String;
                var   endId = transition["endID"].String;
                var   isNeg = transition["type"].String.Equals("negative");
                int   minRate, maxRate;
                float minCooldown, maxCooldown;
                bool  terminate;
                try
                {
                    minRate     = transition["minRate"].Int;
                    maxRate     = transition["maxRate"].Int;
                    minCooldown = transition["minCooldown"].Float;
                    maxCooldown = transition["maxCooldown"].Float;
                    terminate   = transition["terminate"].Bool;
                }
                catch (Exception)
                {
                    minRate     = 1;
                    maxRate     = 1;
                    minCooldown = 0f;
                    maxCooldown = 0f;
                    terminate   = false;
                }

                // Connect proper Components by their IDs.
                try
                {
                    var type = ComponentTypeById(particles, startId);
                    if (type == "Observer")
                    {
                        if (isNeg)
                        {
                            ((Observer)particles.FirstOrDefault(particle => particle.Id == startId))
                            .ConnectWith_Else(particles.FirstOrDefault(particle => particle.Id == endId),
                                              minRate, maxRate, minCooldown, maxCooldown, terminate);
                        }
                        else
                        {
                            particles.FirstOrDefault(particle => particle.Id == startId)
                            .ConnectWith(particles.FirstOrDefault(particle => particle.Id == endId),
                                         minRate, maxRate, minCooldown, maxCooldown, terminate);
                        }
                    }
                    else if (type == "Loop")
                    {
                        if (isNeg)
                        {
                            ((Loop)particles.FirstOrDefault(particle => particle.Id == startId))
                            .ConnectWith_End(particles.FirstOrDefault(particle => particle.Id == endId),
                                             minRate, maxRate, minCooldown, maxCooldown, terminate);
                        }
                        else
                        {
                            particles.FirstOrDefault(particle => particle.Id == startId)
                            .ConnectWith(particles.FirstOrDefault(particle => particle.Id == endId),
                                         minRate, maxRate, minCooldown, maxCooldown, terminate);
                        }
                    }
                    else
                    {
                        particles.FirstOrDefault(particle => particle.Id == startId)
                        .ConnectWith(particles.FirstOrDefault(particle => particle.Id == endId),
                                     minRate, maxRate, minCooldown, maxCooldown, terminate);
                    }
                }
                catch (NullReferenceException) { Debug.Log("Something is wrong with data."); }
            }

            // Set the Entry.
            core.Entry = entry;
            return(core);
        }