티스토리 뷰
VR City복습(waypoint순회하며 이동,Quaternion.Lerp회전,Raycast)
Game Client Lee Hwanguk 2023. 3. 6. 01:09#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;
}
}
}
'게임클라이언트 프로그래밍 > Unity' 카테고리의 다른 글
Shader (색상 설정, 텍스쳐 제어, lerp함수, UV) (0) | 2023.03.15 |
---|---|
3D Animation controll,Dot (2) | 2023.03.06 |
3D 캐릭터 이동,시야, 공격 애니매이션 구현 (0) | 2023.03.03 |
3D Dot, 캐릭터의 시야 (0) | 2023.03.02 |
3D 캐릭터의 시선 (각도에 따른 변화) (0) | 2023.03.01 |