示例#1
0
    // Update is called once per frame
    void Update()
    {
        {
            /*
             * Section 6.17.4 Putting it all together!
             */
            GameObject[] allObjects = FindObjectsOfType <GameObject>();
            ArrayList    zombies    = new ArrayList();
            ArrayList    humans     = new ArrayList();

            // iterate through all game objects and find humans and zombies

            foreach (GameObject go in allObjects)
            {
                HumanWithStates  aHuman   = go.GetComponent <HumanWithStates>() as HumanWithStates;
                ZombieWithStates aZombie  = go.GetComponent <ZombieWithStates>() as ZombieWithStates;
                bool             isHuman  = aHuman != null;
                bool             isZombie = aZombie != null;
                {
                    if (isHuman)
                    {
                        humans.Add(go);
                        continue; //added to skip the zombies.Add(go); statement.
                    }
                    if (!isHuman && isZombie)
                    {
                        zombies.Add(go);
                    }
                }
            }

            GameObject[] theZombies = new GameObject [zombies.Count];
            zombies.CopyTo(theZombies);
            foreach (GameObject z in theZombies)
            {
                //check distance from zombie to all humans
                foreach (GameObject h in humans)
                {
                    float dist             = (z.transform.position - h.transform.position).magnitude;
                    float tooCloseToZombie = 1.0f;
                    if (dist < tooCloseToZombie)
                    {
                        zombies.Remove(z);
                    }
                }
            }

            float      closestDistance = Mathf.Infinity;
            GameObject closestTarget   = null;
            foreach (GameObject zombie in zombies)
            {
                float dist = (zombie.transform.position - transform.position).magnitude;
                if (dist < closestDistance)
                {
                    closestDistance = dist;
                    closestTarget   = zombie;
                }
            }

            if (closestTarget != null)
            {
                GunTurretController controller = GetComponent <GunTurretController>();
                controller.ShootAtTarget(closestTarget);
                Debug.DrawLine(closestTarget.transform.position, transform.position, Color.red);
            }
        }
    }
        void Update()
        {
            /* * * * * * * * * * * * * * * * * *
            * Section 6.16.3 Just For Zombies *
            * * * * * * * * * * * * * * * * * */

            HumanWithStates closestHuman = null;

            GameObject[] allGameObjects = GameObject.FindObjectsOfType <GameObject>();
            float        closest        = Mathf.Infinity;
            Vector3      direction      = Vector3.zero;

            foreach (GameObject go in allGameObjects)
            {
                HumanWithStates human = go.GetComponent <HumanWithStates>();
                if (human != null)
                {
                    float distance = (go.transform.position - transform.position).magnitude;
                    //check if it's a zombie
                    if (distance < closest)
                    {
                        closestHuman = human;
                        direction    = go.transform.position - transform.position;
                        closest      = distance;
                    }
                }
            }

            /* * * * * * * * * * * * * * * * * * * * *
            * Section 6.16.2 Zombie State Machine   *
            * * * * * * * * * * * * * * * * * * * * */
            // Jump to specific label for updates
            switch (MovementState)
            {
            case MovementStates.Idleing: goto Idle;

            case MovementStates.Wandering: goto Wander;

            case MovementStates.Looking: goto Look;

            case MovementStates.Chasing: goto Chase;

            case MovementStates.Feeding: goto Feed;
            }

            // return here to update timers.
UpdateTimer:
            if (Time.time > StateTimer)
            {
                StateTimer = Time.time + Random.Range(3.0f, 7.0f);
                switch (MovementState)
                {
                case MovementStates.Idleing:
                    switch (Random.Range(0, 3))
                    {
                    case 0:
                        MovementState = MovementStates.Idleing;
                        break;

                    case 1:
                        MovementState = MovementStates.Looking;
                        break;

                    case 2:
                        MovementState = MovementStates.Wandering;
                        break;
                    }
                    break;

                case MovementStates.Wandering:
                case MovementStates.Looking:
                case MovementStates.Chasing:
                case MovementStates.Feeding:
                    MovementState = MovementStates.Idleing;
                    break;
                }
            }
            return;// escape from Update()

Idle:
            Debug.Log("Idle");
            goto UpdateTimer;

Look:
            Debug.Log("Look");
            {
                /* * * * * * * * * * * * * * * * * * * * * * * * * * *
                * Section 6.16.2 Zombie State Machine continued...  *
                * * * * * * * * * * * * * * * * * * * * * * * * * * */

                // update rotation
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, 5f);

                // checking if we're facing our target direction
                float angle = Quaternion.Angle(transform.rotation, targetRotation);
                if (angle < 0.1f || angle == 180)
                {
                    Vector3 dir = new Vector3()
                    {
                        x = Random.Range(-1f, 1f),
                        y = 0,
                        z = Random.Range(-1f, 1f)
                    };
                    targetRotation = Quaternion.LookRotation(dir, transform.up);
                }

                /* * * * * * * * * * * * * * * * * * * * * * * * * *
                * Section 6.16.3 This is a Reference to Yourself  *
                * * * * * * * * * * * * * * * * * * * * * * * * * */

                if (this.GetType() == typeof(HumanWithStates))
                {
                    goto UpdateTimer;
                }

                /* * * * * * * * * * * * * * * * * * *
                * Section 6.16.4 Just for Zombies   *
                * * * * * * * * * * * * * * * * * * */
                if (closest < 5)
                {
                    targetRotation     = Quaternion.LookRotation(direction, transform.up);
                    transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, 5f);
                    MovementState      = MovementStates.Chasing;
                }
            }
            goto UpdateTimer;

Wander:
            Debug.Log("Wander");
            {
                /*
                 * Push the character forward to walk around while lookinmg
                 */
                transform.position += transform.forward * 0.01f;
            }
            goto Look;

Chase:
            Debug.Log("Chase");
            {
                if (closest < 0.25f)
                {
                    MovementState = MovementStates.Feeding;
                }
                transform.position += transform.forward * 0.01f;
            }
            goto UpdateTimer;

Feed:
            Debug.Log("Feed");
            {
                if (closestHuman != null && closest < 0.25f)
                {
                    // convert human to zombie
                    Transform zombiePrimitive = transform.Find("ZombiePrimitive");
                    if (zombiePrimitive == null)
                    {
                        return;
                    }
                    Destroy(closestHuman.transform.Find("HumanPrimitive").gameObject);
                    GameObject newZombie = GameObject.Instantiate(zombiePrimitive.gameObject);
                    newZombie.transform.parent        = closestHuman.gameObject.transform;
                    newZombie.transform.localPosition = Vector3.zero;
                    newZombie.transform.localRotation = Quaternion.identity;
                    closestHuman.gameObject.AddComponent <ZombieWithStates>();
                    Destroy(closestHuman);
                    return;
                }
            }
            goto UpdateTimer;
        }