EasyCastleUNITY

충돌감지를 통한, 플레이어 회전 변경 본문

유니티 심화

충돌감지를 통한, 플레이어 회전 변경

EasyCastleT 2023. 8. 21. 13:00

벽과 부딫치면, 벽의 법선벡터 방향으로 회전하여, 벽에 붙는다. 

플레이어 컴포넌트
벽 컴포넌트

실행영상

플레이어 이동및 충돌처리 스크립트

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

namespace Test
{
    public class Player : MonoBehaviour
    {
        private float moveSpeed = 3.0f;

        // Start is called before the first frame update
        void Start()
        {

        }

        // Update is called once per frame
        void Update()
        {
            //이동
            this.transform.Translate(this.transform.forward * this.moveSpeed * Time.deltaTime);
        }

        private void OnCollisionEnter(Collision collision)
        {
            this.moveSpeed = 0.0f;
            ContactPoint cp = collision.GetContact(0);
            Quaternion rot = Quaternion.LookRotation(cp.normal);
            this.transform.rotation = rot;
        }
    }
}

유의한 점

처음으로 ContactPoint 라는 클래스를 사용해보았다. 

충돌한 물체의 정보들을 받아오는 클래스로, GetContact(0)은 처음 부딫친 물체의 정보를 의미한다. 

 

자연스럽게 회전하는거 추가

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

namespace Test
{
    public class Player : MonoBehaviour
    {
        [SerializeField]
        private Transform eye;
        private float moveSpeed = 0.2f;
        private float rotateSpeed = 1.0f;

        private Quaternion rot;

        [SerializeField]
        private Transform startTrans;
        [SerializeField]
        private Transform endTrans;
        [SerializeField]
        [Range(0f, 1f)]
        private float elapsedTime = 0.0f;
        

        // Start is called before the first frame update
        void Start()
        {
            
        }

        // Update is called once per frame
        void Update()
        {
            
            //눈에서 정면을 향해 ray 발사
            Ray ray = new Ray(this.eye.position, this.transform.forward);
            //Debug.DrawRay(ray.origin, ray.direction * 100f, Color.blue, 5f);
            RaycastHit hit;
            if(Physics.Raycast(ray, out hit, 100f))
            {
                this.rot = Quaternion.LookRotation(hit.normal);
                DrawArrow.ForDebug(hit.point, hit.normal, 5.0f, Color.green, ArrowType.Solid);
                this.endTrans.position = new Vector3(hit.point.x,this.transform.position.y,hit.point.z);
            }
            //이동
            this.StartCoroutine(this.CoMoveForward());
            //this.transform.position= Vector3.Lerp(this.startTrans.position,this.endTrans.position,Time.deltaTime);
        }

        private IEnumerator CoMoveForward()
        {
            while (true)
            {
                if (Vector3.Distance(this.transform.position, this.endTrans.position) <= 0.1f)
                {
                    break;
                }
                this.transform.Translate(this.transform.forward * this.moveSpeed * Time.deltaTime);
                yield return null;
            }
            Debug.Log("move complete");

            while (true)
            {
                this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rot, Time.deltaTime * this.rotateSpeed);
                if(this.transform.rotation == rot)
                {
                    break;
                }
                yield return null;
            }
            Debug.Log("rotate complete");
        }

        
    }
}

바로 그 각도가 되는 것이 아니라 회전을 smooth하게