[패스트캠퍼스 수강 후기] 올인원 패키지 : 유니티 포트폴리오 완성 100% 환급 챌린지 45회차 미션 시작합니다.

04. 배틀로얄 - 35, 36 번을 진행합니다.



이번시간에는 무기를 집고, 던지고 등의 무기와의 Interactive 동작들을 하는 스크립트를 작성할 예정입니다.




사용하게될 Prefabs가 위와 같이 준비되어 있습니다.



그리고 드디어 전에 만들었던 Effect Tool 창에서 Effect에 대한 설정을 해줍니다.



SoundTool 설정해보다가 문제가 있어서 확인해보니 코드 변경이 필요한 부분이 있네요.
위와 같이 수정을 해줍니다 ^^;;;


SoundTool도 마찬가지로 위와 같이 설정을 해줍니다.



Contents 폴더를 생성하고 InteractiveWeapon 스크립트를 생성합니다.
Player 폴더 밑에 ShootBehaviour 스크립트를 생성합니다.



public class ShootBehaviour : GenericBehaviour
{
    /// <summary>
    /// 인벤토리 역할을 하게 될 함수.
    /// </summary>
    public void AddWeapon(InteractiveWeapon weapon) {
    }
}



/// <summary>
/// 충돌체를 생성해서 무기를 주을 수 있도록 한다.
/// 루팅했으면 충돌체는 제거.
/// 무기를 다시 버릴 수도 있어야 하며, 충돌체를 다시 붙여줍니다.
/// 관련해서 UI도 컨트롤할 수 있어야 하고 ShootBehaviour에 주은 무기를 넣어주게 됩니다.
/// </summary>
public class InteractiveWeapon : MonoBehaviour
{
    public string label_weaponName; // 무기이름.
    public SoundList shotSound, reloadSound, pickSound, dropSound, noBulletSound;
    public Sprite weaponSprite;
    public Vector3 rightHandPosition; // 플레이어 오른손 보정 위치
    public Vector3 relativeRotation; // 플레이어 맞춘 보정을 위한 회전값.
    public float bulletDamage = 10f;
    public float recoilAngle; // 반동
    public enum WeaponType { NONE, SHORT, LONG, }
    public enum WeaponMode { SEMI, BURST, AUTO, }
    public WeaponType weaponType = WeaponType.NONE;
    public WeaponMode weaponMode = WeaponMode.SEMI;
    public int burstSize = 1;
    
    public int currentMagCapacity, totalBullets; // 현재 탄창 양과 소지하고 있는 전체 총알량
    private int fullMag, maxBullets; // 재장전시 꽉 채우는 탄의 양과 한번에 채울 수 있는 최대 총알수
    private GameObject player, gameController;
    private ShootBehaviour playerInventory;
    private BoxCollider weaponCollider;
    private SphereCollider interactiveRadius; // 무기 감지 반경.
    private Rigidbody weaponRigidbody;
    private bool pickable;
    // UI
    public GameObject screenHUD;
    public WeaponUIManager weaponHUD;
    private Transform pickHUD;
    public Text pickupHUD_Label;
    
    public Transform muzzleTransform;
    
    private void Awake() {
        gameObject.name = label_weaponName;
        gameObject.layer = LayerMask.NameToLayer(TagAndLayer.LayerName.IgnoreRayCast);
        foreach (Transform tr in transform)
            tr.gameObject.layer = LayerMask.NameToLayer(TagAndLayer.LayerName.IgnoreRayCast);
        player = GameObject.FindGameObjectWithTag(TagAndLayer.TagName.Player);
        playerInventory = player.GetComponent<ShootBehaviour>();
        gameController = GameObject.FindGameObjectWithTag(TagAndLayer.TagName.GameController);
        
        if (weaponHUD == null) {
            if (screenHUD == null) screenHUD = GameObject.Find("ScreenHUD");
            weaponHUD = screenHUD.GetComponent<WeaponUIManager>();
        }
        if (pickHUD == null) pickHUD = gameController.transform.Find("PickupHUD");
        
        // 인터랙션을 위한 충돌체 설정
        weaponCollider = transform.GetChild(0).gameObject.AddComponent<BoxCollider>(); // Child에는 Box, 본인에게는 Sphere를 붙이려고..
        CreateInteractiveRadius(weaponCollider.center);
        weaponRigidbody = gameObject.AddComponent<Rigidbody>();
        
        if (weaponType == WeaponType.NONE) weaponType = WeaponType.SHORT;
        fullMag = currentMagCapacity;
        maxBullets = totalBullets;
        pickHUD.gameObject.SetActive(false);
        if (muzzleTransform == null) muzzleTransform = transform.Find("muzzle");
    }
    
