[SKKU DT] 11일차 -FPS 게임 만들기(2) -무기 만들기(폭탄, 총)

2023. 11. 13. 18:21SKKU DT

728x90
반응형

폭탄 던지기

-포물선으로 이동하게(수동적인 오브젝트에는 RigidBody 사용)

-충돌했을 때 폭탄이 사라지게 하기

-폭발 이펙트

https://assetstore.unity.com/packages/vfx/particles/war-fx-5669

 

War FX | 시각 효과 파티클 | Unity Asset Store

Add depth to your next project with War FX from Jean Moreno. Find this & more 시각 효과 파티클 on the Unity Asset Store.

assetstore.unity.com

 

 


 

 

폭탄이 어떠한 물체라도 닿으면 없어지게 하기

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

public class BombAction : MonoBehaviour
{
    //충돌했을 때
    private void OnCollisionEnter(Collision collision)
    {
        //폭탄(자기 자신) 제거
        Destroy(gameObject);
    }
}

 

 


 

 

이펙트 프리팹에 들어갈 DestroyEffect 스크립트 작성

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

public class DestroyEffect : MonoBehaviour
{
    //지속 시간
    public float destroyTime = 5.4f;
    //경과 시간
    float currentTime = 0;

    // Update is called once per frame
    void Update()
    {
        //경과 시간이 지속 시간을 초과하면 이펙트 지우기
        if (currentTime > destroyTime)
        {
            Destroy(gameObject);
        }
        //경과 시간 누적
        currentTime += Time.deltaTime;
    }
}

 

 


 

 

BombAction 스크립트에서 폭탄 없어지는 자리에 폭발 이펙트 적용

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

public class BombAction : MonoBehaviour
{
    //폭발 이펙트 변수
    public GameObject Bombeffect;
    //충돌했을 때
    private void OnCollisionEnter(Collision collision)
    {
        //이펙트 프리팹 생성
        GameObject eff = Instantiate(Bombeffect);
        //효과 위치를 폭탄의 위치로
        eff.transform.position = transform.position;
        //폭탄(자기 자신) 제거
        Destroy(gameObject);
    }
}

 

 


 

 

폭탄이 플레이어에 닿아도 터지지 않게 설정 -Layer 이용

 

레이어 생성, Player와 Bomb에 각각 적용

 

 

Physics에서 Player와 Bomb의 충돌 끄기

 

 


 

 

마우스 우클릭으로 폭탄 발사하기 -PlayerFire 스크립트 생성, 폭탄의 RigidBody 가져오기

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

public class PlayerFire : MonoBehaviour
{
    //폭탄 발사 위치 정하기
    public GameObject firePosition;
    //폭탄 오브젝트 가져오기
    public GameObject bombs;
    //투척 파워
    public float throwPower = 10f;

    void Update()
    {
        //마우스 오른쪽 버튼 입력
        if(Input.GetMouseButtonDown(1))
        {
            //폭탄 생성
            GameObject bomb = Instantiate(bombs);
            //폭탄의 위치를 발사 위치로 이동
            bomb.transform.position = firePosition.transform.position;
            //폭탄의 Rigid Body 컴포넌트를 가져옴
            Rigidbody rb = bomb.GetComponent<Rigidbody>();
            //카메라의 정면으로 폭탄에 힘을 가해서 던지기/ForceMode는 질량과 힘을 모두 생각함
            rb.AddForce(Camera.main.transform.forward * throwPower, ForceMode.Impulse);
        }
    }
}

 

폭탄 일정 시간마다 발사하기(응용)

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

public class PlayerFire : MonoBehaviour
{
    //폭탄 발사 위치 정하기
    public GameObject firePosition;
    //폭탄 오브젝트 가져오기
    public GameObject bombs;
    //투척 파워
    public float throwPower = 10f;
    //제한 시간
    float limitTime = 3f;
    //현재 시간
    float currentTime = 0;

