티스토리 뷰

# 터치슬라이드를 이용한 오브잭트 제어를 공부중이다. 먼저 이전에 오브잭트를 이동하는 방식에서 변경할 부분들이 있었다. 

 

1. x 축을 기준으로 회전하면서 z축 방향으로 이동, 오브잭트가 지면보다 낮은 위치로 떨어지면 GameOver

*Script

    private void Update()
    {
        this.transform.position += Vector3.forward * this.moveSpeed * Time.deltaTime; //z축(앞으로) 이동
        this.transform.Rotate(Vector3.right * this.rotateSpeed * Time.deltaTime); // 회전 (x축을 기준으로)
        if(this.transform.position.y<this.limitY) //떨어지면? 게임오버
        {
            Debug.Log("GameOver");
        }
    }

 

2. x축(좌,우) 로 이동 하는 중이라면 같은 방향으로 1번 이상 이동 불가(이중 이동 방지), 자연스러운 이동 연출을 위하여 

Mathf.Lerp(start, end, percent); 로 현재위치(start)에서 목표위치(end)까지 일정한비율(percent)로 값을 보간

*Script

public void MoveToX(int x)
    {
        
        if (this.isXMove) return; //이중 이동 방지

        if (x > 0 && this.transform.position.x < this.moveXWidth) //우로 이동
        {
            this.StartCoroutine(OnMoveToX(x));
            
        }

        else if(x<0&&this.transform.position.x>-this.moveXWidth) //좌로 이동
        {
            StartCoroutine(OnMoveToX(x));
        }
    }
    private IEnumerator OnMoveToX(int direction)
    {
        float current = 0;
        float percent = 0;
        float start = this.transform.position.x;
        float end = this.transform.position.x + direction * this.moveXWidth;

        this.isXMove= true;
        
        while(percent < 1)
        {
            current += Time.deltaTime;
            percent = current / this.moveTimeX;

            float x=Mathf.Lerp(start, end, percent);
            this.transform.position=new Vector3(x, this.transform.position.y, this.transform.position.z);

            yield return null;
        }

        this.isXMove= false;
    }

3. 자연스러운 jump 연출을 위하여 포물선운동 공식 적용

*Script

private IEnumerator OnMveToY()
    {
        float current = 0;
        float percent = 0;
        float v0 = -this.gravity; //y방향의 초기 속도
        
        this.isJump= true;
        this.rb.useGravity = false;

        while(percent < 1)
        {
            current += Time.deltaTime;
            percent = current / this.moveTimeY;

            //시간경과에 따라 오브잭트의 y위치를 변경
            //포물선 운동 : 시작위치+초기속도*시간+중력*시간제곱
            float y = this.originY + (v0 * percent) + (this.gravity * percent * percent);
            this.transform.position=new Vector3(this.transform.position.x,y,this.transform.position.z);
            yield return null;
        }
        this.isJump= false;
        this.rb.useGravity = true;
    }

*포물선 공식?

https://namu.wiki/w/%ED%8F%AC%EB%AC%BC%EC%84%A0%20%EC%9A%B4%EB%8F%99

=>포물선 운동 : 시작위치+초기속도*시간+중력*시간제곱

 

4.터치 슬라이드를 이용한 오브잭트 제어

 * PC환경 모두 적용 (Application.isMobilePlatform)

    private void Update()
    {
        //모바일 환경? PC환경?
        if (Application.isMobilePlatform)
        {
            Debug.Log("Mobile");
            OnMobilePlatform();
        }
        else
        {
            Debug.Log("PC");
            OnPCPlatform();
        }
    }
/// <summary>
    /// PC환경
    /// </summary>
    private void OnPCPlatform()
    {
        if(Input.GetMouseButtonDown(0))
        {
            Debug.Log("PC Touch");
            this.touchStart = Input.mousePosition;
        }

        else if (Input.GetMouseButton(0))
        {
            this.touchEnd = Input.mousePosition;
            this.OnDragXY();
        }
    }

* Mobile환경(터치 슬라이드 적용)