    private void CreateInteractiveRadius(Vector3 center) {
        interactiveRadius = gameObject.AddComponent<SphereCollider>();
        interactiveRadius.center = center;
        interactiveRadius.radius = 1;
        interactiveRadius.isTrigger = true;
    }
    
    private void TogglePickHUD(bool toggle) {
        pickHUD.gameObject.SetActive(toggle);
        if (toggle) {
            pickHUD.position = transform.position + Vector3.up * 0.5f;
            Vector3 direction = player.GetComponent<BehaviourController>().playerCamera.forward;
            direction.y = 0;
            pickHUD.rotation = Quaternion.LookRotation(direction);
            pickupHUD_Label.text = "Pick " + gameObject.name;
        }
    }
    
    private void UpdateHUD() {
        weaponHUD.UpdateWeaponHUD(weaponSprite, currentMagCapacity, fullMag, totalBullets);
    }
    
    public void Toggle(bool active) {
        if (active) SoundManager.Instance.PlayOneShotEffect((int)pickSound, transform.position, 0.5f);
        weaponHUD.Toggle(active);
        UpdateHUD();
    }
    
    private void Update() {
        if (pickable && Input.GetKeyDown(ButtonName.Pick)) {
            // disable physics weapon
            weaponRigidbody.isKinematic = true;
            weaponCollider.enabled = false;
            playerInventory.AddWeapon(this);
            Destory(interactiveRadius);
            Toggle(true);
            pickable = false;
            TogglePickHUD(false);
        }
    }
    
    private void OnCollisionEnter(Collision collision) {
        if (collision.collider.gameObject != player && Vector3.Distance(transform.position, player.transform.position) <= 5f) {
            SoundManager.Instance.PlayOneShotEffect((int)dropSound, transform.position, 0.5f);
        }
    }
   
    private void OnTriggerExit(Collider other) {
        if (other.gameObject == player) {
            pickable = false;
            TogglePickHUD(false);
        }
    }
    
    private void OnTriggerStay(Collider other) {
        if (other.gameObject == player && playerInventory && playerInventory.isActiveAndEnabled) {
            pickable = true;
            TogglePickHUD(true);
        }
    }
    
    public void Drop() {
        gameObject.SetActive(true);
        transform.position += Vector3.up;
        weaponRigidbody.isKinematic = false;
        transform.parent = null;
        CreateInteractiveRadius(weaponCollider.center);
        weaponCollider.enabled = true;
        weaponHUD.Toggle(false);
    }
    
    public bool StartReload() {
        if (currentMagCapacity == fullMag || totalBullets == 0) return false;
        else if (totalBullets < fullMag - currentMagCapacity) {
            currentMagCapacity += totalBullets;
            totalBullets = 0;
        }
        else {
            totalBullets -= fullMag - currentMagCapacity;
            currentMagCapacity = fullMag;
        }
        return true;
    }
    
    public void EndReload() {
        UpdateHUD();
    }
    
    public bool Shoot(bool firstShot = true) {
        if (currentMagCapacity > 0) {
            currentMagCapacity--;
            UpdateHUD();
            return true;
        }
        if (firstShot && noBulletSound != SoundList.None) {
            SoundManager.Instance.PlayOneShotEffect((int)noBulletSound, muzzleTransform.position, 5f);
        }
        return false;
    }
    
    public void ResetBullet() {
        currentMagCapacity = fullMag;
        totalBullets = maxBullets;
    }
}




이제 Unity에서 Interactive Weapon을 위와 같이 설정해 줍니다.



Unity 실행화면 입니다. Interactive가 되지 않는 버그가!? ㅎㅎ 좀더 세팅이 필요하기에 계속 이어진다고 합니다.




<위의 코드들은 제가 보면서 주요한 함수, 코드를 확인하기 위해 타이핑한 용도로, 전체 소스코드가 아님에 주의해 주세요. 전체 코드는 교육 수강을 하면 완벽하게 받으실 수가 있답니다 ^^>

패스트캠퍼스 - 올인원 패키지 : 유니티 포트폴리오 완성 bit.ly/2R561g0

 

유니티 게임 포트폴리오 완성 올인원 패키지 Online. | 패스트캠퍼스

게임 콘텐츠 프로그래머로 취업하고 싶다면, 포트폴리오 완성은 필수! '디아블로'와 '배틀그라운드' 게임을 따라 만들어 보며, 프로그래머 면접에 나오는 핵심 개념까지 모두 잡아 보세요!

www.fastcampus.co.kr

 

+ Recent posts