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

04. 배틀로얄 - 33, 34 번을 진행합니다.



저번 시간에 계속하여 AimBehaviour 작업을 계속 이어나갑니다.


public class AimBehaviour : MonoBehaviour
{
    // 변수들 및 Start()
    
    // 카메라에 따라 플레이어를 올바른 방향으로 회전.
    void Rotating() {
        Vector3 forward = behaviourController.playerCamera.TransformDirection(Vector3.forward);
        forward.y = 0.0f;
        forward = forward.normalized;
        
        Quaternion targetRotation = Quaternion.Euler(0f, behaviourController.GetCamScript.GetH, 0.0f);
        float minSpeed = Quaternion.Angle(transform.rotation, targetRotation) * aimTurnSmoothing);
        if (peekCorner) {
            // 조준중 일때 플레이어 상체만 살짝 기울여 주기 위함
            myTransform.rotation = Quaternion.LookRotation(-behaviourController.GetLastDirection()); // IK(Inverse Kinematics)를 검색!
            targetRotation *= Quaternion.Euler(initialRootRotation);
            targetRotation *= Quaternion.Euler(initialHipRotation);
            targetRotation *= Quaternion.Euler(initialSpineRotation);
            Transform spine = behaviourController.GetAnimator.GetBoneTransform(HumanBodyBones.Spine);
            spine.rotation = targetRotation;
        }
        else {
            behaviourController.SetLastDirection(forward);
            myTransform.rotation = Quaternion.Slerp(myTransform.rotation, targetRotation, minSpeed * Time.deltaTime);
        }
    }
    
    // 조준중일때를 관리하는 함수
    void AimManagement() {
        Rotating();
    }
    
    private IEnumerator ToggleAimOn() {
        yield return new WaitForSeconds(0.05f);
        // 조준이 불가능한 상태일 때에 대한 예외처리.
        if (behaviourController.GetTempLockStatus(behaviourCode) || behaviourController.IsOverriding(this)) {
            yield return false;
        }
        else {
            aim = true;
            int signal = 1;
            if (peekCorner) {
                signal = (int)Mathf.Sign(behaviourController.GetH);
            }
            aimCamOffset.x = Mathf.Abs(aimCamOffset.x) * signal);
            aimPivotOffset.x = Mathf.Abs(aimPivotOffset.x) * signal);
            yield return new WaitForSeconds(0.1f);
            behaviourController.GetAnimator.SetFloat(speedFloat, 0.0f);
            behaviourController.OverrideWithBehaviour(this);
        }
    }
    
    private IEnumerator ToggleAimOff() {
        aim = false;
        yield return new WaitForSeconds(0.3f);
        behaviourController.GetCamScript.ResetTargetOffsets();
        behaviourController.GetCamScript.ResetMaxVerticalAngle();
        yield return new WaitForSeconds(0.1f);
        behaviourController.RevokeOverridingBehaviour(this);
    }
    
    public override void LocalFixedUpdate() {
        if (aim) {
            behaviourController.GetCamScript.SetTargetOffset(aimPivotOffset, aimCamOffset);
        }
    }
    
    pubic override void LocalLateUpdate() {
        AimManagement();
    }
    
    private void Update() {
        peekCorner = behaviourController.GetAnimator.GetBool(cornerBool);
        
        if (Input.GetAxisRaw(ButtonName.Aim) != 0 && !aim) {
            StartCoroutine(ToggleAimOn());
        }
        else if (aim && Input.GetAxisRaw(ButtonName.Aim) == 0) {
            StartCoroutine(ToggleAimOff());
        }
        // 조준중일때는 달리기를 하지 않도록..
        canSprint = !aim;
        if (aim && Input.GetButtonDown(ButtonName.Shoulder) && !peekCorner) {
            aimCamOffset.x = aimCamOffset.x * (-1);
            aimPivotOffset.x = aimPivotOffset.x * (-1);
        }
        behaviourController.GetAnimator.SetBool(aimBool, aim);
    }
    
    private void OnGUI() {
        if (crossHair != null) {
            float length = behaviourController.GetCamScript.GetCurrentPivotMagnitude(aimPivotOffset);
            if (length < 0.05f) {
                GUI.DrawTexture(new Rect(Screen.width * 0.5f - (crossHair.width * 0.5f), Screen.height * 0.5f - (crossHair.height * 0.5f), crossHair.width, crossHair.height), crossHair);
            }
        }
    }
}




