게임클라이언트 프로그래밍/R&D

Bullet Pattern R&D (Laser,LineRenderer를 이용한 공격 패턴)

Game Client Lee Hwanguk 2023. 3. 15. 00:56

#target을 향해 laser를 발사하는 패턴

 

*레퍼런스 영상

#Boss는 일정시간 충전? 하는 모션을 보여준다

#target의 방향으로 laser를 발사하며 일정한 속도로 target을 추적(회전 -Quaternion.LookRotation)한다

#laser는 target 방향으로 부드럽게 회전한다 (Quaternion.Slerp)

#target을 기준으로 세갈래로 나뉘는 레이져

#target을 일정한 속도로 추적

#기둥(오브잭트)와 충돌 또는 target과 충돌하면 레이져가 끊김

 

*참고 영상

https://www.youtube.com/watch?v=UzQTH4gOeLk&list=PL45tEBs0ZUum2OfXHweD2K2Q-DSqwaVsk&index=12 

https://www.youtube.com/watch?v=biL29u6YFpk 

https://www.youtube.com/watch?v=Da9hT7PCEUk 

#LineRenderer

https://docs.unity3d.com/kr/2018.4/Manual/class-LineRenderer.html

 

라인 렌더러 - Unity 매뉴얼

라인 렌더러(Line Renderer) 컴포넌트는 3D 공간에서 두 개 이상 지점의 배열을 사용하고 각각을 연결하는 직선을 그립니다. 따라서 하나의 라인 렌더러 컴포넌트는 단순한 직선에서 시작해서 복잡

docs.unity3d.com

#RaycastHit2D hit = Physics2D.Raycast 

https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html

 

Unity - Scripting API: Physics2D.Raycast

A raycast is conceptually like a laser beam that is fired from a point in space along a particular direction. Any object making contact with the beam can be detected and reported. This function returns a RaycastHit object with a reference to the Collider t

docs.unity3d.com

#Quaternion.LookRotation

https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

 

Unity - Scripting API: Quaternion.LookRotation

Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X. Returns identity if the magnitude of forward is zero. If forward and upwards are colinear, or if the

docs.unity3d.com

#Quaternion.Slerp

https://docs.unity3d.com/ScriptReference/Quaternion.Slerp.html

 

Unity - Scripting API: Quaternion.Slerp

Use this to create a rotation which smoothly interpolates between the first quaternion a to the second quaternion b, based on the value of the parameter t. If the value of the parameter is close to 0, the output will be close to a, if it is close to 1, the

docs.unity3d.com

 

#1. 충전을 연출하는 오브잭트를 활성/ 비활성 ->충전오브잭트가 비활성되면 Laser발사

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

public class BossLaserTest : MonoBehaviour
{
    private LineRenderer laser; 
    
    public Transform firepoint; 
    public Transform target;
    public GameObject charging;

    private float chargingTime = 3f; //충전 시간
    private float delta;
    private void Start()
    {
        laser = GetComponent<LineRenderer>();
        //this.charging.gameObject.SetActive(false);

        laser.startWidth = .57f; //laser의 시작 넓이
        laser.endWidth = .57f; //끝 넓이

        //1. Boss가 일정 시간 충전? 후 Laser발사 (charging -> laser)
        this.ChargingLaser();
        Invoke("FireLaser", this.chargingTime); //charging 이후 
        //2. 
    }
    private void Update()
    {
        this.delta += Time.deltaTime;
        if (this.delta >= chargingTime)
        {
            this.charging.gameObject.SetActive(false);
            Debug.Log("charging off");
            Debug.LogFormat("{0}", this.charging.activeSelf);
            this.delta = 0;
        }
    }

    private void ChargingLaser()
    {
        this.charging.gameObject.SetActive(true);
        Debug.LogFormat("{0}",this.charging.activeSelf);
        Debug.Log("charging on");       
    }
    private void FireLaser() //firepoint->target
    {
        laser.SetPosition(0, firepoint.position); //0번 인덱스 (start)
        laser.SetPosition(1, this.target.position); //1번 인덱스 (end)
        Quaternion targetRotation = Quaternion.LookRotation(this.target.position - this.firepoint.position);
        this.firepoint.rotation = Quaternion.Slerp(this.firepoint.rotation, targetRotation, 1 * Time.deltaTime);
        Debug.Log("fire on");
    }
}

 

 

#LineRendder를 이용하여 여러가지 공격패턴을 구현할 수 있다

*공격 예상 경로+돌진 공격

 

*탕탕특공대 보스 패턴을 참고했다. 돌진 공격 전 라인랜더러를 통해 경고선이 생기고 그 방향으로 돌진한다.
        //공격 궤적 예상 라인
        var direction = (target.position - laser.transform.position).normalized; //방향
        var distance = Vector3.Distance(target.position, laser.transform.position); //거리

        // 라인 랜더러 시작점
        laser.SetPosition(0, this.firepoint.transform.position);

        // 라인 랜더러 끝점
        laser.SetPosition(1, this.target.position);

        // laser의 포지션 이동
        this.transform.position += direction * 7f * Time.deltaTime;