/// <summary>
    /// 모바일 환경에서는 터치&드레그로 조작
    /// </summary>
    private void OnMobilePlatform()
    {
        //현제 화면을 터치하고 있지않다면? return
        if (Input.touchCount == 0) return;

        //첫번째 터치 정보
        Touch touch=Input.GetTouch(0);

        //터치시작
        if(touch.phase==TouchPhase.Began)
        {
            this.touchStart = touch.position;
        }

        //터치 & 드레그
        else if (touch.phase==TouchPhase.Moved)
        {
            this.touchEnd = touch.position;
            this.OnDragXY();
        }
    }

* 터치상태로 x/y축 드래그 범위 감지

private void OnDragXY()
    {
        //터치 상태로 x축 드래그 범위가 dragDistance보다 클때
        if(Mathf.Abs(this.touchEnd.x-this.touchStart.x)>=this.dragDistance)
        {
            this.movement.MoveToX((int)Mathf.Sign(this.touchEnd.x - this.touchStart.x));
            return;
        }

        //터치 상태로 y축 양의 방향으로 드래그 범위가 dragDistance보다 클떄
        if (this.touchEnd.y - touchStart.y >= this.dragDistance)
        {
            this.movement.MoveToY();
            return;
        }
    }

5. FollingCam

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

public class FollowingCam : MonoBehaviour
{
    public Transform target; //카메라가 따라갈 대상 (플레이어)

    private Vector3 offset = new Vector3(0f, 5f, -9f); //카메라와 대상 사이의 오프셋

    private float smoothSpeed = 0.125f; //카메라 이동 스무딩 정도

    private void Start()
    {
    }
    private void LateUpdate()
    {
        //target이 null이면? return
        if (this.target == null) return;

        //플레이어의 위치에 오프셋을 더한 위치로 카메라 이동
        Vector3 desiredPosition = target.position + offset;
        Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
        transform.position = smoothedPosition;

        //카메라가 항상 대상을 바라보도록 설정
        transform.LookAt(target);

        //카메라의 Rotation을 (30, 0, 0)으로 설정
        transform.rotation = Quaternion.Euler(30f, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z);

    }
}

 

* Test

 

