티스토리 뷰

#1. player의 이동(waypoint를 순회하며 반복 이동구현)

#Vector3.MoveTowards 사용

https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html

 

Unity - Scripting API: Vector3.MoveTowards

Use the MoveTowards member to move an object at the current position toward the target position. By updating an object’s position each frame using the position calculated by this function, you can move it towards the target smoothly. Control the speed of

docs.unity3d.com

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

public class Player2 : MonoBehaviour
{
    public Transform[] waypoints;
    private float speed = 2f;
    private int idx = 0;

    private void Start()
    {
        this.GetComponent<CharacterController>();
    }
    private void Update()
    {
        this.MoveWaypoint();
    }
    public void MoveWaypoint()
    {
        this.transform.position = Vector3.MoveTowards(
            this.transform.position, waypoints[idx].transform.position, speed * Time.deltaTime);
        if (this.transform.position == waypoints[idx].transform.position)
            this.idx++;
        if (this.idx == this.waypoints.Length)
            this.idx = 0;
    }
}

#2. player의 회전(waypoint로 회전)

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

public class Player2 : MonoBehaviour
{
    public Transform[] waypoints;
    private float speed = 2f;
    private int idx = 0;

    private float damping = 3f;
    private void Start()
    {
        this.GetComponent<CharacterController>();
    }
    private void Update()
    {
        this.MoveWaypoint();
    }
    public void MoveWaypoint()
    {
        //순회 이동
        this.transform.position = Vector3.MoveTowards(
            this.transform.position, waypoints[idx].transform.position, speed * Time.deltaTime);
        if (this.transform.position == waypoints[idx].transform.position)
            this.idx++;
        if (this.idx == this.waypoints.Length)
            this.idx = 0;        
        //회전
        //현재 위치에서 다음 웨이포인트로 향하는 백터
        Vector3 dir = this.waypoints[idx].position-this.transform.position; 
        //백터의 회전 각도
        Quaternion rot=Quaternion.LookRotation(dir);
        //회전처리
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rot, Time.deltaTime * damping);
    }

}

https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

 

Unity - Scripting API: Quaternion.LookRotation

Z axis will be aligned with forward, X axis aligned with cross product between forward and upwards, and Y axis aligned with cross product between Z and X. Returns identity if the magnitude of forward is zero. If forward and upwards are colinear, or if the

docs.unity3d.com

 

#RayCast

*UI가 Player를 바라보게 

#LookAt

https://docs.unity3d.com/ScriptReference/Transform.LookAt.html

 

Unity - Scripting API: Transform.LookAt

Then it rotates the transform to point its up direction vector in the direction hinted at by the worldUp vector. If you leave out the worldUp parameter, the function will use the world y axis. The up vector of the rotation will only match the worldUp vecto

docs.unity3d.com

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

public class Billboard2 : MonoBehaviour
{
    private Transform camTrans;
    private Transform trans;
    void Start()
    {
        this.camTrans=Camera.main.GetComponent<Transform>(); //main Camera의 Transform컴포넌트 가져오기
        this.trans=this.GetComponent<Transform>();
    }
    private void LateUpdate() //카메라를 따라가게하는로직은 LateUpdate에서
    {
        this.trans.LookAt(camTrans.position);
    }
}

*player가 Car,UI (Layer)를 바라보면 이동 멈춤

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

public class Player2 : MonoBehaviour
{
    public enum eMoveType
    {
        WayPoint,
        LookAt
    }
    public eMoveType moveType= eMoveType.WayPoint;
    public Transform[] waypoints;
    private float speed = 2f;
    private int idx = 0;

