이 답변에 대한 내 이전 답변의 댓글 스레드를 참조하십시오.
카메라가 특정 지점을 중심으로 궤도에 진입하는 데는 두 가지 방법이 있습니다. 다른 작업을하기 전에 Unity에서 빈 GameObject를 생성하고 카메라를 궤도에 진입시키려는 고정 점에 설정하십시오. GameObject가 카메라의 시야에 있는지 확인하십시오. 그런 다음 카메라를 Empty GameObject의 부모로 삼으십시오.
쉬운 (그러나 더 단단한) 접근을 위해 TouchCamera 스크립트를 Empty GameObject에 연결하십시오. 카메라에서 TouchCamera 스크립트를 제거하십시오. 이제 스크립트의 Update 메서드 시작 부분 위에이 줄을 public Camera camera
추가하십시오. 스크립트에서 GetComponent<Camera>()
의 모든 항목을 camera
으로 바꿉니다. 스크립트를 저장하고 Unity로 돌아갑니다. 마지막으로 빈 GameObject를 클릭하고 카메라를 TouchCamera 구성 요소의 Serialized Camera 필드로 드래그하십시오. 이 접근법은 본질적으로 카메라의 제어를 Empty GameObject로 이동시킵니다.
더 복잡하지만 (더 유연한) 접근 방식을 위해 새 C# 스크립트를 만들고 "CameraControl"이라고 이름을 지정하십시오. 그런 다음 스크립트에 다음 코드를 복사하여 붙여 넣으십시오 (이미있는 코드를 대체하십시오).
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
public class CameraControl : MonoBehaviour {
Vector2?[] oldTouchPositions = {
null,
null
};
Vector2 oldTouchVector;
float oldTouchDistance;
public Transform CenterOfRotation;
public Camera camera;
private Vector2 actualCenter;
private Vector2 prevTouchDelta;
private Vector3 prevMousePosition;
private bool rotate;
void Start()
{
//swap with below commented line for y rotation.
actualCenter = new Vector2(CenterOfRotation.position.x, CenterOfRotation.position.z);
//actualCenter = new Vector2(CenterOfRotation.position.x, CenterOfRotation.position.y);
}
void Update() {
if(!rotate){
if (Input.touchCount == 0) {
oldTouchPositions[0] = null;
oldTouchPositions[1] = null;
}
else if (Input.touchCount == 1) {
if (oldTouchPositions[0] == null || oldTouchPositions[1] != null) {
oldTouchPositions[0] = Input.GetTouch(0).position;
oldTouchPositions[1] = null;
}
else {
Vector2 newTouchPosition = Input.GetTouch(0).position;
transform.position += transform.TransformDirection((Vector3)((oldTouchPositions[0] - newTouchPosition) * camera.orthographicSize/camera.pixelHeight * 2f));
oldTouchPositions[0] = newTouchPosition;
}
}
else {
if (oldTouchPositions[1] == null) {
oldTouchPositions[0] = Input.GetTouch(0).position;
oldTouchPositions[1] = Input.GetTouch(1).position;
oldTouchVector = (Vector2)(oldTouchPositions[0] - oldTouchPositions[1]);
oldTouchDistance = oldTouchVector.magnitude;
}
else {
Vector2 screen = new Vector2(camera.pixelWidth, camera.pixelHeight);
Vector2[] newTouchPositions = {
Input.GetTouch(0).position,
Input.GetTouch(1).position
};
Vector2 newTouchVector = newTouchPositions[0] - newTouchPositions[1];
float newTouchDistance = newTouchVector.magnitude;
transform.position += transform.TransformDirection((Vector3)((oldTouchPositions[0] + oldTouchPositions[1] - screen) * camera.orthographicSize/screen.y));
//transform.localRotation *= Quaternion.Euler(new Vector3(0, Mathf.Asin(Mathf.Clamp((oldTouchVector.y * newTouchVector.x - oldTouchVector.x * newTouchVector.y)/oldTouchDistance/newTouchDistance, -1f, 1f))/0.0174532924f, 0));
camera.orthographicSize *= oldTouchDistance/newTouchDistance;
transform.position -= transform.TransformDirection((newTouchPositions[0] + newTouchPositions[1] - screen) * camera.orthographicSize/screen.y);
oldTouchPositions[0] = newTouchPositions[0];
oldTouchPositions[1] = newTouchPositions[1];
oldTouchVector = newTouchVector;
oldTouchDistance = newTouchDistance;
}
}
}
else{
InwardRotation();
}
}
void OnGUI()
{
rotate = GUILayout.Toggle(rotate, "Toggle For Rotation", "Button");
}
void InwardRotation()
{
//mouse version
if(Input.GetMouseButton(0))
{
//distance from center of screen to touch
Vector3 centerScreen = camera.ViewportToScreenPoint(new Vector3(0.5f, 0.5f, 1));
Vector3 mouseDelta = Input.mousePosition - new Vector3(centerScreen.x, centerScreen.y, 0f);
//if mouse doesn't move very much, don't rotate
if(mouseDelta.sqrMagnitude < 0.1f)
return;
//attempts to make movement smoother
if(prevMousePosition == Vector3.zero)
prevMousePosition = mouseDelta;
//this gets the angle between the current touch and the last touch
float theta = Mathf.Atan2(mouseDelta.y, mouseDelta.x) - Mathf.Atan2(prevMousePosition.y, prevMousePosition.x);
//Gets the rotated coordinates of the camera. Swap with below commented line for y rotation.
Vector2 newPos = RotatedCoordinates(transform.position.x, transform.position.z, theta, CenterOfRotation.position, true);
//Vector2 newPos = RotatedCoordinates(transform.position.x, transform.position.y, theta, CenterOfRotation.position, true);
Debug.Log("New Pos = " + newPos);
//swap with below commented line for y rotation.
transform.localPosition = new Vector3(newPos.x, transform.localPosition.y, newPos.y);
//transform.localPosition = new Vector3(newPos.x, newPos.y, transform.localPosition.z);
transform.LookAt(CenterOfRotation);
prevMousePosition = mouseDelta;
}
if(Input.touches.Length > 0f)
{
//distance from center of screen to touch
Vector3 centerScreen = camera.ViewportToScreenPoint(new Vector3(0.5f, 0.5f, 1));
Vector2 touchDelta = Input.GetTouch(0).position - new Vector2(centerScreen.x, centerScreen.y);
//if mouse doesn't move very much, don't rotate
if(touchDelta.sqrMagnitude < 0.1f)
return;
//attempts to make movement smoother
if(prevTouchDelta == Vector2.zero)
prevTouchDelta = touchDelta;
//this gets the angle between the current touch and the last touch
float theta = Mathf.Atan2(touchDelta.y, touchDelta.x) - Mathf.Atan2(prevTouchDelta.y, prevTouchDelta.x);
//Gets the rotated coordinates of the camera. Swap with below commented line for y rotation.
Vector2 newPos = RotatedCoordinates(transform.position.x, transform.position.z, theta, CenterOfRotation.position, true);
//Vector2 newPos = RotatedCoordinates(transform.position.x, transform.position.y, theta, CenterOfRotation.position, true);
Debug.Log("New Pos = " + newPos);
//swap with below commented line for y rotation.
transform.localPosition = new Vector3(newPos.x, transform.localPosition.y, newPos.y);
//transform.localPosition = new Vector3(newPos.x, newPos.y, transform.localPosition.z);
transform.LookAt(CenterOfRotation);
prevTouchDelta = touchDelta;
}
else{
prevTouchDelta = Vector2.zero;
}
}
/// <summary>
/// This method returns the coordinates of a plane rotated about its origin. It translates a point from one place on a unit circle to another.
/// </summary>
/// <returns>The coordinates.</returns>
/// <param name="x">The x coordinate.</param>
/// <param name="y">The y coordinate.</param>
/// <param name="theta">Theta.</param>
/// <param name="ThetaInRad">If set to <c>true</c> theta in RAD.</param>
public Vector2 RotatedCoordinates(float x, float y, float theta, Vector2 center, bool ThetaInRad = false)
{
if(!ThetaInRad)
theta *= Mathf.Deg2Rad;
Vector2 XY = new Vector2((Mathf.Cos(theta) * (x - center.x) - Mathf.Sin(theta) * (y - center.y)) + center.x, (Mathf.Sin(theta) * (x - center.x) + Mathf.Cos(theta) * (y - center.y)) + center.y);
return XY;
}
}
이제 카메라에이 첨부 (빈 게임 오브젝트의 자식해야하는)와 TouchCamera 스크립트를 제거합니다. CameraControl 구성 요소에는 "회전 중심"과 "카메라"라는 두 개의 필드가 있습니다. 빈 GameObject 및 카메라를 각각이 필드로 드래그하십시오. 이 스크립트를 생략하면이 스크립트는 Null 참조 오류를 발생시킵니다. 이제 막 치다.재생 창의 왼쪽 상단 모서리에있는 Toggle For Rotation
버튼을 클릭하면 마우스 포인터 또는 한 손가락을 화면 가운데로 드래그하여 카메라를 회전시킬 수 있습니다. Empty GameObject에서 카메라를 떼어 내면 스크립트가 계속 작동합니다. 또한 다른 Transform을 제공하여 우주의 어떤 지점을 도약 할 수 있습니다. 약간의 편집을 통해 Transform을 완전히 없애고 World Space에서 Vector3를 참조 점으로 사용할 수 있지만 transform.LookAt(CenterOfRotation);
행없이 카메라의 실제 회전을 직접 제어해야합니다. 대략 30 번째 줄, 145 번째 줄, 151 번째 줄에있는 3 개의 줄을 편집하여 회전축을 변경할 수 있습니다.
감사합니다! 내가 지금 시험에서보고있는 한 가지 이슈가 있긴하지만. 회전이 시작되면 다른 스 와이프 기능이 더 이상 작동하지 않습니다. 그래서 내가 측면으로 스 와이프하여 회전하면 더 이상 스 와이프 할 수 없습니다. 이상하게 보입니다. 그리고 이것이 빠른 해결책이라고 기대하고 있습니다. 또한 내부로 회전시키는 방법이 있습니까? 기껏해야 카메라가 바깥 쪽을 향하도록 회전합니다. 고마워요 :) – Natecurt3030
재부팅 및 두 번째 테스트 후 문지름이 작동하는 것처럼 보입니다. 아마도 이상한 버그 일 것입니다. 그러나, 나는 아직도 어떤 정보든지 사람이 카메라가 내면을 향하게하는 회전을 가지고 관해 가지고 있을지도 모르는 것을 좋아할 것이다! – Natecurt3030
그래서 여러분이 생각하는 것은 카메라의 로컬 축 중 하나가 아닌 카메라 외부의 한 지점을 중심으로 카메라를 회전시키는 것입니다. 먼저 카메라를 회전시킬 월드 스페이스에서 참조 점을 지정해야하므로 수행하기가 훨씬 더 어려워집니다. 예를 들어 카메라 앞에 20 단위가 고정되어 있거나 회전 할 사용자 정의 점/객체를 선택할 수 있습니다. 네가 뭘하고 있는지 모른 채, 나는별로 도움이 안돼. 미안합니다. – LWKatze