我目前正在学习Unity,并且在我正在做的项目上停留了一段时间。
我有一个火星模型,该模型被赋予旋转扭矩,并且有两个卫星绕其旋转。我希望能够使用箭头键在周围移动相机,但是似乎无法弄清楚。
当前代码(全部在一个名为GameManager的脚本中):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManagerScript : MonoBehaviour
{
// Start is called before the first frame update
public GameObject mars;//planet
public GameObject phobos;//moon1
public GameObject deimos;//moon2
public GameObject refpoint;//empty game object I placed inside mars
//All object are referenced using the inspector
void Start()
{
Camera.main.transform.position = new Vector3(0,0,-200);
Camera.main.transform.LookAt(mars.transform.position);
Rigidbody rb = mars.GetComponent<Rigidbody>();
rb.angularVelocity = new Vector3(0,20,0);
}
// Update is called once per frame
void Update()
{
if(Input.GetKey("up")){
Camera.main.transform.transform.RotateAround(refpoint.transform.position, Vector3.right, 50* Time.deltaTime);
}
else if(Input.GetKey("down")){
Camera.main.transform.transform.RotateAround(refpoint.transform.position, Vector3.right, -50* Time.deltaTime);
}else if(Input.GetKey("right")){
Camera.main.transform.transform.RotateAround(refpoint.transform.position, Vector3.up, -50* Time.deltaTime);
}else if(Input.GetKey("left")){
Camera.main.transform.transform.RotateAround(refpoint.transform.position, Vector3.up, 50* Time.deltaTime);
}
phobos.transform.RotateAround(mars.transform.position, phobos.transform.up, 60*Time.deltaTime);
deimos.transform.RotateAround(mars.transform.position, deimos.transform.up, 50*Time.deltaTime);
}
}
最初效果很好,但是一旦在上/下之后使用左/右,反之亦然,方向就会变得混乱。
任何帮助表示赞赏。
答案 0 :(得分:1)
如果您定义了另一个函数来获取新的Vector旋转,可能会更好,例如:
Vector3 CalculateRotationVector(){
Vector3 RotationVector = Vector3.zero;
if(Input.GetKey("up")){
RotationVector += Vector3.right;
}
else if(Input.GetKey("down")){
RotationVector -= Vector3.right;
}else if(Input.GetKey("right")){
RotationVector -= Vector3.right;
}else if(Input.GetKey("left")){
RotationVector += Vector3.right;
}
return RotationVector;
}
在更新功能中,您可以这样称呼它:
void Update(){
Camera.main.transform.RotateAround(refpoint.transform.position, CalculateRotationVector(), 50* Time.deltaTime);
}
但是我不确定这是否行得通,因为我现在无法统一尝试,可能会给您一个想法。
答案 1 :(得分:0)
您并不总是希望绕全局右轴旋转。您可以在全局down
与参考点到相机的方向之间使用叉积,以找到合适的轴。
此逻辑要求您防止照相机直接在行星上方或下方移动。根据全局上/下角度与从参考点到摄像机的方向之间的夹角以及垂直于上/下轴的摄像机的“最小角度”来夹紧垂直旋转。
此外,Camera.main
在内部调用FindGameObjectsWithTag
,因此recommended来缓存结果。
总的来说,看起来像这样:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManagerScript : MonoBehaviour
{
// Start is called before the first frame update
public GameObject mars;//planet
public GameObject phobos;//moon1
public GameObject deimos;//moon2
public GameObject refpoint;//empty game object I placed inside mars
//All object are referenced using the inspector
private Camera mainCam;
private float cameraRotateSpeed = 50f;
private float cameraMinVerticalAngle = 10f;
void Start()
{
mainCam = Camera.main;
mainCam.transform.position = new Vector3(0,0,-200);
mainCam.transform.LookAt(mars.transform.position);
Rigidbody rb = mars.GetComponent<Rigidbody>();
rb.angularVelocity = new Vector3(0,20,0);
}
// Update is called once per frame
void Update()
{
float horizontalRotateDirection = 0f;
float verticalRotateDirection = 0f;
if(Input.GetKey("up")){
doRotate = true;
verticalRotateDirection += 1f;
}
if(Input.GetKey("down")){
doRotate = true;
verticalRotateDirection -= 1f;
}
if(Input.GetKey("right")){
doRotate = true;
horizontalRotateDirection += 1f;
}
if(Input.GetKey("left")){
doRotate = true;
verticalRotateDirection -= 1f;
}
float horizontalRotateAmount = horizontalRotateDirection
* cameraRotateSpeed * Time.deltaTime;
float verticalRotateAmount = verticalRotateDirection
* cameraRotateSpeed * Time.deltaTime;
// Prevent camera from flipping
Vector3 fromRefToCam = (mainCam.transform.position - refpoint.transform.position).normalized;
float maxRotateDown = Vector3.Angle(Vector3.down, fromRefToCam);
float maxRotateUp = Vector3.Angle(Vector3.up, fromRefToCam)
verticalRotateAmount = Mathf.Clamp(verticalRotateAmount,
cameraMinVerticalAngle - maxRotateDown,
maxRotateUp - cameraMinVerticalAngle);
Vector3 verticalRotateAxis = Vector3.Cross(Vector3.down, fromRefToCam);
//Rotate horizontally around global down
mainCam.transform.RotateAround(refpoint.transform.position,
Vector3.up,
horizontalRotateAmount);
// Rotate vertically around camera's right (in global space)
mainCam.transform.RotateAround(refpoint.transform.position,
verticalRotateAxis,
verticalRotateAmount);
phobos.transform.RotateAround(mars.transform.position, phobos.transform.up,
60*Time.deltaTime);
deimos.transform.RotateAround(mars.transform.position, deimos.transform.up,
50*Time.deltaTime);
}
}
答案 2 :(得分:0)
我相信RotateAround是一个错误。使用其他建议的解决方案,您会很快迷失在旋转中,而相机倒置甚至侧向倾斜。
public class GameManagerScript : MonoBehaviour
{
// Start is called before the first frame update
public GameObject mars;//planet
public GameObject phobos;//moon1
public GameObject deimos;//moon2
public GameObject refpoint;//empty game object I placed inside mars
//All object are referenced using the inspector
public float cameraAngularVelocity = 60f;
public float cameraDistance = 200;
public float cameraAngleY = 0;
public float cameraAngleX = 0;
private Camera mainCam;
void Start()
{
mainCam = Camera.main;
}
void Update()
{
float angleDelta = cameraAngularVelocity * Time.deltaTime;
//Standard Input management
if (Input.GetKey("up"))
{
cameraAngleX += angleDelta;
}
if (Input.GetKey("down"))
{
cameraAngleX -= angleDelta;
}
if (Input.GetKey("right"))
{
cameraAngleY -= angleDelta;
}
if (Input.GetKey("left"))
{
cameraAngleY += angleDelta;
}
//Alternative using axis
cameraAngleX += Input.GetAxis("Vertical") * angleDelta;
cameraAngleY += Input.GetAxis("Horizontal") * angleDelta;
//Protections
cameraAngleX = Mathf.Clamp(cameraAngleX, -90f, 90f);
cameraAngleY = Mathf.Repeat(cameraAngleY, 360f);
Quaternion cameraRotation =
Quaternion.AngleAxis(cameraAngleY, Vector3.up)
* Quaternion.AngleAxis(cameraAngleX, Vector3.right);
Vector3 cameraPosition =
refpoint.transform.position
+ cameraRotation * Vector3.back * cameraDistance;
mainCam.transform.position = cameraPosition;
mainCam.transform.rotation = cameraRotation;
phobos.transform.RotateAround(mars.transform.position, phobos.transform.up, 60 * Time.deltaTime);
deimos.transform.RotateAround(mars.transform.position, deimos.transform.up, 50 * Time.deltaTime);
}
}
此解决方案可锁定您的侧倾,并防止垂直方向通过X旋转。
答案 3 :(得分:-2)
看看这个。
https://docs.unity3d.com/ScriptReference/Transform.RotateAround.html
借助此功能,您可以围绕给定点旋转。如果您将其与按键输入相结合,并且将恒定速度乘以Time.deltaTime
,则可能会起作用