    private float damping = 3f;
    public bool isStoped = false;
    private void Start()
    {
        this.GetComponent<CharacterController>();
    }
    private void Update()
    {
        //this.MoveWaypoint();
        if (isStoped) return;
        switch (this.moveType)
        {
            case eMoveType.WayPoint:
                this.MoveWaypoint();
                break;
            case eMoveType.LookAt:
                break;
        }
        
    }
    public void MoveWaypoint()
    {
        //순회 이동
        this.transform.position = Vector3.MoveTowards(
            this.transform.position, waypoints[idx].transform.position, speed * Time.deltaTime);
        if (this.transform.position == waypoints[idx].transform.position)
            this.idx++;
        if (this.idx == this.waypoints.Length)
            this.idx = 0;        
        //회전
        //현재 위치에서 다음 웨이포인트로 향하는 백터
        Vector3 dir = this.waypoints[idx].position-this.transform.position; 
        //백터의 회전 각도
        Quaternion rot=Quaternion.LookRotation(dir);
        //회전처리
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rot, Time.deltaTime * damping);
    }

}

*RaycastHit 반응을 통해 이벤트 호출

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class EyeCast2 : MonoBehaviour
{
    private Transform trans;
    private Ray ray;
    private RaycastHit hit;
    public float dist = 10f;
    public Player2 player;
    public Image img; //fill Image
    private GameObject preveBtn;
    private GameObject currBtn;
    private float time = 1.0f; 
    private float delta = 0f;
    private bool isClicked=false;
    void Start()
    {
        this.trans=this.GetComponent<Transform>();
    }
    private void InitButton()
    {
        this.delta = 0;
        this.isClicked = false;
        if(this.img!=null)
        {
            this.img.fillAmount= 0;
        }
    }

    void Update()
    {
        this.ray=new Ray(this.trans.position,this.trans.forward);
        Debug.DrawRay(this.ray.origin,this.ray.direction*this.dist,Color.red);
        
        //비트연산자를 이용하여 Layer 이용
        var mask = 1 << 8 | 1 << 9; //8 과 9 레이어
        if(Physics.Raycast(this.ray,out this.hit, this.dist, mask))
        {
            this.player.isStoped = true;
            this.GazButton();
        }
        else
        {
            this.player.isStoped = false;
            this.ReleaseButton();
        }
    }


    private void GazButton()
    {
        //현재 시점의 포인터 이벤트 정보 추출
        GvrPointerEventData data=new GvrPointerEventData(EventSystem.current);
        //현재 응시하고있는것이 버튼이면
        if (this.hit.collider.gameObject.layer == 8)
        {   //Ray에 맞은 버튼을 현재 응시하는 버튼에 저장
            this.currBtn=this.hit.collider.gameObject;
            //이전 버튼과 현재 응시 하고있는버튼이 서로 다르다면?
            if(this.preveBtn!=this.currBtn)
            {
                //버튼의 응시여부 및 시간의 초기화
                this.InitButton();
                //현재응시하고있는 버튼에 PointerEnter이벤트 전달
                ExecuteEvents.Execute(this.currBtn, data, ExecuteEvents.pointerEnterHandler);
                //이전에 응시했던 버튼에 PointerExit이벤트 전달
                ExecuteEvents.Execute(this.preveBtn, data, ExecuteEvents.pointerExitHandler);
                //이전 버튼의 정보 갱신
                this.preveBtn = currBtn;
            }
            else
            {
                //이미버튼을 응시해서 클릭 이벤트가 호출된 경우 더이상 fill을 채우지 않고 빠져나감
                if (this.isClicked) return;
                this.delta += Time.deltaTime;
                this.img.fillAmount = this.delta / this.time;
                if (this.delta >= this.time)
                {
                    Debug.LogFormat("{0} clicked", this.currBtn.name);
                    //클릭 이벤트 전달
                    ExecuteEvents.Execute(this.currBtn, data, ExecuteEvents.pointerClickHandler);
                    this.isClicked= true;
                }
            }
        }
    }

    //레티클이 버튼 이외의 다른곳을 응시 했을때 기존 버튼 초기화
    private void ReleaseButton()
    {
        //버튼 응시 정보 초기화
        this.InitButton();
        //현재 시점의 포인터 이벤트 정보 추출
        PointerEventData data=new PointerEventData(EventSystem.current);
        //이전에 응시했던 버튼이있다면
        if (this.preveBtn != null)
        {   //이전에 응시했던 버튼에 PoinerExit 이벤트 전달
            ExecuteEvents.Execute(this.preveBtn,data, ExecuteEvents.pointerExitHandler);
            this.preveBtn = null;
        }
    }
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함