void Update() { if (ARAVRInput.IsPC() == false) { return; } // 마우스 입력에 따라 카메라를 회전 시키고 싶다. // 1. 사용자의 마우스 입력을 얻어와야 한다. // 마우스의 좌우 입력을 받는다. float x = Input.GetAxis("Mouse X"); float y = Input.GetAxis("Mouse Y"); #if Remote Vector3 pos = Input.mousePosition - lastPos; pos.Normalize(); x = pos.x; y = pos.y; lastPos = Input.mousePosition; #endif // 2. 방향이 필요하다. // 이동 공식에 대입하여 각 속성별로 회전 값을 누적 시킨다. angle.x += x * sensitivity * Time.deltaTime; angle.y += y * sensitivity * Time.deltaTime; angle.y = Mathf.Clamp(angle.y, -90, 90); // 3. 회전 시키고 싶다. // 카메라의 회전값에 새로 만들어진 회전 값을 할당한다. transform.eulerAngles = new Vector3(-angle.y, angle.x, angle.z); }
void Update() { // 왼쪽 컨트롤러의 One 버튼을 누르면 if (ARAVRInput.GetDown(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 라인랜더러 컴포넌트 활성화 lr.enabled = true; } // 왼쪽 컨트롤러의 One 버튼을 떼면 else if (ARAVRInput.GetUp(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 라인랜더러 비활성화 lr.enabled = false; // 텔레포트 UI 가 활성화 되어 있을 때 if (teleportCircleUI.gameObject.activeSelf) { GetComponent <CharacterController>().enabled = false; // 텔레포트 UI 위치로 순간이동 transform.position = teleportCircleUI.position + Vector3.up; GetComponent <CharacterController>().enabled = true; } // 텔레포트 UI 비활성화 teleportCircleUI.gameObject.SetActive(false); } // 왼쪽 컨트롤러의 One 버튼을 누르고 있을때 else if (ARAVRInput.Get(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 주어진 길이크기의 커브를 만들고 싶다. MakeLines(); } }
void Update() { // 사용자의 입력에 따라 앞뒤좌우로 이동하고 싶다. // 1. 사용자의 입력을 받는다. float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); // 2. 방향을 만든다. Vector3 dir = new Vector3(h, 0, v); // 2.0 사용자가 바라보는 방향으로 입력 값을 변화 시키기 dir = Camera.main.transform.TransformDirection(dir); // 2.1 중력 적용한 수직 방향 추가 v=v0+at yVelocity += gravity * Time.deltaTime; // 2.2 바닥에 있을 경우 수직항력처리를 위해 속도를 0으로 한다. if (cc.isGrounded) { yVelocity = 0; } // 2.3 사용자가 점프버튼을 누르면 속도에 점프크기를 할당한다. if (ARAVRInput.GetDown(ARAVRInput.Button.Two, ARAVRInput.Controller.RTouch)) { yVelocity = jumpPower; } dir.y = yVelocity; // 3. 이동한다. cc.Move(dir * speed * Time.deltaTime); }
void Update() { // 크로스헤어 표시 ARAVRInput.DrawCrosshair(crosshair); // 사용자가 IndexTrigger 버튼을 누르면 if (ARAVRInput.GetDown(ARAVRInput.Button.IndexTrigger)) { // 컨트롤러의 진동 재생 ARAVRInput.PlayVibration(ARAVRInput.Controller.RTouch); // 총알 오디오 재생 bulletAudio.Stop(); bulletAudio.Play(); // Ray 를 카메라의 위치로 부터 나가도록 만든다. Ray ray = new Ray(ARAVRInput.RHandPosition, ARAVRInput.RHandDirection); // Ray 의 충돌정보를 저장하기 위한 변수 지정 RaycastHit hitInfo; // 플레이어 레이어 얻어오기 int playerLayer = 1 << LayerMask.NameToLayer("Player"); // 타워 레이어 얻어오기 int towerLayer = 1 << LayerMask.NameToLayer("Tower"); int layerMask = playerLayer | towerLayer; // Ray 를 쏜다. ray 가 부딪힌 정보는 hitInfo 에 담긴다. if (Physics.Raycast(ray, out hitInfo, 200, ~layerMask)) { // 총알파편효과 처리 // 총알 이펙트 진행되고 있으면 멈추고 재생 bulletEffect.Stop(); bulletEffect.Play(); // 부딪힌 지점의 방향으로 총알 이펙트 방향을 설정 bulletImpact.up = hitInfo.normal; // 부딪힌 지점 바로 위에서 이펙트가 보여지도록 설정 bulletImpact.position = hitInfo.point; // ray 와 부딪힌 객체가 drone 이라면 폭발효과 처리 if (hitInfo.transform.name.Contains("Drone")) { // 폭발 효과가 있다면 if (explosion) { // 드론위치에 폭발효과 놓기 explosion.position = hitInfo.transform.position; // 폭발 효과 재생 explosionEffect.Stop(); explosionEffect.Play(); // 폭발 오디오 재생 explosion.GetComponent <AudioSource>().Stop(); explosion.GetComponent <AudioSource>().Play(); } // 드론 제거 Destroy(hitInfo.transform.gameObject); } } } }
void Update() { // 사용자의 입력에 따라 앞뒤좌우로 이동하고 싶다. // 1. 사용자의 입력을 받는다. float h = ARAVRInput.GetAxis("Horizontal"); float v = ARAVRInput.GetAxis("Vertical"); // 2. 방향을 만든다. Vector3 dir = new Vector3(h, 0, v); // 2.0 사용자가 바라보는 방향으로 입력 값을 변화 시키기 dir = Camera.main.transform.TransformDirection(dir); // 2.1 중력 적용한 수직 방향 추가 v=v0+at yVelocity += gravity * Time.deltaTime; // 2.2 바닥에 있을 경우 수직항력처리를 위해 속도를 0으로 한다. if (cc.isGrounded) { yVelocity = 0; } // 2.3 사용자가 점프버튼을 누르면 속도에 점프크기를 할당한다. if (ARAVRInput.GetDown(ARAVRInput.Button.Two, ARAVRInput.Controller.RTouch)) { yVelocity = jumpPower; } dir.y = yVelocity; // 3. 이동한다. cc.Move(dir * speed * Time.deltaTime); // 오른쪽 터치패드 혹은 썸스틱을 아래로 내리면 Recenter 한다. float recenter = ARAVRInput.GetAxis("Vertical", ARAVRInput.Controller.RTouch); if (recenter < 0) { if (!bRecentering) { ARAVRInput.Recenter(transform, Vector3.back); //ARAVRInput.Recenter(); } bRecentering = true; } else { bRecentering = false; } }
private void TryGrab() { // Grab 버튼을 누르면 일정영역안에 있는 폭탄을 잡는다. // 1. grab 버튼을 눌렀다면 if (ARAVRInput.GetDown(ARAVRInput.Button.HandTrigger, ARAVRInput.Controller.RTouch)) { int closest = 0; // 2. 일정영역 안에 폭탄이 있으니까 // - 영역안에 있는 모든 폭탄 검출 Collider[] hitObjects = Physics.OverlapSphere(ARAVRInput.RHandPosition, grabRange, grabbedLayer); // - 손과 가장 가까운 물체 선택 for (int i = 1; i < hitObjects.Length; i++) { // 손과 가장 가까운 물체와의 거리 Vector3 closestPos = hitObjects[closest].transform.position; float closestDistance = Vector3.Distance(closestPos, ARAVRInput.RHandPosition); // 다음 물체와 손과의 거리 Vector3 nextPos = hitObjects[i].transform.position; float nextDistance = Vector3.Distance(nextPos, ARAVRInput.RHandPosition); // 다음 물체와의 거리가 더 가깝다면 if (nextDistance < closestDistance) { // 가장가까운 물체 인덱스 교체 closest = i; } } // 3. 폭탄을 잡는다. // - 검출된 물체가 있을 경우 if (hitObjects.Length > 0) { // 잡은 상태로 전환 isGrabbing = true; // 잡은 물체기억 grabbedObject = hitObjects[closest].gameObject; // 잡은 물체를 손의 자식으로 등록 grabbedObject.transform.parent = ARAVRInput.RHand; // 물리기능 정지 grabbedObject.GetComponent <Rigidbody>().isKinematic = true; // 초기 위치값 지정 prevPos = ARAVRInput.RHand.position; // 초기 회전 값 지정 prevRot = ARAVRInput.RHand.rotation; } } }
private void TryUngrab() { // 던질 방향 Vector3 throwDirection = (ARAVRInput.RHandPosition - prevPos); // 위치 기억 prevPos = ARAVRInput.RHandPosition; // 쿼터니온 공식 // angle1 = Q1, angle2 = Q2 // angle1 + angle2 = Q1 * Q2 // -angle2 = Quaternion.Inverse(Q2) // angle2 - angle1 = Quaternion.FromToRotation(Q1, Q2) = Q2 * Quaternion.Inverse(Q1) // 회전 방향 = current - previous 의 차 로 구함 - previous 는 Inverse 로 구함 Quaternion deltaRotation = ARAVRInput.RHand.rotation * Quaternion.Inverse(prevRot); // 이전 회전 저장 prevRot = ARAVRInput.RHand.rotation; // 버튼을 놓았다면 if (ARAVRInput.GetUp(ARAVRInput.Button.HandTrigger, ARAVRInput.Controller.RTouch)) { // 잡지 않은 상태로 전환 isGrabbing = false; // 물리기능 활성화 grabbedObject.GetComponent <Rigidbody>().isKinematic = false; // 손에서 폭탄 떼어내기 grabbedObject.transform.parent = null; // 던지기 grabbedObject.GetComponent <Rigidbody>().velocity = throwDirection * throwPower; // 각속도 = (1/dt) * dθ(특정축 기준 변위각도) float angle; Vector3 axis; deltaRotation.ToAngleAxis(out angle, out axis); Vector3 angularVelocity = (1.0f / Time.deltaTime) * angle * axis; grabbedObject.GetComponent <Rigidbody>().angularVelocity = angularVelocity; // 잡은 물체 없도록 설정 grabbedObject = null; } }
void Update() { // 왼쪽 컨트롤러의 One 버튼을 누르면 if (ARAVRInput.GetDown(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 라인랜더러 컴포넌트 활성화 lr.enabled = true; } // 왼쪽 컨트롤러의 One 버튼을 떼면 else if (ARAVRInput.GetUp(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 라인랜더러 비활성화 lr.enabled = false; if (teleportCircleUI.gameObject.activeSelf) { // 워프 기능 사용이 아닐때 순간이동 처리 if (isWarp == false) { GetComponent <CharacterController>().enabled = false; // 텔레포트 UI 위치로 순간이동 transform.position = teleportCircleUI.position + Vector3.up; GetComponent <CharacterController>().enabled = true; } else { // 워프 기능 사용할때는 Warp() 코루틴 호출 StartCoroutine(Warp()); } } // 텔레포트 UI 비활성화 teleportCircleUI.gameObject.SetActive(false); } // 왼쪽 컨트롤러의 One 버튼을 누르고 있을때 else if (ARAVRInput.Get(ARAVRInput.Button.One, ARAVRInput.Controller.LTouch)) { // 1. 왼쪽 컨트롤러를 기준으로 Ray 를 만든다. Ray ray = new Ray(ARAVRInput.LHandPosition, ARAVRInput.LHandDirection); RaycastHit hitInfo; int layer = 1 << LayerMask.NameToLayer("Terrain"); // 2. Terrain 만 Ray 충돌 검출 if (Physics.Raycast(ray, out hitInfo, 200, layer)) { // 3. Ray 가 부딪힌 지점에 라인그리기 lr.SetPosition(0, ray.origin); lr.SetPosition(1, hitInfo.point); // 4. Ray 가 부딪힌 지점에 텔레포트 UI 표시 teleportCircleUI.gameObject.SetActive(true); teleportCircleUI.position = hitInfo.point; // 텔레포트 UI 가 위로 누워 있도록 방향 설정 teleportCircleUI.forward = hitInfo.normal; // 텔레포트 UI 의 크기가 거리에 따라 보정 되도록 설정 teleportCircleUI.localScale = originScale * Mathf.Max(1, hitInfo.distance); } else { // Ray 충돌이 발생하지 않으면 선이 Ray 방향으로 그려지도록 처리 lr.SetPosition(0, ray.origin); lr.SetPosition(1, ray.origin + ARAVRInput.LHandDirection * 200); // 텔레포트 UI 는 화면에서 비활성화 teleportCircleUI.gameObject.SetActive(false); } } }
private void TryGrab() { // Grab 버튼을 누르면 일정영역안에 있는 폭탄을 잡는다. // 1. grab 버튼을 눌렀다면 if (ARAVRInput.GetDown(ARAVRInput.Button.HandTrigger, ARAVRInput.Controller.RTouch)) { // 원거리 물체 잡기 사용한다면 if (isRemoteGrab) { // 손방향으로 레이 제작 Ray ray = new Ray(ARAVRInput.RHandPosition, ARAVRInput.RHandDirection); RaycastHit hitInfo; // SphereCast 를 이용하여 물체 충돌 체크 if (Physics.SphereCast(ray, 0.5f, out hitInfo, remoteGrabDistance, grabbedLayer)) { // 잡은 상태로 전환 isGrabbing = true; // 잡은 물체기억 grabbedObject = hitInfo.transform.gameObject; // 물체가 끌려오는 기능 실행 StartCoroutine(GrabbingAnimation()); } return; } int closest = 0; // 2. 일정영역 안에 폭탄이 있으니까 // - 영역안에 있는 모든 폭탄 검출 Collider[] hitObjects = Physics.OverlapSphere(ARAVRInput.RHandPosition, grabRange, grabbedLayer); // - 손과 가장 가까운 물체 선택 for (int i = 1; i < hitObjects.Length; i++) { // 손과 가장 가까운 물체와의 거리 Vector3 closestPos = hitObjects[closest].transform.position; float closestDistance = Vector3.Distance(closestPos, ARAVRInput.RHandPosition); // 다음 물체와 손과의 거리 Vector3 nextPos = hitObjects[i].transform.position; float nextDistance = Vector3.Distance(nextPos, ARAVRInput.RHandPosition); // 다음 물체와의 거리가 더 가깝다면 if (nextDistance < closestDistance) { // 가장가까운 물체 인덱스 교체 closest = i; } } // 3. 폭탄을 잡는다. // - 검출된 물체가 있을 경우 if (hitObjects.Length > 0) { // 잡은 상태로 전환 isGrabbing = true; // 잡은 물체기억 grabbedObject = hitObjects[closest].gameObject; // 잡은 물체를 손의 자식으로 등록 grabbedObject.transform.parent = ARAVRInput.RHand; // 물리기능 정지 grabbedObject.GetComponent <Rigidbody>().isKinematic = true; // 초기 위치값 지정 prevPos = ARAVRInput.RHandPosition; // 초기 회전 값 지정 prevRot = ARAVRInput.RHand.rotation; } } }