본문 바로가기
UNITY/Unity Study

해결 - 따로 돌릴 땐 됐는데 합치니 제 기능을 못 함

by GREEN나무 2023. 7. 31.
728x90

각자 다른 씬에서 테스트할 때는 잘 됐는데

 

같이 두니 

PlayerMove1의 캐릭터 좌우 회전이 안 되고 - 해결. 

TestPlayer는  - 해결

if (clickInterface != null)
        { 

            Debug.Log("3");
            Item item = clickInterface.ClickItem();
            //item에 클릭된 오브젝트의 아이템 정보를 넘김; ObjectItem.cs의 ClickItem()에서 사용
            print($"{item.itemName}"); // 클릭한 아이템 이름 콘솔창에 출력
            inventory.AddItem(item); // 만들어 둔 인벤토리에 아이템을 넣기
        }

이 부분이 기능을 못 합니다

 

 

플레이어 움직임 스크립트

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove1 : MonoBehaviour
{// 플레이어 움직이기

    // 이동 속도_________________________________________
    public float walkSpeed; // 걷기 속도 5
    public float runSpeed; // 달리기 속도
    private float applySpeed; // 이동속도 대입
    public float croechSpeed;
    
    //__________________________________________
    // 점프_________________________
    public float jumpForce; // 숫자기입
    //_______________________________________

    // 상태변수_________________________________________
    private bool isRun = false;
    private bool isCrouch = false;
    private bool isGround = true;

    //_________________________________________________


    // 앉을 때 얼마나 앉는가___________________
    public float crouchPosY;
    private float originPosY;
    private float applyCrouchPosY;
    //________________________________________




    // 땅 착지 여부______________________
    private CapsuleCollider capsuleCollider;
    // _________________________________________



    // 카메라________________________________________
    public float lookSensitivity;// 카메라 민감도  1(0으로 하면 안움직임)
    public float cameraRotationLimit; //카메라 각도 45
    private float currentCameraRotationX;
    
    // 컴포넌트_____________________________________________
    public Camera theCamera;
    private Rigidbody myRigid;
    //_____________________________________________________
   

    void Start()
    {
        capsuleCollider = GetComponent<CapsuleCollider> ();
        myRigid = GetComponent<Rigidbody>();
        // myRigid에 리지드바디 넣겠다
        applySpeed = walkSpeed;
        originPosY = theCamera.transform.localPosition.y;
        applyCrouchPosY = originPosY;

        
    }

    void Update()
    {
        IsGround(); // 레이저
        TryJump();
        TryRun();
        TryCrouch();
        Move();
        //CameraRotation();
        CharacterRotation();
    }

    private void TryCrouch()
    {
        if (Input.GetKeyDown(KeyCode.LeftControl))
        {
            Crouch();
        }
    }

    private void Crouch()
    {
        isCrouch = !isCrouch; // 스위치 역할
        /* // 윗줄 의미
         * if (isCrouch)
            isCrouch = false;
        else
            isCrouch = true;
        */

        if (isCrouch)
        {
            applySpeed = croechSpeed;
            applyCrouchPosY = crouchPosY;
        }
        else
        {
            applySpeed = walkSpeed;
            applyCrouchPosY = originPosY;
        }
        //theCamera.transform.localPosition = new Vector3(theCamera.transform.localPosition.x, applyCrouchPosY, theCamera.transform.localPosition.z);
        StartCoroutine(CrouchCoroutine());
        // 코루틴 시작
    
    }

    // 코루친,, 기원문법 : IEnumerator Crluchcoroutione(){}
    // 병렬처리(같이 동작)
    IEnumerator CrouchCoroutine()
    { // 자연스러운 카메라 처리; 부드러운 동작 실행
        float _posY = theCamera.transform.localPosition.y;
        //yield return new WaitForSeconds(1f);
        int count = 0;
        while (_posY != applyCrouchPosY) //원하는 값이 나올 때 까지 반복(앉은 자세)
        {
            count++;
            // 보간 - 처음 빨랐다가 목적지에 도달할수록 서서히 느려짐
            _posY = Mathf.Lerp(_posY, applyCrouchPosY, 0.3f);
            // (a,b,c) - a부터 b까지 c의 비율로 증가; c가 0.5면 만가고 남은거의 반가고 ... 도달할 때까지 반복
            theCamera.transform.localPosition = new Vector3(0, _posY, 0);
            if (count > 15) 
                break;
            yield return null;
        }
        theCamera.transform.localPosition = new Vector3(0, applyCrouchPosY, 0f);
    }

    // 지면 체크.
    private void IsGround() // 레이저
    {
        isGround = Physics.Raycast(transform.position, Vector3.down, capsuleCollider.bounds.extents.y + 0.1f);
    }


    //점프 시도
    private void TryJump()
    {
        if(Input.GetKeyDown(KeyCode.Space) && isGround)
        {
            Jump();
        }
    }

    // 점프
    private void Jump()
    {
        // 앉기 해제
        if (isCrouch)
            Crouch();
        myRigid.velocity = transform.up * jumpForce;

    }

    // 달리기 시도 
    private void TryRun()
    {
        if (Input.GetKey(KeyCode.LeftShift))
        {
            Running();
        }
        if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            RunningCancle();
        }
    }


    // 달리기
    private void Running()
    {
        // 앉기 해제
        if (isCrouch)
            Crouch();
        isRun = true;
        applySpeed = runSpeed;
    }

    //달리기 취소
    private void RunningCancle()
    {
        isRun = false;
        applySpeed = walkSpeed;
    }

    //움직임 실행
    private void Move()
    {
        float _moveDirX = Input.GetAxisRaw("Horizontal");
        // Horizontal - 좌우(X)
        float _moveDirZ = Input.GetAxisRaw("Vertical");
        // Vertical - 앞뒤(Z)
        // - 점프(Y 높이)


        //위에 변수로 이동벡터 설정
        Vector3 _moveHorizontal = transform.right * _moveDirX;
        Vector3 _moveVertical = transform.forward * _moveDirZ;

        Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * applySpeed;

        myRigid.MovePosition(transform.position + _velocity * Time.deltaTime);
    }

    // // 좌우 캐릭터 회전
    // private void CharacterRotation()
    // { 
    //     float _yRotation = Input.GetAxisRaw("Mouse X");
    //     Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f) * lookSensitivity;
    //     myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));
    //     // 오일러값을 쿼터니엄 값으로 바꿈
    //     myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));
    //     //Debug.Log(myRigid.rotation);
    //     //Debug.Log(myRigid.rotation.eulerAngles);
    // }


    // //상하 카메라 회전
    // private void CameraRotation()
    // { 
    //     float _xRotation = Input.GetAxisRaw("Mouse Y");
    //     float _cameraRotationX = _xRotation * lookSensitivity;
    //     currentCameraRotationX -= _cameraRotationX; //반전시키기
    //     currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit); //각도 제한

    //     theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f); //localEulerAngles - 오일러각으로 변환;
    // }

    // 좌우 캐릭터 회전
	private void CharacterRotation()
	{ 
    	float _yRotation = Input.GetAxisRaw("Mouse X") * lookSensitivity;
    	Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f);

    	// 캐릭터 좌우 회전 (y축 기준)
    	myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));

    	// 카메라 상하 회전 (x축 기준)
    	float _xRotation = Input.GetAxisRaw("Mouse Y") * lookSensitivity;
    	currentCameraRotationX -= _xRotation;
    	currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit);

    	theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f);
	}


}

