Tanks案例笔记(三、相机控制)

三、相机控制

1.在Hierarchy面板创建空物体命名CameraRig作为相机父物体,Position(0,0,0),Rotation(40,60,0);

2.把相机拖到CameraRig物体下作为子物体,Position(0,0,-65),Rotation(0,0,0);

3.确保相机是正交模式

4.拖入CameraControl脚本到相机父物体上,脚本:

using UnityEngine;

public class CameraControl : MonoBehaviour
{
    public float m_DampTime = 0.2f;              //相机移动时间(缓慢移动而不是直接到达)   
    public float m_ScreenEdgeBuffer = 4f;     //确保坦克们都在屏幕中间      
    public float m_MinSize = 6.5f;                  
    public Transform[] m_Targets; //相机观察的目标

    private Camera m_Camera;                
    
    private float m_ZoomSpeed;                      
    private Vector3 m_MoveVelocity;                 
    private Vector3 m_DesiredPosition;              //目标位置

    private void Awake()
    {
        m_Camera = GetComponentInChildren();//获取组件
    }

    private void FixedUpdate()
    {
        Move(); //移动相机
        Zoom();//设置相机size
    }

    private void Move()
    {
        //找到相机观察的目标们的中间位置,也就是相机的运动目标位置
        FindAveragePosition();
        //平缓移动相机到中间位置
        transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
    }

    //计算相机观察的目标们的平均位置(中间位置)
    private void FindAveragePosition()
    {
        Vector3 averagePos = new Vector3();
        int numTargets = 0;

        for (int i = 0; i < m_Targets.Length; i++)
        {
            if (!m_Targets[i].gameObject.activeSelf)
                continue;//退出本次循环开始下次循环
            //显示着的所有目标、
            averagePos += m_Targets[i].position;
            numTargets++;
        }
        //计算几个目标位置的平均位置(中间位置)
        if (numTargets > 0)
            averagePos /= numTargets;
        //竖直位置保持不变
        averagePos.y = transform.position.y;

        m_DesiredPosition = averagePos;
    }

    private void Zoom()
    {
        //计算需要的相机的size
        float requiredSize = FindRequiredSize();
        //目标时间内缓慢改变相机的size到目标值
        m_Camera.orthographicSize = Mathf.SmoothDamp(m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
    }

    //计算需要的相机的size(难点)
    private float FindRequiredSize()
    {
        //世界坐标转为本地坐标
        Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);

        float size = 0f;
        //遍历所有目标,计算所有需要的size,找出最大size
        for (int i = 0; i < m_Targets.Length; i++)
        {
            if (!m_Targets[i].gameObject.activeSelf)
                continue;

            Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);

            Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;

            size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.y));

            size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.x) / m_Camera.aspect);
        }
        
        size += m_ScreenEdgeBuffer;

        size = Mathf.Max(size, m_MinSize);

        return size;
    }

    //给外部调用,设置相机位置和size
    public void SetStartPositionAndSize()
    {
        FindAveragePosition();

        transform.position = m_DesiredPosition;

        m_Camera.orthographicSize = FindRequiredSize();
    }
}

设置相机size的过程可能难一点,看一下下面的知识点,然后慢慢理解。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

重要点1:关于相机

相机Projection参数区分了相机是透视类型还是正交类型,如下图:

透视类型有近大远小的效果,而正交类型远近一样大。

Tanks案例笔记(三、相机控制)_第1张图片

Tanks案例笔记(三、相机控制)_第2张图片

所谓aspect就是屏幕的横纵比:

Tanks案例笔记(三、相机控制)_第3张图片


重要点2:Transform.InverseTransformPoint

变换位置从世界坐标到自身坐标。获取参数pos相对于物体的坐标位置。

和Transform.TransformPoint相反。

注意,返回位置受缩放影响。如果你是处理方向使用Transform.InverseTransformDirection。

e.g.:

using UnityEngine;
using System.Collections;
//把世界坐标转为相对物体的坐标,然后看相对位置
public class example : MonoBehaviour {
	public Transform cam = Camera.main.transform;
	public Vector3 cameraRelative = cam.InverseTransformPoint(transform.position);
	public void Awake() {
		if (cameraRelative.z > 0)
			print("The object is in front of the camera");
		else
			print("The object is behind the camera");
	}
}






----------------------------------------------------------------------------------------------------------------------------------------------------------------

你可能感兴趣的:(Unity案例坦克大战)