    void Update()
    {
        //마우스 오른쪽 버튼 입력
        if(Input.GetMouseButtonDown(1) && currentTime > limitTime)
        {

            //폭탄 생성
            GameObject bomb = Instantiate(bombs);
            //폭탄의 위치를 발사 위치로 이동
            bomb.transform.position = firePosition.transform.position;
            //폭탄의 Rigid Body 컴포넌트를 가져옴
            Rigidbody rb = bomb.GetComponent<Rigidbody>();
            //카메라의 정면으로 폭탄에 힘을 가해서 던지기/ForceMode는 질량과 힘을 모두 생각함
            rb.AddForce(Camera.main.transform.forward * throwPower, ForceMode.Impulse);
            //현재 시간 초기화
            currentTime = 0;
        }
        currentTime += Time.deltaTime;
    }
}

 

 


 

 

총 쏘기 구현 -Ray

빛 자체는 Ray, 빛을 쏘는 오브젝트는 RayCast, Ray가 맞은 부분은 RayCastHit

Ray는 직선으로 쭉 오브젝트와 충돌한다. 보이지 않는 부분까지도. 이 모든 충돌은 배열로 저장된다.

 

 

PlayerFire 스크립트에 Ray 관련 기능을 추가한다.

총 이펙트는 Hierarchy에 남고 쏘면 이펙트가 해당 부분에 이동하는 방식. 처음엔 Y축 1000으로 올려 보이지 않게 한다.

 

 

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

public class PlayerFire : MonoBehaviour
{
    //폭탄 발사 위치 정하기
    public GameObject firePosition;
    //폭탄 오브젝트 가져오기
    public GameObject bombs;
    //투척 파워
    public float throwPower = 10f;
    //폭탄 제한 시간
    float limitTime = 1f;
    //폭탄 현재 시간
    float currentTime = 0;
    //총알 이펙트
    public GameObject bulletEffect;
    //파티클 시스템 가져오기
    ParticleSystem ps;

    private void Start()
    {
        //총알 이펙트의 파티클 시스템 가져오기
        ps = bulletEffect.GetComponent<ParticleSystem>();
    }

    void Update()
    {
        //마우스 오른쪽 버튼 입력
        if(Input.GetMouseButtonDown(1) && currentTime > limitTime)
        {

            //폭탄 생성
            GameObject bomb = Instantiate(bombs);
            //폭탄의 위치를 발사 위치로 이동
            bomb.transform.position = firePosition.transform.position;
            //폭탄의 Rigid Body 컴포넌트를 가져옴
            Rigidbody rb = bomb.GetComponent<Rigidbody>();
            //카메라의 정면으로 폭탄에 힘을 가해서 던지기/ForceMode는 질량과 힘을 모두 생각함
            rb.AddForce(Camera.main.transform.forward * throwPower, ForceMode.Impulse);
            //현재 시간 초기화
            currentTime = 0;
        }
        currentTime += Time.deltaTime;

        //마우스 왼쪽 버튼 입력
        if (Input.GetMouseButtonDown(0))
        {
            //Ray 생성 후 위치와 방향 설정
            Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
            //Ray가 부딪힌 대상 저장
            RaycastHit hitInfo = new RaycastHit();
            //Ray를 발사한 후 부딪힌 물체가 있으면 총알 이펙트 생성
            if(Physics.Raycast(ray, out hitInfo))
            {
                bulletEffect.transform.position = hitInfo.point; //좌표 설정
                ps.Play(); //파티클 플레이
            }
        }
    }
}

 

 

현재는 어딜 부딪히나 항상 같은 이펙트를 유지한다. 부딪히는 물체의 법선 벡터에 맞게 터지는 효과를 주도록 수정한다.

if(Physics.Raycast(ray, out hitInfo))
{
    bulletEffect.transform.position = hitInfo.point; //좌표 설정
    bulletEffect.transform.forward = hitInfo.normal; //총알 효과를 Ray가 부딪힌 지점의 법선 벡터와 일치하도록 설정
    ps.Play(); //파티클 플레이
}

 

 


 

 

크로스 헤드 (제대로) 적용하기

UI 캔버스 이미지로 Sprite 2D 이미지로 바꿔서 적용

 

 

응용(총구에 불꽃 추가하기)

728x90
반응형