[Cyphers] 클레어 평타(LC), 클레어 클렌징빔(LCRC)로 타격시 사운드 추가
2023. 10. 12.

평타(LC) 사운드 추가

-평타의 사운드는 평타를 발사할때 일반적으로 나는 소리, 평타가 어떤 물체에 부딪히는 경우에 발생하는 충격파음, 프리즘에 반사된 평타의 충격파으로 총 세가지가 있다.

Audio Source 컴포넌트 추가
오디오 실행
LC 충돌 사운드/ 프리즘 LC 충돌 사운드

https://youtu.be/OSaB6QA9MiU

평타+프리즘 사운드 구현

프리즘(RC) 사운드 추가

프리즘 생성 사운드

 

클렌징빔(LCRC) 사운드 추가

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
using UnityEngine.InputSystem.Processors;
using static UnityEditor.PlayerSettings;
using UnityEngine.UI;
using TMPro;

public class ClareController : MonoBehaviour
{
    [SerializeField] MouseController mouse;
    [SerializeField] private Transform clareHandTrans;
    [SerializeField] private GameObject beamGo;
    [SerializeField] private GameObject beamImpactGo;
    [SerializeField] private GameObject prismGo;
    [SerializeField] private LineRenderer lr;
    [SerializeField] private Transform LCPos;
    [SerializeField] private PlayerInput playerInput;
    [SerializeField] private Transform LCRCPos;
    //----------------------UI-------------------------------------
    [SerializeField] private GameObject RCDisable;
    [SerializeField] private GameObject LCRCDisable;
    //-------------------Audio-------------------------------------
    [SerializeField] private AudioClip lcStart;
    [SerializeField] private AudioClip lcImpact;
    [SerializeField] private AudioClip lcPrismImpact;
    [SerializeField] private AudioClip prismCreate;
    [SerializeField] private AudioClip lcRcStart;
    [SerializeField] private AudioClip lcRcDialogue;

    private GameObject newBeamGo;
   
    private GameObject impactGo = null;
    private List<GameObject> goList = new List<GameObject>();
    private List<GameObject> impactGoList = new List<GameObject>();
    private Vector3 moveDir;
    private Animator anim;
    private Ray ray2;
    private Ray ray3;
    private RaycastHit hit;
    private ParticleSystemRenderer psr;

    private Coroutine prismRoutine;
    private Coroutine lcBeamRoutine;
    private bool isLC;
    private bool isLCRC;
    private bool isDie;
    private bool isLCRCCool;
    private List<GameObject> beamPools = new List<GameObject>();
    private List<GameObject> impactPools = new List<GameObject>();
    private new AudioSource audio;//new 한정자
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animator>();
       