아이템 인벤토리에 넣는 스크립트

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestPlayer : MonoBehaviour
{
    [Header("인벤토리")]
    public Inventory inventory;
    // 하이라키의 Inventory 넣기(inventory.cs 있어야함)

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("0");
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            
            RaycastHit hit; // 클릭한 곳에 3D 오브젝트가 있는지 체크
            if (Physics.Raycast(pos, Camera.main.transform.forward, out hit))
            {
            Debug.Log("1");
                // 만약 오브젝트를 클릭했다면 HitCheckObject(hit) 함수로 hit 정보를 넘김
                HitCheckObject(hit);
            }

            // 2D인 경우
            /*
            RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);
            if (hit.collider != null)
            {
                HitCheckObject(hit);
            }
            */
        }
    }

    void HitCheckObject(RaycastHit hit)
    {
            Debug.Log("2");
        // 클릭된 오브젝트의 IObjectItem 인터페이스를 clickInterface에 넘겨줌
        IObjectItem clickInterface = hit.transform.gameObject.GetComponent<IObjectItem>();
        // 클릭된 오브젝트가 아이템이아니면(=인터페이스를 가지고 있지 않으면) clickInterface는 null 이 됨

        if (clickInterface != null)
        { 

            Debug.Log("3");
            Item item = clickInterface.ClickItem();
            //item에 클릭된 오브젝트의 아이템 정보를 넘김; ObjectItem.cs의 ClickItem()에서 사용
            print($"{item.itemName}"); // 클릭한 아이템 이름 콘솔창에 출력
            inventory.AddItem(item); // 만들어 둔 인벤토리에 아이템을 넣기
        }
    }
}

 

해결

캐릭터 좌우 회전 - 플레이어의 애니메이터를 비활성화하고 Rigidbody의 Rotation x, z를 막아둠

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

스케일값이 음수인 객체 수정하니 해결됨

 

BoxColliders does not support negative scale or size.
The effective box size has been forced positive and is likely to give unexpected collision geometry.
If you absolutely need to use negative scaling you can use the convex MeshCollider. Scene hierarchy path "ICTSchool 2FloorWothClass 1/Libray/PlaneMiddl/SHW_Pillar_01_07 (1)"

 

'UNITY > Unity Study' 카테고리의 다른 글

버튼 눌러 팝업창 넘기기  (0) 2023.08.02
목표에 도달하면 팝업창 띄우기  (0) 2023.08.01
애셋배치-학교  (0) 2023.07.29
프리펩 해제하기  (0) 2023.07.28
UI이미지로 슬라이더 만들기  (0) 2023.07.28