在两个或更多相机unity3D之间切换

时间:2017-06-01 04:17:56

标签: c# unity3d camera smoothing

我正在制作一个游戏,其中玩家控制两个不同的角色(每个角色都有自己的空对象,相机作为孩子),并通过按下控制键来切换一个或另一个。问题是,我试图通过使用另一台相机在两个角色相机之间进行一点过渡,所以它并不仅仅是在一个和另一个之间传送,但我似乎无法做到。我尝试使用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;  
         }  
     }  
 } 

2 个答案:

答案 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,就可以轻松修改它以像原始代码一样运行。