본문 바로가기
Unity 포트폴리오/플젝2. 3D FPS게임

Unity FPS : PowerShot 및 Charging 애니메이션 구현

by jjiing 2022. 6. 21.

(본 글은 프로젝트 중 공부했던 내용을 개인적으로 기록하기 위한 용도입니다.)

 

 

 

플레이어가 일반 총알 발사 외에도 몬스터를 적중시키면 스킬게이지를 채워 큰 데미지를 가지는 powershot을 쏠 수 있게 구현했다. 

스킬게이지가 차오를 때마다 무기 위에있는 fuelcell이라는 것이 위로 올라오게끔 구현했다.

몬스터를 적중해 fuelcellRatio가 1에서 0이 되면 사진처럼 총 위에 연료통이 위로 올라오고 스킬에 초록불이 들어온다.

 

script

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

public class GunFuelCellControl : MonoBehaviour
{
    public GameObject[] FuelCells;
    public Vector3 FuelCellUsedPosition;
    public Vector3 FuelCellUnusedPosition;
    
    Gun gun;
    public float fuelCellRatio;

    //effect
    public GameObject powerShotEffect;
    public GameObject powerShotFlash;

    //Audio
    public AudioSource audioSource;
    public AudioClip powerShotFire;


    void Start()
    {
        FuelCellUsedPosition = new Vector3(0f, 0.1f, 0f);
        FuelCellUnusedPosition = new Vector3(0f, 0f, 0f);

        gun = GetComponent<Gun>();
        fuelCellRatio = 1;

        audioSource = GetComponent<AudioSource>();
    }

    void Update()
    {
        //몬스터 적중할 때마다 fuelCell 올라오게 하는 애니메이션
        UseBulletFuelCell();

        //파워샷 발사 함수
        if (gun.FuelCellRatio <= 0 && !gun.isReload)
        {
            if (Input.GetKeyDown(KeyCode.Q))
                PowerShot();
        }

    }
    private void PowerShot()
    {

        //오디오
        audioSource.clip = powerShotFire;
        audioSource.Play();
        //이펙트
        var flashInstance = Instantiate(powerShotFlash, gun.weaponMuzzle.position, gun.weaponMuzzle.rotation);
        flashInstance.transform.forward = gameObject.transform.forward;
        var flashPs = flashInstance.GetComponent<ParticleSystem>();
        Destroy(flashInstance, flashPs.main.duration);

        //발사
        GameObject powerShot = Instantiate(powerShotEffect, gun.powerShotPoint.position, gun.powerShotPoint.rotation);
        Rigidbody powerShotRigid = powerShot.GetComponent<Rigidbody>();
        powerShotRigid.velocity = transform.forward * 120f;

        gun.FuelCellRatio = 1;//ratio초기화


    }
    
    //FuelCell을 부드럽게 이동시키기 위해 lerp랑 inversLerp사용
    private void UseBulletFuelCell()
    {
        for (int i = 0; i < FuelCells.Length; i++)
        {
            float length = FuelCells.Length;
            float lim1 = i / length;
            float lim2 = (i + 1) / length;

            float value = Mathf.InverseLerp(lim1, lim2, gun.FuelCellRatio); //적중하면 1 ->0으로 줄어드는 ratio
            value = Mathf.Clamp01(value);
            FuelCells[i].transform.localPosition =
                Vector3.Lerp(FuelCellUsedPosition, FuelCellUnusedPosition, value);

        }
    }
 
    
}