활쏘기 연습-궁수의 전설
2023. 8. 20.

플레이어 셋팅을 하면서 처음 등장 시 기울어져서 소환되면 넘어지는 것을 방지하기 위해 rigidbody-constraints-Freeze Rotation 사용(회전을 막음)

시작시 캐릭터 소환

 

 

플레이어 이동

 

 

playercontroller수정 및 값 할당

화살발사를 위해 빈 오브젝트를 만들고 하위에 화살 오브젝트를 자식으로 넣어주었다. 자식으로 넣고 화살의 방향을 조절하고, 빈 오브젝트에 rigidbody와 ArrowControl 스크립트를 넣어주었다. 다음과 같이 작성하면 빈 오브젝트의 z축 방향으로 움직인

다.

화살 발사

몬스터를 동적 생성하는 코드

-빈 오브젝트로 MonsterGenerator를 만든후 MosnterGenerator.cs를 넣어주었다.

충돌체크, 몬스터 제거하는 RemoveArrow.cs를 몬스터 프리팹에 넣어주었다.

]

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

public class PlayerController : MonoBehaviour
{
    //변수
    private Vector3 moveDir;   
    [SerializeField] private float moveSpeed = 3f;
    [SerializeField] private float turnSpeed = 150f;
    [SerializeField] private GameObject arrow;
    [SerializeField] private Transform firePos;
    [SerializeField] private eControllType controllType;
    [SerializeField] private VariableJoystick joystick;
    public enum eControllType
    {
        Keryboad, Joystick
    }
    private Animator anim;
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        float h = 0f;
        float v = 0f;
        float r = Input.GetAxis("Mouse X");//마우스를 왼쪽으로 움직이면 음수, 오른쪽 양수 반환
        //키보드 이동-마우스를 움직이는 쪽으로 에임전환
        if (this.controllType == eControllType.Keryboad)
        {
             h = Input.GetAxis("Horizontal");
             v = Input.GetAxis("Vertical");
            if (Input.GetMouseButtonDown(0))//좌클릭시 공격
            {
                anim.SetInteger("State", 1);
                this.Fire();
            }
            else
            {
                anim.SetInteger("State", 0);//Idle
            }
        }
        else if (this.controllType == eControllType.Joystick)
        {
            h = this.joystick.Direction.x;
            v = this.joystick.Direction.y;
            if (Input.GetKeyDown(KeyCode.Space))//스페이스바로 공격
            {
                anim.SetInteger("State", 1);
                this.Fire();
            }
            else
            {
                anim.SetInteger("State", 0);//Idle
            }
        }
       
            moveDir = (Vector3.forward * v) + Vector3.right * h;
            this.transform.Translate(moveDir.normalized * this.moveSpeed * Time.deltaTime);//이동
            Vector3 angle = Vector3.up * turnSpeed * Time.deltaTime * r;
            this.transform.Rotate(angle);//Vector3.up을 축으로 회전
            
        
    }

    private void Fire()
    {
        Instantiate(arrow, firePos.position, firePos.rotation);//총알 프리팹의 인스턴스 생성
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ArrowControl : MonoBehaviour
{
    [SerializeField] private float damage = 20.0f;//파괴력
    [SerializeField] private float force = 800.0f;//발사 힘
    private Rigidbody rb;

    // Start is called before the first frame update
    void Start()
    {   
        this.rb = GetComponent<Rigidbody>();
        this.rb.AddForce(this.transform.forward * force);//전진방향으로 힘을 준다.
    }

    // Update is called once per frame
    void Update()
    {
       
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterGenerator : MonoBehaviour
{
    [SerializeField] private List<GameObject> prefabList;//동적 배열: 컬렉션은 반드시 인스턴스화
  
    // Start is called before the first frame update
    void Start()
    {
        this.GenerateMonster(GameEnums.eMonsterType.ChesterMonster, new Vector3(1.5f,0,5));
        this.GenerateMonster(GameEnums.eMonsterType.BeholderMonster, new Vector3(-1.5f, -1.5f, 3));
        this.GenerateMonster(GameEnums.eMonsterType.ChesterMonster, new Vector3(1.5f, 0, -4));
    }

  public GameObject GenerateMonster(GameEnums.eMonsterType monsterType,Vector3 initPos)
    {
        int index = (int)monsterType;//몬스터 타입 인덱스로 변경
        GameObject prefab = this.prefabList[index];     
        GameObject go = Instantiate(prefab);
        go.transform.position = initPos;        
        return go;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameEnums
{
   public enum eMonsterType
    {
        BeholderMonster,ChesterMonster
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RemoveArrow : MonoBehaviour
{
    [SerializeField]private float hp = 3;
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log(collision);

        if (collision.collider.CompareTag("Arrow"))
        {
            this.hp -= 1;
            Destroy(collision.gameObject); //arrow
            if (this.hp <= 0)
            {
                Destroy(this.gameObject);//monster 사망
                Debug.Log("몬스터 사망");
            }
        } 
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraControl : MonoBehaviour
{
    [Range(0.0f, 20.0f)] public float distance = 0.5f;
    [Range(0.0f, 10.0f)] public float height = 4.0f;
    [SerializeField] private float damping = 0.1f;
    private Vector3 velocity = Vector3.zero;
    [SerializeField] private Transform targetTr;//카메라가 따라가야할 대상
    [SerializeField] private float targetOffset = 2.0f;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 pos = targetTr.position + (-targetTr.transform.forward * distance) + (Vector3.up * height);        
        //구면 선형 보간 함수를 사용해 부드럽게 위치를 변경
        this.transform.position = Vector3.SmoothDamp(this.transform.position, pos, ref velocity, damping);
        //smoothdamp를 이용한 위치 보간
        this.transform.LookAt(targetTr.position + (targetTr.up * targetOffset));//카메라를 타겟의 좌표를 향해 회전
    }
}

조이스틱 할 수 있게 수정

조이스틱으로 이동, 공격(스페이스바)

 

myoskin