0409 총알 피하기 게임 (랜덤 총알 + 유도탄 생성)

2021. 4. 9. 11:50unity

매터리얼
- 쉐이더와 텍스쳐가 합쳐진 에셋
-오브젝트의 픽셀 컬러를 결정

쉐이더
-주어진 입력에 따라 픽셀의 최종 컬러를 결정하는 코드
-질감과 빛에 의한 반사광과 빛의 굴절을 만듦

Input.GetKeyDown

Input.GetKeyUp

Input.GetKey: 키를 누르고 있는 동안 값 받기

AddForce: 관성이 적용되고, 가속이 된다.

 

using UnityEngine;

public class BulletSpawner : MonoBehaviour
{
    public GameObject bulletPrefab; //생성할 탄알의 원본 프리팹
    public float spawnRateMin = 0.5f; //최소 생성주기
    public float spawnRateMax = 3f;

    private Transform target; //발사할 대상
    private float spawnRate; //생성 주기
    private float timeAfterSpawn; //생성한 후의 시간
    // Start is called before the first frame update
    void Start()
    {
        //최근 생성 이후의 누적 시간을 0으로 초기화
        this.timeAfterSpawn = 0;
        //탄알 생성 간격을 spwanRateMin과 spawnRateMax사시에 랜덤값으로 지정
        this.spawnRate = Random.Range(this.spawnRateMin, this.spawnRateMax);
        //플레이어컨트롤러 컴포넌트를 가진 게임 오브젝트를 찾아 조준 대상으로 설정
        this.target = FindObjectOfType<PlayerController>().transform;
    }

    // Update is called once per frame
    void Update()
    {
        //timeAfterSpawn갱신
        this.timeAfterSpawn += Time.deltaTime;
        //최근 생성 지점부터 누적된 시간이 생성주기보다 크거나 같으면
        if (this.timeAfterSpawn >= this.spawnRate) 
        {
            //누적 타임 리셋
            this.timeAfterSpawn = 0;
            //bulletPrefab의 복제본을 transform.position위치와 transform.rotation회전으로 생성
            GameObject bullet = Instantiate(this.bulletPrefab, this.transform.position, this.transform.rotation);
            //생성된 bullet 오브젝트의 정면방향이 target을 향하도록 회전
            bullet.transform.LookAt(target);
        }
        
        
        //다음번 생성 간격을 spawnRateMin, spawnRateMax 사이의 랜덤으로 설정
        this.spawnRate = Random.Range(this.spawnRateMin, this.spawnRateMax);
    }
}

using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float speed = 8f;
    private Rigidbody bulletRigidbody;
    // Start is called before the first frame update
    void Start()
    {
        //게임 오브젝트에서 리지드바디 컴포넌트를 찾아 bulletRigidbody변수에 할당
        this.bulletRigidbody = this.GetComponent<Rigidbody>();

        //리지드바디의 속도 = 앞쪽 방향 * 이동 속력
        this.bulletRigidbody.velocity = this.transform.forward * speed;

        Destroy(this.gameObject, 3f); //3초 뒤에 오브젝트 제거


    }


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

    private void OnTriggerEnter(Collider other)
    {
        //충돌 감지
        if (other.tag == "Player") 
        {
            PlayerController playerController = other.GetComponent<PlayerController>();

            //상대방으로부터 플레이어컨롤러 플레이어 컨트롤러 컴포넌트 가져오는데 성공했다면
            if (playerController != null) 
            {
                playerController.Die();
            }
            //상대방의 플레이어컨트롤러 컴포넌트의 die 메서드 실행
        }
    }
}

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody playerRigidbody;
    public float speed =8f;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //if (Input.GetKey(KeyCode.UpArrow)) 
        //{
        //    this.playerRigidbody.AddForce(0,0,-this.speed);
        //}

        //if (Input.GetKey(KeyCode.DownArrow)) 
        //{
        //    this.playerRigidbody.AddForce(0, 0, this.speed);
        //}
        //if (Input.GetKey(KeyCode.LeftArrow)) 
        //{
        //    this.playerRigidbody.AddForce(this.speed, 0, 0);
        //}
        //if (Input.GetKey(KeyCode.RightArrow)) 
        //{
        //    this.playerRigidbody.AddForce(-this.speed, 0, 0);
        //}

        //수평축과 수직축의 입력값을 감지해서 저장
        float xInput = Input.GetAxis("Horizontal");
        float zInput = Input.GetAxis("Vertical");

        Debug.LogFormat("{0} {1}", xInput, zInput);
        //실제 이동속도를 입력값과 이동 속력을 사용해 결정
        float xSpeed = xInput * speed; //방향과 속도
        float zSpeed = zInput * speed;

        //벡터3 속도를 (xSpeed, 0, zSpeed)로 생성
        Vector3 newVelocity = new Vector3(xSpeed, 0, zSpeed);
        
        
        
        //이전 속도를 지우고 새로운 속도를 사용
        //관성이 무시됨
        playerRigidbody.velocity = newVelocity;

    }
    public void Die() 
    {
        this.gameObject.SetActive(false);
    }
}

 

 

 

키보드 방향으로 입력 시 캐릭터 시야방향도 변하도록 수정

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody playerRigidbody;
    public float speed =8f;

    private Animation anim;
    private Vector3 lookDirection;
    public int Hpmax = 100;
    public int hp;
    public int damage = 10;
    public bool isDie;
    public System.Action OnHit;
    public System.Action OnDie;
    // Start is called before the first frame update
    void Start()
    {
        
        this.anim = this.GetComponent<Animation>();
    }

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

        if (Input.GetKey(KeyCode.LeftArrow) ||
            Input.GetKey(KeyCode.RightArrow) ||
            Input.GetKey(KeyCode.UpArrow) ||
            Input.GetKey(KeyCode.DownArrow))

        {//수평축과 수직축의 입력값을 감지해서 저장
        //실제 이동속도를 입력값과 이동 속력을 사용해 결정
        float xInput = Input.GetAxis("Vertical");
        float zInput = Input.GetAxis("Horizontal");
        lookDirection = xInput * Vector3.forward + zInput * Vector3.right;

        Debug.LogFormat("{0} {1}", xInput, zInput);

        //키보드가 입력하는 방향으로 돌리게 만든다.
        this.transform.rotation = Quaternion.LookRotation(lookDirection);
        this.transform.Translate(Vector3.forward * speed * Time.deltaTime);

        this.anim.Play("run@loop");
        }
        else 
        {
            this.anim.Play("idle@loop");
        }
    }


    public void Die() 
    {
        isDie = true;
        this.anim.Play("die");
        this.GetComponent<CapsuleCollider>().enabled = false;
        this.playerRigidbody.velocity = Vector3.zero;
        
    }
    public void PlayAnimation(string name) 
    {
        this.anim.Play(name);
    }
    public void GetHit()
    {
        if (this.isDie) return;

        this.hp -= this.damage;
        if (this.hp <= 0) 
        {
            this.Die();
        }
        
    }