Unity에서 "Cross Hair"를 설정해줍니다.

 

 



Unity에서 플레이를 하여 마우스 우클릭을 하면 위 화면과 같이 조준점이 나타나는 것을 확인할 수 있습니다.
물론 현재는 총을 가지고 있지 않아도 무조건 Cross hair가 나타나는 상황으로 무기를 가진 상태에서만 조준이 되도록 처리를 해주어야 하겠지요.

여기까지 캐릭터의 움직임과 조준 등에 대한 처리가 마무리되었습니다.





 



이제 무기를 줍고 총을 쏘고 등을 개발을 해야하는데 하나씩 진행을 해나아가게 됩니다.

 

 



자 우선 UI 폴더를 만들고, WeaponUIManager 스크립트를 생성하고 코드 작업을 시작합니다!!!!!


/// <summary>
/// 무기를 획득하면 획득한 무기를 UI를 통해 보여주고
/// 현재 잔탄량과 전체 소지할 수 있는 총알량을 출력
/// </summary>
public class WeaponUIManager : MonoBehaviour
{
    public Color bulletColor = Color.white;
    public Color emptyBulletColor = Color.black;
    private Color noBulletColor; // 투명하게 색깔표시.
    
    [SerializeField] private Image weaponHUD;
    [SerializeField] private GameObject bulletMag;
    [SerializeField] private Text totalBulletsHUD;
    
    void Start() {
        noBulletColor = new Color(0f, 0f, 0f, 0f);
        if (weaponHUD == null) weaponHUD = transform.Find("WeaponHUD/Weapon").GetComponent<Image>();
        if (bulletMag == null) bulletMag = transform.Find("WeaponHUD/Data/Mag").gameObject;
        if (totalBulletsHUD == null) totalBulletsHUD = transform.Find("WeaponHUD/Data/bulletAmount").GetComponent<Text>();
        Toggle(false); // 시작시 탄창 UI 숨기기.
    }
    
    public void Toggle(bool active) {
        weaponHUD.transform.parent.gameObject.SetActive(active);
    }
    
    public void UpdateWeaponHUD(Sprite weaponSprite, int bulletLeft, int fullMag, int ExtraBullets) {
        if (weaponSprite != null && weaponHUD.sprite != weaponSprite) {
            weaponHUD.sprite = weaponSprite;
            weaponHUD.type = Image.Type.Filled;
            weaponHUD.fillMethod = Image.FillMethod.Horizontal;
        }
        int bulletCount = 0;
        foreach (Transform bullet in bulletMag.transform) {
            if (bulletCount < bulletLeft) bullet.GetComponent<Image>().color = bulletColor; // 잔탄..
            else if (bulletCount >= fullMag) bullet.GetComponent<Image>().color = noBulletColor; // 넘치는탄..
            else bullet.GetComponent<Image>().color = emptyBulletColor; // 사용한탄..
            bulletCount++;
        }
        totalBulletsHUD.text = bulletLeft + "/" + ExtraBullets;
    }
}




우선 ScreenHUD에 WeaponUIManager 스크립트를 연결해주고,
각 변수에 위와 같이 드래그하여 설정해 줍니다.

다음 진행할 것에 대한 설명이 이어집니다.

수류탄에 의한 데미지를 예로 든다면,
로컬게임에서는 수류탄 반경내 데미지 받는 GameObject를 찾아내고 각각 데미지를 받는 코드를 작성하고,
Server/Client 구조에서는 서버에서 수류탄 반경내 해당하는 Client를 찾아내어 데이터 전송을 하면 Client에서는 단순히 데미지 처리를 하는 형태로 제작합니다.
총소리가 발생하면 특정 영역내 GameObject내에 Alert를 알려주는 시스템도 진행하게 됩니다.





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

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

 

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

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

www.fastcampus.co.kr

 

+ Recent posts