我正在制作一个游戏,其中玩家控制两个不同的角色(每个角色都有自己的空对象,相机作为孩子),并通过按下控制键来切换一个或另一个。问题是,我试图通过使用另一台相机在两个角色相机之间进行一点过渡,所以它并不仅仅是在一个和另一个之间传送,但我似乎无法做到。我尝试使用lerp,但我不知道我是否正确,所以我阅读并尝试了Vector3.MoveTowards,但仍然无法做到。到目前为止,这是我的代码(这是因为我有一个最后一刻 - 脑死亡):
public class CameraController : MonoBehaviour
{
public Camera cam1;
public Camera cam2;
public Camera movingCamera;
public bool isCurrentPlayer;
public Transform target1;
public Transform target2;
public float speed = 0.2f;
void FixedUpdate()
{
float step = speed * Time.deltaTime;
if (Input.GetButtonDown("Control"))
{
if (isCurrentPlayer)
{
movingCamera.enabled = true;
cam2.enabled = false;
while (transform.position != target1.position)
{
transform.position = Vector3.MoveTowards(transform.position, target1.position, step);
}
if (transform.position == target1.transform.position)
{
movingCamera.enabled = false;
cam1.enabled = true;
}
isCurrentPlayer = false;
}
else if (!isCurrentPlayer)
{
movingCamera.enabled = true;
cam1.enabled = false;
while (transform.position != target2.position)
{
transform.position = Vector3.MoveTowards(transform.position, target2.position, step);
}
if (transform.position == target2.transform.position)
{
movingCamera.enabled = false;
cam2.enabled = true;
}
isCurrentPlayer = true;
}
}
}
答案 0 :(得分:0)
transform.position指向CameraController游戏对象的位置。如果你想移动movingCamera,你可能想使用movingCamera.transform.position。另外请记住,在你的脚本中,MoveTowards()只会在你按下" Control"按钮。
正如memBrain所说,最好只使用一台摄像机 - 视觉上看起来一样。
脚本应如下所示:
// Assuming target1 is player 1 and target2 is player 2
private float snapThreshold = 0.1f;
private Vector3 movingCameraDestination = Vector3.zero;
void FixedUpdate()
{
if(Input.GetButtonDown("Control"))
{
if(isCurrentPlayer)
{
//Set position of transition camera to player 1 and set it's destination to player's 2 position
movingCamera.transform.position = player1.position;
movingCameraDestination = player2.position;
//Disable player 1 camera and enable transition camera
cam1.enabled = false;
movingCamera.enabled = true;
}
else
{
//Set position of transition camera to player 21 and set it's destination to player's 1 position
movingCamera.transform.position = player2.position;
movingCameraDestination = player1.position;
//Disable player 1 camera and enable transition camera
cam2.enabled = false;
movingCamera.enabled = true;
}
}
//If transition camera is enabled and its destination is not Vector3.zero - move it
if(movingCameraDestination != Vector3.zero && movingCamera.enabled)
{
movingCamera.transform.position = Vector3.Lerp(movingCamera.transform.position, movingCameraDestination, speed * Time.deltaTime);
//If the distance between transition camera and it's destination is smaller or equal to threshold - snap it to destination position
if(Vector3.Distance(movingCamera.transform.position, movingCameraDestination) <= snapThreshold)
{
movingCamera.transform.position = movingCameraDestination;
}
//If transition camera reached it's destination set it's destination to Vector3.zero and disable it
if(movingCamera.transform.position == movingCameraDestination)
{
movingCameraDestination = Vector3.zero;
movingCamera.enabled = false;
}
}
}
答案 1 :(得分:0)
我对两件事感到好奇。为什么使用FixedUpdate来管理更新?这不是物理代码。您使用多台摄像机有特殊原因吗?如果可以,我建议进行以下更改。
您可以简单地使用主摄像头而不是多个摄像头。此外,您可以通过使用一组玩家GameObjects来增加可以切换的玩家对象的数量,并通过将输入参数更改为左控制和右控制,您可以在下一个玩家和之前的玩家之间切换以双向导航一系列球员。
这是我实现这些更改的示例代码(经过测试和工作,但可以进行改进。)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Attached to Main Camera
public class CameraController : MonoBehaviour {
// set manually in inspector
public GameObject[] players;
public float movementSpeed = 1.0f;
public float rotationSpeed = 1.0f;
private int currentPlayer;
private float startTime;
private float distanceToPlayer;
private Vector3 startPosition;
private Quaternion startOrientation;
// Use this for initialization
void Start () {
currentPlayer = 0;
ResetCamera();
}
// Update is called once per frame
void Update () {
float distanceCovered;
float rotationCovered;
float fractionTraveled;
// switch to previous
if (Input.GetButtonDown("left ctrl")) {
if (currentPlayer == 0) currentPlayer = players.Length - 1;
else currentPlayer--;
ResetCamera();
}
// switch to nextPlayer
if (Input.GetButtonDown("right ctrl")) {
if (currentPlayer == players.Length - 1) currentPlayer = 0;
else currentPlayer++;
ResetCamera();
}
// Keep moving camera
if (transform.position != players[currentPlayer].transform.position)
{
distanceCovered = (Time.time - startTime) * movementSpeed;
fractionTraveled = distanceCovered / distanceToPlayer;
rotationCovered = (Time.time - startTime) * rotationSpeed;
// Lerp to player position
transform.position = Vector3.Lerp(
startPosition,
players[currentPlayer].transform.position,
fractionTraveled
);
// match player orientation
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
players[currentPlayer].transform.rotation,
rotationCovered
);
// Stop moving camera
} else {
// Match orientation
if (transform.rotation != players[currentPlayer].transform.rotation)
transform.rotation = players[currentPlayer].transform.rotation;
// Set parent transform to current player
transform.parent = players[currentPlayer].transform;
}
}
void ResetCamera() {
transform.parent = null;
startTime = Time.time;
startPosition = transform.position;
startOrientation = transform.rotation;
distanceToPlayer = Vector3.Distance(
transform.position,
players[currentPlayer].transform.position
);
}
}
显然,这些值需要调整,移动算法非常基本。原油但功能。您还可以将玩家移动代码添加到相机中,只需确保它指向玩家[currentPlayer],它将适用于您的每个玩家对象,而不必使用其他脚本,除非有理由这样做。
随意使用此代码。就像我说的,它有效。但是,如果您选择这样做,只需删除数组并恢复单个GameObjects,就可以轻松修改它以像原始代码一样运行。