스토리지

[07.05] 좀비 서바이벌 03 - 좀비 소환하기 본문

Unity/유니티 기본

[07.05] 좀비 서바이벌 03 - 좀비 소환하기

ljw4104 2021. 7. 5. 16:45

1. Nav Mesh Bake

Window -> AI -> Navigation -> Bake탭 -> Bake 버튼

 

2. Spawn Points 설정

 

3. 좀비 소환하고 플레이어를 쫓아가기 (최대 2마리)

using System.Collections.Generic;
using UnityEngine;

public class ZombieSpawner : MonoBehaviour
{
    public GameObject zombiePrefab;
    public Transform[] spawnPos;
    public List<GameObject> zombies;
    public int maxCount = 2;

    // Start is called before the first frame update
    void Start()
    {
        this.zombies = new List<GameObject>();
        this.CreateZombie();
    }

    private void CreateZombie()
    {
        for(int i = 0; i < this.maxCount - this.zombies.Count; i++)
        {
            //좀비 생성 뒤에 2개의 Spawn Point 중에 랜덤한 위치에 생성
            var zombieGo = Instantiate(this.zombiePrefab);
            zombieGo.GetComponent<Zombie>().Init(this.spawnPos[i].position, i);
        }
    }
}
using System;
using UnityEngine;
using UnityEngine.AI;

public class Zombie : MonoBehaviour
{
    public Action onDie;

    private bool isFollow;
    private float delta;
    private float span = 2;
    private NavMeshAgent agent;
    public int Id
    {
        get;
        private set;
    }
    // Start is called before the first frame update
    public void Init(Vector3 initPos, int id)
    {
        this.transform.position = initPos;
        this.Id = id;
        this.isFollow = true;
        this.agent = GetComponent<NavMeshAgent>();
    }

    public void Hit()
    {
        Debug.Log("Hit");
        this.Die();
    }

    public void Die()
    {
        Debug.Log("Die");
        this.onDie();
    }

    private void Update()
    {
        if(this.isFollow == true)
        {
            var player = GameObject.Find("Woman");
            if (player != null)
            {
                this.transform.LookAt(player.transform);
                this.agent.speed = 1.5f;
                this.agent.SetDestination(player.transform.position);

                var distance = Vector3.Distance(this.transform.position, player.transform.position);
                if (distance < 1f)
                {
                    this.isFollow = false;
                    this.agent.isStopped = true;
                }
            }
        }
        else
        {
            this.delta += Time.deltaTime;
            if(this.delta > this.span)
            {
                this.delta = 0;
                this.isFollow = true;
                this.agent.isStopped = false;
            }
        }
    }
}

 

5. 조이스틱에서 손을 떼면 가장 가까운 좀비를 바라본다.

using UnityEngine;

public class GameMain : MonoBehaviour
{
    public VariableJoystick joystick;
    public GameObject playerGo;
    public Animator playerAnimator;
    // Start is called before the first frame update
    void Start()
    {
        this.playerAnimator = this.playerGo.GetComponent<Animator>();
        this.joystick.onPointUp = () =>
        {
            var zombies = FindObjectsOfType<Zombie>();
            var zombie = zombies[0];
            var shortestDistance = Vector3.Distance(this.playerGo.transform.position, zombie.transform.position);
            foreach (var i in zombies)
            {
                var distance = Vector3.Distance(this.playerGo.transform.position, i.transform.position);
                if(distance < shortestDistance)
                {
                    zombie = i;
                    shortestDistance = distance;
                }
            }
            this.playerGo.transform.LookAt(zombie.gameObject.transform);
        };
    }

    // Update is called once per frame
    void Update()
    {
        if(this.joystick.Horizontal != 0 && this.joystick.Vertical != 0)
        {
            var angles = new Vector3(0, Mathf.Atan2(this.joystick.Horizontal, this.joystick.Vertical) * 180 / Mathf.PI, 0);
            this.playerGo.transform.eulerAngles = angles;
            this.playerGo.transform.Translate(Vector3.forward * 1.0f * Time.deltaTime);
            this.playerAnimator.SetFloat("Move", 1.0f);
        }
        else
        {
            this.playerGo.GetComponent<Rigidbody>().velocity = Vector3.zero;
            this.playerGo.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
            this.playerAnimator.SetFloat("Move", 0);
        }
    }
}

 

6. 좀비가 총에 맞아 죽고, 새로 생성된다.

using System.Collections.Generic;
using UnityEngine;

public class ZombieSpawner : MonoBehaviour
{
    public GameObject zombiePrefab;
    public Transform[] spawnPos;
    public List<GameObject> zombies;
    public int maxCount = 2;

    // Start is called before the first frame update
    void Start()
    {
        this.zombies = new List<GameObject>();
        this.CreateZombie();
    }

    private void CreateZombie()
    {
        int total = this.maxCount - this.zombies.Count;
        for (int i = 0; i < total; i++)
        {
            //좀비 생성 뒤에 2개의 Spawn Point 중에 랜덤한 위치에 생성
            var zombieGo = Instantiate(this.zombiePrefab);
            zombieGo.GetComponent<Zombie>().Init(this.spawnPos[Random.Range(0,2)].position);
            this.zombies.Add(zombieGo);

            zombieGo.GetComponent<Zombie>().onDie = () =>
            {
                this.zombies.Remove(zombieGo);
                Destroy(zombieGo);
                this.CreateZombie();
            };
        }
    }
}
using System;
using UnityEngine;
using UnityEngine.AI;

public class Zombie : MonoBehaviour
{
    public Action onDie;

    private bool isFollow;
    private float delta;
    private float span = 2;
    private NavMeshAgent agent;
    private Animator anim;
    // Start is called before the first frame update
    public void Init(Vector3 initPos)
    {
        this.transform.position = initPos;
        this.isFollow = true;
        this.agent = GetComponent<NavMeshAgent>();
        this.anim = GetComponent<Animator>();
    }

    public void Hit()
    {
        this.Die();
    }

    public void Die()
    {
        this.onDie();
    }

    private void Update()
    {
        if(this.isFollow == true)
        {
            var player = GameObject.Find("Woman");
            if (player != null)
            {
                this.anim.SetBool("HasTarget", true);
                this.transform.LookAt(player.transform);
                this.agent.speed = 1.5f;
                this.agent.SetDestination(player.transform.position);

                var distance = Vector3.Distance(this.transform.position, player.transform.position);
                if (distance < 1f)
                {
                    this.anim.SetBool("Move", false);
                    this.isFollow = false;
                    this.agent.isStopped = true;
                }
            }
        }
        else
        {
            this.delta += Time.deltaTime;
            if(this.delta > this.span)
            {
                this.delta = 0;
                this.isFollow = true;
                this.agent.isStopped = false;
            }
        }
    }
}

Comments