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

[마블 VR] 공중 적 이동/공격/피격

by 노재두내 2023. 12. 20.

1. 공중 적 이동/공격

랜덤한 목표 지점에 도착하면 목표지점을 변경하고., 도착하지 않았다면(this.transform.position!=position) 이동한다.

Coroutine을 이용해서 일정 시간마다 laser effect를 setActive로 공격 구현

   private IEnumerator CoMove()
    {
        var position = this.transform.position+ new Vector3(Random.Range(-0.8f, 0.8f), Random.Range(-0.5f, 1.0f), Random.Range(-10f, -3.5f));
        this.laserStaticEffect.SetActive(false);
        while (true)
        {
            this.transform.LookAt(position);
            this.transform.Translate(Vector3.forward * 4f * Time.deltaTime);
            var dis = Vector3.Distance(position, this.transform.position);
            if (dis < 0.2f)
            {
                this.StartCoroutine(this.CoAttackAndMove());
                break;
            }

            yield return null;
        }
    }

    //공격-> 랜덤이동-> 공격-> 랜덤이동 ..
    private IEnumerator CoAttackAndMove()
    {
        var position = this.transform.position + new Vector3(Random.Range(-0.8f, 1.2f), Random.Range(-1f, 1.2f), Random.Range(-1f, 1.2f));
        Debug.Log(position);
        while (true)
        {
            if (this.transform.position == position)
            {
                Debug.Log("목표 위치 변경 ");
                this.laserStaticEffect.SetActive(true);
                yield return new WaitForSeconds(2.0f);
                position =this.transform.position + new Vector3(Random.Range(-0.8f, 1.2f), Random.Range(-1f, 1.2f), Random.Range(-1f, 1.2f));
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.1f);
                this.laserStaticEffect.SetActive(false);
            }

            yield return null;
        }
    }

 

실행 결과

 


버그 수정. ray쏘는거 수정하기

영상에서 보는거처럼 레이저에 맞지 않는데 방패가 진동을 한다 -> 레이저는 안쏘지만 ray는 계속 쏘고 있기 때문

 

이동할때는 Laser스크립트를 비활성화 하고 , 공격할 때 활성화 되도록 구현하자

추가한 코드

 

이제 공격할때만 흔들린다.

 

+ 플레이어 입장에서 적이 공격을 멈추고 이동할때 , 공격해야 damage를 입지 않는데 , 현재 이동하는 시간이 너무 짧다.

this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.05f); 

0.1->0.05로 줄임


1. 공중 적 피격

이펙트를 붙이고, 맞은 방향(collision.GetContact(0))으로 밀리도록 스크립트에 addforce를 해주었다.

 

 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(contact.point * 20f);
            this.getHitEffect.SetActive(true);

            this.laserStaticEffect.SetActive(false);
            this.laser.enabled = false;
            this.StopCoroutine(this.coroutine);
        }
    }

결과 영상


 [전체 코드]

using Palmmedia.ReportGenerator.Core.Reporting.Builders;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEngine.GraphicsBuffer;

public class AerialEnemy : MonoBehaviour
{
    private Rigidbody rBody;
    private SphereCollider parentCollider;
    [SerializeField]
    private SphereCollider childCollider;
    [SerializeField]
    private GameObject laserStaticEffect;
    [SerializeField]
    private Laser laser;
    [SerializeField]
    private GameObject getHitEffect;
    private Coroutine coroutine;
    private void Start()
    {
        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(contact.point * 20f);
            this.getHitEffect.SetActive(true);

            this.laserStaticEffect.SetActive(false);
            this.laser.enabled = false;
            this.StopCoroutine(this.coroutine);
        }
    }

    //생성되고 랜덤 위치로 이동
    private void Move()
    {
        if (this.coroutine != null) StopCoroutine(this.coroutine);
        this.coroutine = this.StartCoroutine(this.CoMove());
    }

    private IEnumerator CoMove()
    {
        var position = this.transform.position+ new Vector3(Random.Range(-0.8f, 0.8f), Random.Range(-0.5f, 1.0f), Random.Range(-9f, -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()
    {
        var position = this.transform.position + new Vector3(Random.Range(-0.8f, 1.2f), Random.Range(-1f, 0.8f), Random.Range(-1f, 1.2f));
        Debug.Log(position);
        while (true)
        {
            if (this.transform.position == position)
            {
                Debug.Log("목표 위치 변경 ");
                this.laserStaticEffect.SetActive(true);
                this.laser.enabled = true;
                yield return new WaitForSeconds(2.5f);
                position =this.transform.position + new Vector3(Random.Range(-0.7f, 0.8f), Random.Range(-0.5f, 0.8f), 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;
        }
    }
}

 


수정해야 할 점

위에 영상을 보면 너무 다같이 움직이고 다같이 공격하는 느낌이 든다.

Random.Range를 이용해서 시간차를 줌

this.time += Time.deltaTime;
            if (this.transform.position == position)
            {
                //Debug.Log("목표 위치 변경 ");
                if (this.time > 0.5f)
                {
                    this.laserStaticEffect.SetActive(true);
                    this.laser.enabled = true;
                    this.time = 0;
                }
                yield return new WaitForSeconds(2.5f);
                position = this.transform.position + new Vector3(Random.Range(-0.7f, 0.8f), Random.Range(-0.5f, 0.8f), Random.Range(-0.6f, 1f));
            }

다같이 공격하는거같은건 사라졌지만 공격안하고 있는애들은 멀뚱히 서있는 모습

-> 공격안할 때는 이동하도록 하기

 private IEnumerator CoAttackAndMove()
    {
        var position = this.transform.position + new Vector3(Random.Range(-0.8f, 1.2f), Random.Range(-1f, 0.8f), Random.Range(-1f, 1.2f));
        Debug.Log(position);
        while (true)
        {
            this.time += Time.deltaTime;
            if (Vector3.Distance(position, this.transform.position)<0.2f)
            {
                //Debug.Log("목표 위치 변경 ");
                if (this.time > 0.7f)
                {
                    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.5f, 0.5f), Random.Range(-0.5f, 0.6f), Random.Range(-0.6f, 0.9f));
            }
            else
            {
                this.transform.position = Vector3.MoveTowards(this.transform.position, position, 0.05f);
                this.laserStaticEffect.SetActive(false);
                this.laser.enabled = false;
            }

            yield return null;
        }
    }

시간들을 조절함

+ 어떤 물체랑 부딪히면 , 이동도 안하고 레이저 발사도 안함  ===> if (this.transform.position == position) 이면 이동하고 공격하도록 만들어놨기 때문, distance가 0.2이하면 이동하고 공격하도록 수정했다 (위 코드)

 

수정 결과물

 

근데 뭐어어엉ㄴ가 .... 좀.. 맘에 안든다 왠지 모르게 .. 후..

 

부딪힐때도 오른쪽에서 부딪혔는데 왼쪽으로 날라가는게 아니라 뒤로만 날라감

contact.point를 찍어보니

x값이 작아서 많이 힘을 못받는거같다