게임개발/게임엔진 응용 프로그래밍

절대강좌 유니티 (2) 총 발사

pudding81 2024. 3. 13. 14:27

 

 

 

 

 

총알 컨트롤러

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

public class BulletCtrl : MonoBehaviour
{
    public float damage=20f;
    public float force = 1500f;
    private Rigidbody rb;
   


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.AddForce(transform.forward * force);
       
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

플레이어에 발사 스크립트 붙임 

- 발사하기 

- 오디오 추가하기 

- 발사지점 효과 넣기  muzzleFlash

 

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

public class FireCtrl : MonoBehaviour
{
    public GameObject bulletprefab;
    public Transform firepoint;
    
    private AudioSource audioSource;
    public AudioClip fireFlash;
    private MeshRenderer muzzleFlash;
    private Coroutine muzzleFlashCoroutine;

    private void Start()
    {
        audioSource = GetComponent<AudioSource>();   
        muzzleFlash = this.firepoint.GetComponentInChildren<MeshRenderer>();
        muzzleFlash.enabled = false;

    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Fire();
            
        }
    }


    private void Fire()
    {
        Instantiate(bulletprefab, firepoint.position,firepoint.rotation);
       
       audioSource.PlayOneShot(fireFlash,1f);


        if (muzzleFlashCoroutine != null) StopCoroutine(muzzleFlashCoroutine);

        this.muzzleFlashCoroutine = StartCoroutine(this.ShowMuzzleFlash());

    }


    IEnumerator ShowMuzzleFlash()
    {
        Vector2 offset = new Vector2(Random.Range(0, 2), Random.Range(1, 2)) * 0.5f;
        muzzleFlash.material.mainTextureOffset = offset;
        float angle = Random.Range(0, 360);
        muzzleFlash.transform.localRotation = Quaternion.Euler(0, 0, angle);


        float scale = Random.Range(1, 2);
        muzzleFlash.transform.localScale = Vector3.one * scale;





        muzzleFlash.enabled = true;
        yield return new WaitForSeconds(0.2f);
        muzzleFlash.enabled = false;

    }
}

 

총알이 충돌할 경우 사라지는 스크립트 

스파크 효과 넣기 

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

public class RemoveBullet : MonoBehaviour
{
    public GameObject sparkEffectPrefab;
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.CompareTag("Bullet"))
        {
            //첫번째 충돌 지점의 정보 추출 
            ContactPoint contactPoint = collision.contacts[0];

            DrawArrow.ForDebug(contactPoint.point, -contactPoint.normal, 10, Color.red);

            //충돌한 총알의 법선 벡터를 쿼터니언으로 변환 
            Quaternion rot = Quaternion.LookRotation(-contactPoint.normal);


           GameObject spark= Instantiate(sparkEffectPrefab,collision.transform.position,Quaternion.identity);

            Destroy(spark,0.5f);


            Destroy(collision.gameObject);
        }
    }


}

 

 

 

 

 

드럼통 컨트롤러

- 총알 3번 맞으면 위로 날아가면서 폭발하기

- 폭발 주변 반경으로 간접 영향 주기

- 폭발 효과 넣기 

- 드럼통 텍스처 3종 랜덤으로 변하기

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

public class BarrelCtrl : MonoBehaviour
{
    private int hitCount =0;
    private Transform trans;
    private Rigidbody rb;
    public GameObject explosionprefab;
    public Texture[] textures;
    private new MeshRenderer renderer;

    //폭발반경
    public float radius = 10f;


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        trans = GetComponent<Transform>();

        // 자식 렌더러 
        renderer = GetComponentInChildren<MeshRenderer>();
        int index = Random.Range(0, textures.Length);
        renderer.material.mainTexture = textures[index];


    }

    
    void Update()
    {
        

    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.collider.CompareTag("Bullet"))
        {
            if(++hitCount==3)
            {
                ExplodeBarrel();

            }

        }


    }

    private void ExplodeBarrel()
    {
       
        GameObject go = Instantiate(explosionprefab, trans.position,Quaternion.identity);

        Destroy(go,5f);

       // rb.mass = 1.0f;
       // rb.AddForce(Vector3.up * 1500);

        //간접 폭발력 전달
        IndirectDamage(trans.position);

        Destroy(gameObject, 3);

    }

    private void IndirectDamage(Vector3 pos)
    {
        Collider[] colls = Physics.OverlapSphere(pos, radius, 1<<3); // 3번 레이어만 사용

        foreach (var coll in colls)
        {
            var rb = coll.GetComponent<Rigidbody>();
            rb.mass = 1.0f;
            rb.constraints = RigidbodyConstraints.None;
            rb.AddExplosionForce(1500, pos, radius, 1200);

        }
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(this.transform.position,radius);


       
    }
}

 

기즈모 그리기 스크립트 추가 

 

https://gist.githubusercontent.com/MatthewMaker/5293052/raw/12c5183be07abee19752d2596177d6264ba50ace/DrawArrow.cs