        this.BeamPool();
        this.ImpactPool();
        this.prismGo = Instantiate<GameObject>(this.prismGo);
        this.beamImpactGo = Instantiate<GameObject>(this.beamImpactGo);
        this.newBeamGo = Instantiate<GameObject>(this.beamGo);
        this.psr = this.newBeamGo.GetComponent<ParticleSystemRenderer>();
        this.audio = GetComponent<AudioSource>();
        this.newBeamGo.SetActive(false);
        this.prismGo.SetActive(false);
        this.beamImpactGo.SetActive(false);
        lr.enabled = false;

    }
    private void BeamPool()
    {
        for (int i = 0; i < 5; i++)
        {
            GameObject go = Instantiate<GameObject>(this.beamGo);
            go.SetActive(false);
            this.beamPools.Add(go);//Add on List
        }
    }
    private void ImpactPool()
    {
        for(int i = 0; i < 5; i++)
        {
            GameObject go = Instantiate<GameObject>(this.beamImpactGo);
            go.SetActive(false);
            this.impactPools.Add(go); ;//Add on List
        }
    }
    private GameObject GetBeamInPool()
    {
        foreach(GameObject beam in beamPools)
        {
            if(beam.activeSelf == false)
            {//비활성화일떄에만
                return beam;
            }
        }
        return null;
    }
    private GameObject GetImpactInpool()
    {
        foreach(GameObject impact in impactPools)
        {
            if(impact.activeSelf == false)//비활성화일때만
            {
                return impact;
            }
        }
        return null;
    }
    private GameObject CreateBeam(Vector3 position)
    {
        GameObject go = this.GetBeamInPool();
        go.transform.position = position;
        go.SetActive(true);
        return go;
    }
    private GameObject CreateImpact(Vector3 position)
    {
        GameObject go = this.GetImpactInpool();
        go.transform.position = position;
        go.SetActive(true);
        return go;
    }

    // Update is called once per frame
    void Update()
    {
        //  Debug.Log(this.playerInput.actions["LCRC"].WasPressedThisFrame());

        if (moveDir != Vector3.zero)
        {
            if (this.moveDir.z > 0)//forward
            {
                //this.transform.rotation = Quaternion.LookRotation(moveDir); ;//진행방향으로 회전
                this.transform.Translate(Vector3.forward * 4.0f * Time.deltaTime);//이동
                if (this.moveDir.x == 0)//forward
                {
                    this.anim.SetInteger("State", 1);//move forward
                }
                else if (this.moveDir.x > 0)
                {
                    this.anim.SetInteger("State", 2);//move forward rightCross
                }
                else if (this.moveDir.x < 0)
                {
                    this.anim.SetInteger("State", 4);//move forward leftCross
                }
            }
            else if (this.moveDir.z < 0)//backward
            {
                this.transform.Translate(this.moveDir * 4.0f * Time.deltaTime);//이동
                if (this.moveDir.x == 0)//backward
                {
                    this.anim.SetInteger("State", 3);//move backward
                }
                else if (this.moveDir.x > 0)
                {
                    this.anim.SetInteger("State", 7);//move backward rightCross
                }
                else if (this.moveDir.x < 0)
                {
                    this.anim.SetInteger("State", 8);//move backward leftCross
                }
            }
            else
            {//stay but press left or right
                this.transform.Translate(this.moveDir * 4.0f * Time.deltaTime);//이동
                if (this.moveDir.x < 0)
                {
                    this.anim.SetInteger("State", 5);//move left
                }
                else
                {
                    this.anim.SetInteger("State", 6);//move right
                }
            }
        }
        else
        {
           // if (!isLCRC)
            {
                this.anim.SetInteger("State", 0); //idle
            }
            int count = 0;
            if (isLCRC&& count<1)
            {//play animation once
              
                count++;
            }
        }
    }
   
    private IEnumerator CoLCBeam()
    {
        yield return new WaitForSeconds(0.2f);
       // this.anim.SetInteger("State", 10);//LC animation
        this.newBeamGo.SetActive(true);
        this.newBeamGo.transform.position = this.clareHandTrans.position;
 
        if (mouse.hit.point != Vector3.zero && mouse.hit.collider.tag != "Player")
        {
            this.newBeamGo.transform.LookAt(mouse.hit.point);

        }
        else
        {
            this.newBeamGo.transform.LookAt(this.LCPos);
     
        }
        yield return new WaitForSeconds(0.3f);
        this.newBeamGo.SetActive(false);
       // this.anim.SetInteger("State", 0);//Idle
    }

    private IEnumerator CoLCBeamImpact(float distance)
    {
        yield return new WaitForSeconds(0.2f);
       // this.anim.SetInteger("State", 10);//LC animation
        this.newBeamGo.SetActive(true);
       
        this.psr.lengthScale = distance;
        this.newBeamGo.transform.position = this.clareHandTrans.position;

        if (mouse.hit.point != Vector3.zero && mouse.hit.collider.tag != "Player")
        {
            this.newBeamGo.transform.LookAt(mouse.hit.point);
        }
        else
        {
            this.newBeamGo.transform.LookAt(this.LCPos);
        }    
        yield return new WaitForSeconds(0.3f);
        this.newBeamGo.SetActive(false);
        //this.anim.SetInteger("State", 0);//Idle
    }

    private IEnumerator CoBeamImpact()
    {
        yield return new WaitForSeconds(0.2f);
        this.beamImpactGo.SetActive(true);
        this.beamImpactGo.transform.position = this.hit.point;
        yield return new WaitForSeconds(0.3f);
        this.beamImpactGo.SetActive(false);
    }

    public void OffCleansingBeamImpact()
    {
        this.beamImpactGo.SetActive(false);
    }
 
    private IEnumerator CoCleansingBemaCool()
    {
        float coolTime = 3f;
        float leftTime = 3f;
        Image lcrcDisableImage = this.LCRCDisable.GetComponentInChildren<Image>();
        TextMeshProUGUI lcrcCoolTxt = this.LCRCDisable.GetComponentInChildren<TextMeshProUGUI>();

        while (leftTime > 0f)
        {
            this.isLCRCCool = true;
            this.LCRCDisable.SetActive(true);
            leftTime -= Time.deltaTime;
            lcrcDisableImage.fillAmount = leftTime / coolTime;
            int intLeftTime = (int)leftTime;
            lcrcCoolTxt.text = intLeftTime.ToString();
            yield return null;
        }
        this.LCRCDisable.SetActive(false);
        this.isLCRCCool = false;
    }
    private IEnumerator CoCleansingBeamAnim()
    {
        yield return null;
        this.audio.PlayOneShot(this.lcRcStart, 1.8f);
        this.audio.PlayOneShot(this.lcRcDialogue, 1.46f);
        this.anim.SetInteger("State", 11);
        while (isLCRC)
        {
            yield return null;
            this.anim.SetInteger("State", 12);//LCRC animation
            //yield return null;
        }
    }
    private IEnumerator CoCleansingBeam()
    {
        int count=0;
        int count2 = 0;
        int count3 = 0;
        int collsLength=0;

      //  this.isPrism = false;
       
        while (isLCRC) //for rotate with player
            {
            this.newBeamGo.SetActive(true);
            
            this.psr.lengthScale = 10;
                var psr = this.newBeamGo.GetComponent<ParticleSystem>().main;
                psr.startSizeXMultiplier = 3f;

                Vector3 ray3Direction = this.LCPos.position - this.LCRCPos.position;
                this.ray3 = new Ray(this.LCRCPos.position, ray3Direction);
                Debug.DrawRay(this.ray3.origin, this.ray3.direction * 10f, Color.green, 0.5f);
                this.newBeamGo.transform.position = this.LCRCPos.position;
                this.newBeamGo.transform.LookAt(this.LCPos);

                if (Physics.SphereCast(this.ray3.origin, 0.2f, this.ray3.direction, out hit, 10f) && !hit.collider.CompareTag("Player"))
                {
                    // Debug.Log(hit.collider);
                    this.beamImpactGo.SetActive(true);
                    this.beamImpactGo.transform.position = hit.point;
                    if (hit.collider.CompareTag("Prism"))
                    {  //  Debug.LogFormat("count: {0}", count);                   
                       //프리즘 범위내에 개체들을 스캔
                        var layerMask = 3 << LayerMask.NameToLayer("Tower");
                        Collider[] colls = Physics.OverlapSphere(this.prismGo.transform.position, 5f, layerMask);

                        collsLength = colls.Length;
                        if (count < colls.Length)
                        {
                            float distance = Vector3.Distance(this.prismGo.transform.position, colls[count].gameObject.transform.position);

                            this.goList.Add(this.PrismCleansingBeam(distance, colls[count].gameObject.transform.position));
                            this.impactGoList.Add(this.PrismCleansingBeamImpact(distance, colls[count].gameObject.transform.position));
                            count++;
                        }

                    }
                    else
                    {//hitting something but which is not prism
                     //  Debug.LogFormat("count2: {0}",count2);                  
                        if (count2 < collsLength)
                        {
                            this.goList[count2].SetActive(false);
                            this.impactGoList[count2].SetActive(false);
                            count2++;
                        }
                        else
                        {
                            count2 = 0;
                        }
                        count = 0;
                    }

                }
                else
                {//hit nothing
                    this.beamImpactGo.SetActive(false);
                    count = 0;
                    //   Debug.LogFormat("{0}",count3);

                    if (count3 < collsLength)
                    {
                        this.goList[count3].SetActive(false);
                        this.impactGoList[count3].SetActive(false);
                        count3++;
                    }
                    else
                    {
                        count3 = 0;
                    }

                }

            
            yield return null;
            
        }

        

    }

    private void OnDrawGizmos()
    {
        if (hit.point != Vector3.zero && isLCRC)
        {
            Gizmos.color = Color.green;          
            Gizmos.DrawWireSphere(this.ray3.origin + this.ray3.direction * 10f, 0.2f);
        }
    }
    private IEnumerator CoOffCleansingBeam()
    {
        yield return null;
      //  this.anim.SetInteger("State", 0);
        var psr = this.newBeamGo.GetComponent<ParticleSystem>().main;
        psr.startSizeXMultiplier = 1f;
        
        this.newBeamGo.SetActive(false);
        this.beamImpactGo.SetActive(false);
       
        for (int i = 0; i < this.goList.Count; i++)
        {
            this.goList[i].SetActive(false);
            this.impactGoList[i].SetActive(false);
        }
    }
    private IEnumerator CoCreatePrism()
    {
        float coolTime = 7f;
        float leftTime = 7;
        Image rcDisableImage = this.RCDisable.GetComponentInChildren<Image>();
        TextMeshProUGUI rcCoolTxt = this.RCDisable.GetComponentInChildren<TextMeshProUGUI>();

        this.audio.PlayOneShot(this.prismCreate, 1.952f);
        this.RCDisable.SetActive(true);
        this.prismGo.SetActive(true);
        this.prismGo.transform.position = this.LCPos.position;
        while (leftTime > 0f)
        {
            leftTime -= Time.deltaTime;
            rcDisableImage.fillAmount = leftTime/coolTime;
            int intLeftTime = (int)leftTime;
            rcCoolTxt.text = intLeftTime.ToString();
            yield return null;
        }
      //  yield return new WaitForSeconds(coolTime);
        this.prismGo.SetActive(false);
        this.RCDisable.SetActive(false);
    }
    private IEnumerator CoPrismAnim()
    {
        yield return null;
        this.anim.SetInteger("State", 13);      
    }

    private IEnumerator CoPrismLCBeamImpact(float distance, Vector3 target)
    {
        yield return new WaitForSeconds(0.2f);
        GameObject go = this.CreateBeam(this.prismGo.transform.position);  //create GameObject Beam
        GameObject impactGo = null;
        Vector3 targetPos = new Vector3(target.x, target.y + 1f, target.z);
        //Create Ray
        Ray ray = new Ray(this.prismGo.transform.position, targetPos - this.prismGo.transform.position);
        Debug.DrawRay(ray.origin, ray.direction * distance, Color.yellow, 0.3f);
        //Check Ray Hit
        if (Physics.Raycast(ray.origin, ray.direction, out hit, distance + 1f))
        {
        //    Debug.Log("Hit impact!!");
        //  Debug.LogFormat("hit Point: {0}", hit.point);           
            impactGo = this.CreateImpact(hit.point);
            
        }
        var parRenderer = go.GetComponent<ParticleSystemRenderer>();
        parRenderer.lengthScale = distance + 1f;
        var psr = go.GetComponent<ParticleSystem>().main;
        psr.startSizeXMultiplier = 1f;

        go.transform.LookAt(targetPos);
        yield return new WaitForSeconds(0.3f);
        go.SetActive(false);
        if (impactGo != null)
        {
            impactGo.SetActive(false);
        }
    }
    private IEnumerator CoLCAnim()
    {

        yield return null;
        this.audio.PlayOneShot(this.lcStart, 1.0f);
        this.anim.SetInteger("State", 10);//LC animation
        yield return new WaitForSeconds(0.5f);
        this.anim.SetInteger("State", 0);//Idle
    }
    private GameObject PrismCleansingBeam(float distance, Vector3 target)
    {
        GameObject go = this.CreateBeam(this.prismGo.transform.position);//create GameObject Beam
       
        Vector3 targetPos = new Vector3(target.x, target.y + 1f, target.z);
       
        var parRenderer = go.GetComponent<ParticleSystemRenderer>();
        parRenderer.lengthScale = distance + 1f;
        var psr = go.GetComponent<ParticleSystem>().main;
        psr.startSizeXMultiplier = 3f;
        
        go.transform.LookAt(targetPos);
        return go;
    }
  private GameObject PrismCleansingBeamImpact(float distance,Vector3 target)
    {  //Create Ray
        GameObject go = null;
        Vector3 targetPos = new Vector3(target.x,target.y + 1f, target.z);

        Ray ray = new Ray(this.prismGo.transform.position, targetPos - this.prismGo.transform.position);
        Debug.DrawRay(ray.origin, ray.direction * distance, Color.green, 0.5f);
        //Check Ray Hit
        if (Physics.SphereCast(ray.origin, 0.2f, ray.direction, out hit, distance))
        {
         go = this.CreateImpact(hit.point);
        }
        return go;
    }
    private void ScannedByPrism()
    {
        var layerMask = 3 << LayerMask.NameToLayer("Tower");
        Collider[] colls = Physics.OverlapSphere(this.prismGo.transform.position, 5f, layerMask);
        for(int i=0;i<colls.Length;i++)
       // foreach(Collider coll in colls)
        {
            float distance = Vector3.Distance(this.prismGo.transform.position, colls[i].gameObject.transform.position);
         //  Debug.LogFormat("distance: {0}",distance);
            StartCoroutine(this.CoPrismLCBeamImpact(distance,colls[i].gameObject.transform.position));
        }
    }

    public void OnMove(InputAction.CallbackContext ctx)
    {
        Vector2 dir = ctx.ReadValue<Vector2>();
        this.moveDir = new Vector3(dir.x, 0,dir.y);//2차원 좌표를 3차원 좌표로 변환
    }

    public void OnLC(InputAction.CallbackContext ctx)
    {      
            if (ctx.performed)
            {
            StartCoroutine(this.CoLCAnim());
                     Vector3 ray2Direction;
                    if (mouse.hit.point != Vector3.zero)
                    {
                        ray2Direction = mouse.hit.point - this.clareHandTrans.position;
                    }
                    else
                    {
                        ray2Direction = LCPos.position - this.clareHandTrans.position;
                    }
                    this.ray2 = new Ray(this.clareHandTrans.position, ray2Direction);
                    float lcDistance = 8f;

                    if (Physics.Raycast(this.ray2.origin, this.ray2.direction, out hit, lcDistance) && !hit.collider.CompareTag("Player"))
                    {
                        // Debug.LogFormat("LC Hit! Distance : {0}", hit.distance);
                        Debug.DrawRay(this.ray2.origin, this.ray2.direction * lcDistance, Color.yellow, 0.5f);
                        StartCoroutine(this.CoLCBeamImpact(hit.distance));
                        StartCoroutine(this.CoBeamImpact());

                        if (hit.collider.CompareTag("Prism"))
                        {
                         //   Debug.Log("Prism");
                            this.ScannedByPrism();
                            this.audio.PlayOneShot(this.lcPrismImpact, 1f);
                        }
                      else
                      {
                       this.audio.PlayOneShot(this.lcImpact, 1f);
                      }
                    }
                    else
                    {
                        if (this.lcBeamRoutine != null)
                        { StopCoroutine(this.lcBeamRoutine); }
                        this.lcBeamRoutine = StartCoroutine(this.CoLCBeam());
                    }
                }
            
        
    }

    public void OnLCRC(InputAction.CallbackContext ctx)
    {              
        this.playerInput.actions["LC"].Disable();//if LCRC performed, Disable LC Action 
        this.playerInput.actions["RC"].Disable();//if LCRC performed, Disable RC Action 

        if (ctx.interaction is HoldInteraction && ctx.duration != 0)//holding
            {
            if (ctx.performed && !isLCRCCool)
            {
                this.isLCRC = true;
                StartCoroutine(this.CoCleansingBeam());
                StartCoroutine(this.CoCleansingBemaCool());
                StartCoroutine(this.CoCleansingBeamAnim());
              
            }
            }
        else if (ctx.interaction is PressInteraction)//버튼에서 손을 떼면
        {
            if (ctx.performed)
            {
                this.isLCRC = false;
                StopCoroutine(this.CoCleansingBeam());
                StopCoroutine(this.CoCleansingBeamAnim());
                StartCoroutine(this.CoOffCleansingBeam());
           //     Debug.Log("release!");                       
            }

            this.playerInput.actions["LC"].Enable();//LCRC Button Release, Enable LC action
            this.playerInput.actions["RC"].Enable();//Enable RC Action 
        }
        }
    public void OnRc(InputAction.CallbackContext ctx)
    {
        if (ctx.performed && !this.prismGo.activeSelf)//prism cannot be activated if it's already activated
        {
          //  if(this.prismGo.activeSelf)
            Debug.Log("RC!!");
          
              this.prismRoutine = StartCoroutine(this.CoCreatePrism());
              StartCoroutine(this.CoPrismAnim());
            
        }

    }
    public void OnShiftLC(InputAction.CallbackContext ctx)
    {
        this.playerInput.actions["LC"].Disable();//if LCRC performed, Disable LC Action 
        if (ctx.performed)
        {
            Debug.Log("Shift LC!");
            
        }
        this.playerInput.actions["LC"].Enable();//LCRC Button Release, Enable LC action
    }
}
myoskin