본문 바로가기
마블 VR 프로젝트 제작

[마블 VR] 두번 째 포인트 공중 적 생성/이동/공격

by 노재두내 2023. 12. 27.

두번째 포인트에서 나오는 적은 근접공격이 가능 하여야 하므로 한두마리 정도는 플레이어에게 가까이 다가오도록 만들어야 한다.


먼저 생성부터 구현하자

GameSceneMain

private void CreateEnemy()
    {
        if (this.enemyGo.Length == 0)
        {
            //첫번째 포인트에서 생성되는 적임(최대 8마리 3-3-2)
            if (isFirstEnemy == true)
            {
                if (enemyNum < 6)
                {
                    //적 3마리 생성
                    for (int i = 0; i < 3; i++)
                    {
                        //Debug.Log("적 생성해라");
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else if (enemyNum >= 6 && enemyNum < 8)
                {
                    //2마리 생성
                    for (int i = 0; i < 2; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else
                {
                    //더이상 생성하지 X
                    //인디케이터 생성
                    this.playerController.pathGo.SetActive(true);
                    this.playerController.GetComponent<PlayerController>().enabled = true;
                    return;
                }
            }
            //두번째 포인트에서 생성되는 적임(최대 7마리 2-2-1)
            else
            {
                if (enemyNum < 4)
                {
                    for (int i=3;i<5; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else if (enemyNum >= 4&&enemyNum<6 )
                {
                    Instantiate(this.aerialEnemyPrefab, this.points[5].position, Quaternion.identity);
                    enemyNum++;
                }
                else
                {
                    //인디케이터 생성
                    return;
                }
            }
        }
    }

 

 

PlayerController

private void OnCollisionEnter(Collision hit)
    {
        if (hit.collider.CompareTag("Point")){
            Debug.Log("목적지에 도착했습니다");
            //인디케이터 지우고 이동 멈추기
            this.indicatorGo.SetActive(false);
            this.pathGo.SetActive(false);

            if (this.coroutine != null) StopCoroutine(this.coroutine);
            this.gameSceneMain.isFirstEnemy = false;
            this.gameSceneMain.enemyNum = 0;
        }
    }

 

여기까지 결과

 

잘 생성은 되지만, 처음 적과 움직임을 좀 다르게 해야할거같다. 

 


이동

코루틴을 따로 만들까 고민했지만 코드가 너무 복잡해질거같아 bool값으로 조정했다.

private IEnumerator CoFirstEnemyMove()
    {
        if (gameSceneMain.isFirstEnemy == true)
        {
            this.position = this.transform.position + new Vector3(Random.Range(-0.6f, 0.6f), Random.Range(-0.5f, 1.0f), Random.Range(-8f, -4f));
        }
        else
        {
            this.position = this.transform.position + new Vector3(Random.Range(-0.3f, 0.4f), Random.Range(-0.3f, 0.5f), Random.Range(-1f, -0.2f));
        }
        this.laserStaticEffect.SetActive(false);
        this.laser.enabled = false;
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * Random.Range(1f,15f) * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.2f)
            {
                this.coroutine=this.StartCoroutine(this.CoAttackAndMove());
                break;
            }

            yield return null;
        }
    }

  

+마지막 하나 나오는 적은 숨어있다가 뿅하고 나타나서 플레이어에서 다가오게 만들고 싶다. (공격은 안하고 싶음)

=> 공격은 안하는데 빨리 움직여서 맞추기 힘든 적으로 구현 하고싶음 ==> 전저럼 Random.Range로 하면 많이 빠르게 움직이기때문에 너무 멀어지거나 가까워져서 플레이어를 지나칠 수도 있을거같음

--> 일정 범위안에서만 움직이게 할 수 없을까?   

찾아보니 insideUnitCircle과 insideUnitSphere라는게 있음 

https://wolstar.tistory.com/6

 

랜덤 원형안에 오브젝트 생성시키기

원형안에 랜덤으로 생성시키는 함수를 소개합니다. https://docs.unity3d.com/kr/530/ScriptReference/Random-insideUnitSphere.html Vector3 insideUnitSphere 반경이 1인 구 내부의 임의의 점을 반환합니다 정해진 Vector 기준

wolstar.tistory.com

참고한 블로그

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

public class LastEnemyMove : MonoBehaviour
{
    [SerializeField]
    private Transform playerTrans;
    [SerializeField]
    private Transform circlePoint;
    private Coroutine coroutine;
    private Vector3 position;
    private float circleRange = 5f;
    private void Start()
    {
       this.coroutine =this.StartCoroutine(this.CoMove());
    }
    private IEnumerator CoMove()
    {
        yield return new WaitForSeconds(1.0f);
        var position = circlePoint.position;
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * 8f * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.5f)
            {
                StartCoroutine(this.CoRandomMove());
                break;
            }
            yield return null;
        }
    }

    private IEnumerator CoRandomMove()
    {
        this.position = this.circlePoint.position;
        while (true)
        {
            if (Vector3.Distance(position, this.transform.position) < 0.2f)
            {
                yield return new WaitForSeconds(0.7f);
                Vector3 randPos = (Vector3)Random.insideUnitSphere * circleRange;
                randPos.y = 0;
                position = this.circlePoint.position + randPos;
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.9f);
            }

            yield return null;
        }
    }
}

 

결과물

 

 


12월 27일 

두번째 적 이동이 맘에 안듬..

어떻게 구현해야할까..

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEngine.GraphicsBuffer;

public class AerialEnemy : MonoBehaviour
{
    [SerializeField]
    private SphereCollider childCollider;
    [SerializeField]
    private GameObject laserStaticEffect;
    [SerializeField]
    private Laser laser;
    [SerializeField]
    private GameObject getHitEffect;
    private GameSceneMain gameSceneMain;
    private Coroutine coroutine;
    private Coroutine randomMoveCoroutine;
    private Rigidbody rBody;
    private SphereCollider parentCollider;
    private float time=0f;
    private Vector3 position;

    private float circleRange = 1.8f;
    private void Start()
    {
        this.gameSceneMain = GameObject.FindObjectOfType<GameSceneMain>();
        Debug.Log(gameSceneMain);
        this.rBody = this.gameObject.GetComponent<Rigidbody>();
        this.parentCollider = this.gameObject.GetComponent<SphereCollider>();
        this.rBody.useGravity = false;

        this.Move();
       
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Shield"))
        {
            Destroy(this.gameObject, 2f);
            this.rBody.useGravity = true; //바닥으로 떨어지게 
            this.parentCollider.enabled = false;
            this.childCollider.enabled = true;

            var contact = collision.GetContact(0);
            this.rBody.AddForce(transform.forward * -200f);
            this.getHitEffect.SetActive(true);

            this.laserStaticEffect.SetActive(false);
            this.laser.enabled = false;
            if (this.coroutine != null) StopCoroutine(this.coroutine);
            if (this.randomMoveCoroutine != null) StopCoroutine(this.randomMoveCoroutine);
            //Debug.Log("<color=red>맞았다</color>");
        }
    }

    
    private void Move()
    {
        if (gameSceneMain.isFirstEnemy)
        {
            this.coroutine = this.StartCoroutine(this.CoFirstEnemyMove());
        }
        else if (gameSceneMain.isLast==true)
        {
            this.coroutine = this.StartCoroutine(this.CoLastEnemyMove());
        }
        else
        {
            this.coroutine = this.StartCoroutine(this.CoSecondEnemyMove());
            Debug.Log("두번째 적 움직이기");
        }
    }

    //-------------------------------------------------첫번째 적------------------------------------------------------------
    //생성되고 랜덤 위치로 이동
    private IEnumerator CoFirstEnemyMove()
    {
        this.position = this.transform.position + new Vector3(Random.Range(-0.6f, 0.6f), Random.Range(-0.5f, 1.0f), Random.Range(-8f, -4f));
        this.laserStaticEffect.SetActive(false);
        this.laser.enabled = false;
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * Random.Range(1f,15f) * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.2f)
            {
                this.coroutine=this.StartCoroutine(this.CoAttackAndMove());
                break;
            }

            yield return null;
        }
    }


    //공격-> 랜덤이동-> 공격-> 랜덤이동 ..
    private IEnumerator CoAttackAndMove()
    {
        this.position = this.transform.position + new Vector3(Random.Range(-0.8f, 1.2f), Random.Range(-1f, 0.8f), Random.Range(-1f, 1.2f));
        while (true)
        {
            this.time += Time.deltaTime;
            if (Vector3.Distance(position, this.transform.position)<0.2f)
            {
                //Debug.Log("목표 위치 변경 ");
                if (this.time > 0.5f)
                {
                    this.laserStaticEffect.SetActive(true);
                    this.laser.enabled = true;
                    this.time = 0;
                }
                yield return new WaitForSeconds(0.7f);
                position = this.transform.position + new Vector3(Random.Range(-0.8f, 0.8f), Random.Range(-0.5f, 0.7f), Random.Range(-0.6f, 1f));
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.05f);
                this.laserStaticEffect.SetActive(false);
                this.laser.enabled = false;
            }

            yield return null;
        }
    }

    //-----------------------------------------------두번째 적 ---------------------------------------------------------
    //생성되고 랜덤 위치로 이동
    private IEnumerator CoSecondEnemyMove()
    {
        this.position = this.transform.position + new Vector3(Random.Range(-0.4f, 0.6f), Random.Range(0f, 1f), Random.Range(-2.5f, -1.5f));
        this.laserStaticEffect.SetActive(false);
        this.laser.enabled = false;
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * Random.Range(1f, 10f) * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.2f)
            {
                this.coroutine = this.StartCoroutine(this.CoSecondAttackAndMove());
                break;
            }

            yield return null;
        }
    }
    private IEnumerator CoSecondAttackAndMove()
    {
        this.position = this.transform.position + new Vector3(Random.Range(-0.2f, 0.2f), Random.Range(-0.1f, 0.2f), Random.Range(-0.2f, 0.2f));
        while (true)
        {
            this.time += Time.deltaTime;
            if (Vector3.Distance(position, this.transform.position) < 0.2f)
            {
                //Debug.Log("목표 위치 변경 ");
                if (this.time > 0.5f)
                {
                    this.laserStaticEffect.SetActive(true);
                    this.laser.enabled = true;
                    this.time = 0;
                }
                yield return new WaitForSeconds(0.5f);
                this.position = this.transform.position + new Vector3(Random.Range(-0.3f, 0.4f), Random.Range(-0.15f, 0.25f), Random.Range(-0.4f, 0.4f));
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.05f);
                this.laserStaticEffect.SetActive(false);
                this.laser.enabled = false;
            }

            yield return null;
        }
    }

    //-------------------------------------------마지막 하나 적 움직임----------------------------------------------------
    private IEnumerator CoLastEnemyMove()
    {
        this.laserStaticEffect.SetActive(false);
        this.laser.enabled = false;
        yield return new WaitForSeconds(2.5f);
        var position = gameSceneMain.points[4].position;
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * 12f * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.5f)
            {
                this.randomMoveCoroutine = StartCoroutine(this.CoLastAttackAndMove());
                break;
            }
            yield return null;
        }
    }

    private IEnumerator CoLastAttackAndMove()
    {
        this.position = gameSceneMain.points[4].position;
        while (true)
        {
            if (Vector3.Distance(position, this.transform.position) < 0.2f)
            {
                yield return new WaitForSeconds(0.6f);
                Vector3 randPos = (Vector3)Random.insideUnitSphere * circleRange;
                randPos.y = 0;
                position = this.gameSceneMain.points[4].position + randPos;
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.6f);
            }

            yield return null;
        }
    }
}
 public void CreateEnemy()
    {
        if (this.enemyGo.Length == 0)
        {
            //첫번째 포인트에서 생성되는 적임(최대 8마리 3-3-2)
            if (isFirstEnemy == true)
            {
                if (enemyNum < 6)
                {
                    //적 3마리 생성
                    for (int i = 0; i < 3; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else if (enemyNum >= 6 && enemyNum < 8)
                {
                    //2마리 생성
                    for (int i = 0; i < 2; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else
                {
                    //더이상 생성하지 X
                    //첫번째 인디케이터 생성
                    this.playerController.pathGo[0].SetActive(true);
                    this.playerController.GetComponent<PlayerController>().enabled = true;
                    return;
                }
            }
            //두번째 포인트에서 생성되는 적임(최대 7마리 2-2-1)
            else
            {
                if (enemyNum < 2)
                {
                    for (int i=3;i<5; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else if (enemyNum >= 2 && enemyNum < 4)
                {
                    for (int i = 5; i < 7; i++)
                    {
                        Instantiate(this.aerialEnemyPrefab, this.points[i].position, Quaternion.identity);
                        enemyNum++;
                    }
                }
                else if (enemyNum >= 4&&enemyNum<5 )
                {
                    this.isLast = true;
                    Instantiate(this.aerialEnemyPrefab, this.points[7].position, Quaternion.identity);
                    enemyNum++;
                }
                else
                {
                    //두번째 인디케이터 생성
                    this.playerController.pathGo[1].SetActive(true);
                    if (this.isSecond == true)
                    {
                        this.playerController.SecondMove();
                        this.isSecond = false;
                    }
                    return;
                }
            }
        }
    }

  

맘에 안들어..