【问题标题】:Switching between two or more cameras unity3D在两个或多个摄像头之间切换 unity3D
【发布时间】:2017-06-01 17:48:26
【问题描述】:

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

【问题讨论】:

  • 为角色添加空游戏对象以进行相机对接。使用一个摄像机并在更改角色时将摄像机移动到另一个停靠对象并将其指定为子对象。所以你可以控制你的相机移动速度,或者甚至可以添加某种路径让相机以奇特的方式从一个角色飞到另一个角色。
  • 您的CameraController 脚本附加到什么位置?

标签: c# unity3d camera smoothing


【解决方案1】:

我对两件事感到好奇。为什么您使用 FixedUpdate 来管理您的更新?这不是物理代码。您使用多台相机是否有特殊原因?如果可以,我建议进行以下更改。

您可以简单地使用主摄像头而不是多个摄像头。此外,您可以通过使用玩家游戏对象数组来增加可以切换的玩家对象的数量,并且通过将输入参数更改为左控制和右控制,您可以在下一个玩家和上一个玩家之间切换以双向导航玩家数组。

这是实现这些更改的示例代码(经过测试并且可以工作,但可以进行改进。)

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
        );
    }
}

显然需要调整这些值,并且运动算法非常基本。粗糙但功能。您还可以将玩家移动代码添加到相机中,只需确保它指向 player[currentPlayer] 并且它将适用于您的每个玩家对象,而无需使用其他脚本,除非有理由这样做。

请随意使用此代码。就像我说的,它有效。但是,如果您选择这样做,只需删除数组并恢复单个 GameObjects 即可轻松修改它以像您的原始代码一样运行。

【讨论】:

  • 我正在使用多个相机,因为我有等距视图,所以我可以通过让它们拥有一个空游戏对象的子对象来轻松控制角度。我会尝试两种方式的代码并告诉你它是怎么回事,非常感谢!
【解决方案2】:

transform.position 指向 CameraController 游戏对象的位置。如果你想移动movingCamera,你可能想使用movingCamera.transform.position。另外请记住,在您的脚本中,MoveTowards() 只会在您按下“控制”按钮时触发。

正如 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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多