* 전체 Script

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using Unity.VisualScripting;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private float dragDistance = 50f; //드레그 거리
    private Vector3 touchStart; //터치 시작 위치
    private Vector3 touchEnd; //터치 끝 위치

    private Movement movement;

    private void Awake()
    {
        movement = GetComponent<Movement>();
    }
    private void Update()
    {
        //모바일 환경? PC환경?
        if (Application.isMobilePlatform)
        {
            Debug.Log("Mobile");
            OnMobilePlatform();
        }
        else
        {
            Debug.Log("PC");
            OnPCPlatform();
        }
    }

    /// <summary>
    /// 모바일 환경에서는 터치&드레그로 조작
    /// </summary>
    private void OnMobilePlatform()
    {
        //현제 화면을 터치하고 있지않다면? return
        if (Input.touchCount == 0) return;

        //첫번째 터치 정보
        Touch touch=Input.GetTouch(0);

        //터치시작
        if(touch.phase==TouchPhase.Began)
        {
            this.touchStart = touch.position;
        }

        //터치 & 드레그
        else if (touch.phase==TouchPhase.Moved)
        {
            this.touchEnd = touch.position;
            this.OnDragXY();
        }
    }
    /// <summary>
    /// PC환경
    /// </summary>
    private void OnPCPlatform()
    {
        if(Input.GetMouseButtonDown(0))
        {
            Debug.Log("PC Touch");
            this.touchStart = Input.mousePosition;
        }

        else if (Input.GetMouseButton(0))
        {
            this.touchEnd = Input.mousePosition;
            this.OnDragXY();
        }
    }

    private void OnDragXY()
    {
        //터치 상태로 x축 드래그 범위가 dragDistance보다 클때
        if(Mathf.Abs(this.touchEnd.x-this.touchStart.x)>=this.dragDistance)
        {
            this.movement.MoveToX((int)Mathf.Sign(this.touchEnd.x - this.touchStart.x));
            return;
        }

        //터치 상태로 y축 양의 방향으로 드래그 범위가 dragDistance보다 클떄
        if (this.touchEnd.y - touchStart.y >= this.dragDistance)
        {
            this.movement.MoveToY();
            return;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Movement : MonoBehaviour
{

    //x축
    private float moveXWidth = 1.5f; // 1회 이동시 이동거리(x축)
    private float moveTimeX = 0.1f; //1회 이동시 소요시간 (x축)
    private bool isXMove=false; //true : 이동중

    //y축
    private float originY = 0.55f; //점프 및 착지하는 y축 값
    private float gravity = -9.81f; //중력
    private float moveTimeY = 0.3f; //1회 이동에 소요 시간 (y축)
    private bool isJump=false; //true : 점프 중 (2중 점프 방지)

    //z축
    [SerializeField]
    private float moveSpeed = 20.0f; //(이동속도 (z축)

    //회전
    private float rotateSpeed = 300f; //회전 속도
    private float limitY = -1.0f; //플레이어가 사망하는 y위치
    private Rigidbody rb;


    private void Awake()
    {
        this.rb=GetComponent<Rigidbody>();
    }
    private void Update()
    {
        this.transform.position += Vector3.forward * this.moveSpeed * Time.deltaTime; //z축(앞으로) 이동
        this.transform.Rotate(Vector3.right * this.rotateSpeed * Time.deltaTime); // 회전 (x축을 기준으로)
        if(this.transform.position.y<this.limitY) //떨어지면? 게임오버
        {
            Debug.Log("GameOver");
        }
    }

    /// <summary>
    /// 현재 x축 이동 중으로 이동 불가(같은 방향으로 연속 이동 방지)
    /// </summary>
    /// <param name="x"></param>
    public void MoveToX(int x)
    {
        
        if (this.isXMove) return; //이중 이동 방지

        if (x > 0 && this.transform.position.x < this.moveXWidth) //우로 이동
        {
            this.StartCoroutine(OnMoveToX(x));
            
        }

        else if(x<0&&this.transform.position.x>-this.moveXWidth) //좌로 이동
        {
            StartCoroutine(OnMoveToX(x));
        }
    }

    /// <summary>
    /// 오브잭트 점프
    /// 이중 점프 방지
    /// </summary>
   public void MoveToY()
    {
        if (this.isJump)
        {
            return; //이중 점프 방지
        }
        StartCoroutine(this.OnMveToY());
    }

    /// <summary>
    /// x축으로 오브잭트 이동
    /// 이동 중에는 중복 이동을 할 수 없음
    /// </summary>
    /// <param name="direction"></param>
    /// <returns></returns>
    private IEnumerator OnMoveToX(int direction)
    {
        float current = 0;
        float percent = 0;
        float start = this.transform.position.x;
        float end = this.transform.position.x + direction * this.moveXWidth;

        this.isXMove= true;
        
        while(percent < 1)
        {
            current += Time.deltaTime;
            percent = current / this.moveTimeX;

            float x=Mathf.Lerp(start, end, percent);
            this.transform.position=new Vector3(x, this.transform.position.y, this.transform.position.z);

            yield return null;
        }

        this.isXMove= false;
    }
    private IEnumerator OnMveToY()
    {
        float current = 0;
        float percent = 0;
        float v0 = -this.gravity; //y방향의 초기 속도
        
        this.isJump= true;
        this.rb.useGravity = false;

        while(percent < 1)
        {
            current += Time.deltaTime;
            percent = current / this.moveTimeY;

            //시간경과에 따라 오브잭트의 y위치를 변경
            //포물선 운동 : 시작위치+초기속도*시간+중력*시간제곱
            float y = this.originY + (v0 * percent) + (this.gravity * percent * percent);
            this.transform.position=new Vector3(this.transform.position.x,y,this.transform.position.z);
            yield return null;
        }
        this.isJump= false;
        this.rb.useGravity = true;
    }
}
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함