Unity相机自由观察场景模型方法总结

这篇博客介绍了在Unity3D中如何实现三维和二维场景下相机的自由移动和旋转。对于三维场景,通过WASD及鼠标控制相机移动和旋转,使用透视模式,并通过碰撞器限制相机移动范围。二维场景中,同样使用WASD移动,滚轮缩放,但相机切换为正交模式,并根据相机缩放调整移动速度,同时限制相机在特定范围内移动。两种方法都提供了相应的脚本实现。
摘要由CSDN通过智能技术生成

一:方法一

适用场景:三维场景中,需要自由、全方位观察模型
描述:通过WASD控制相机的移动,鼠标控制相机的旋转,相机正视的方向即为正前方,按W前进,S后退,A左边平移,D右边平移。滚轮控制视野的放大缩小。
相机需要加一个碰撞器,加碰撞器是为了限制相机在一个范围内移动,然后还需要把相机的可移动范围也用碰撞器包围起来,需要注意的是,不要用一个整的大的碰撞器,这样的话可能会把相机给弹飞,最好还是每一个面都加一个碰撞体,还有就是相机最好加球形碰撞体。
相机使用的事透视模式。
然后将下面脚本挂载在相机上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLook : MonoBehaviour
{

    //public Transform character;
    public Transform _Camera;

    public float XSensitivity = 1.5f;
    public float YSensitivity = 1.5f;
    public bool clampVerticalRotation = false;
    public float MinimumX = -45F;
    public float MaximumX = 45F;
    public bool smooth = true;
    public float smoothTime = 8f;


    private Quaternion m_CharacterTargetRot;
    private Quaternion m_CameraTargetRot;

    private bool isMove = true;

    private void Start()
    {
        Init();
    }

    private void Update()
    {
        //if (Input.GetMouseButton(1))
        //{
        //    LookRotation(_Camera);
        //}
        LookRotation(_Camera);

        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 dir = transform.forward * v + transform.right * h;
        transform.GetComponent<Rigidbody>().velocity = dir * 20;

        if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            //限制size大小
            transform.GetComponent<Camera>().fieldOfView = Mathf.Clamp(transform.GetComponent<Camera>().fieldOfView, 10, 75);
            //滚轮改变
            transform.GetComponent<Camera>().fieldOfView =
            transform.GetComponent<Camera>().fieldOfView - Input.GetAxis
            ("Mouse ScrollWheel") * 20;
        }
    }

    public void Init()
    {
        //m_CharacterTargetRot = character.localRotation;
        m_CameraTargetRot = _Camera.localRotation;
    }


    public void LookRotation(Transform _camera)
    {
        float yRot = Input.GetAxis("Mouse X") * XSensitivity;
        float xRot = Input.GetAxis("Mouse Y") * YSensitivity;


        m_CameraTargetRot = _camera.localRotation * Quaternion.Euler(-xRot, yRot, 0f);

        if (clampVerticalRotation)
            m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);

        if (smooth)
        {
            _camera.localRotation = Quaternion.Slerp(_camera.localRotation, m_CameraTargetRot,
                smoothTime * Time.deltaTime);

        }
        else
        {

            _camera.localRotation = m_CameraTargetRot;
        }
        _camera.localRotation = Quaternion.Euler(new Vector3(_camera.eulerAngles.x, _camera.eulerAngles.y, 0f));

    }


    Quaternion ClampRotationAroundXAxis(Quaternion q)
    {
        q.x /= q.w;
        q.y /= q.w;
        q.z /= q.w;
        q.w = 1.0f;

        float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);

        angleX = Mathf.Clamp(angleX, MinimumX, MaximumX);

        q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * angleX);

        return q;
    }

}

具体组件、参数设置如下图所示:
在这里插入图片描述

二:方法二

适用场景:二维场景中,需要自由、全方位观察模型
描述:通过WASD控制相机的移动,相机正视的方向即为正前方,按W向上移动,S向下移动,A左边平移,D右边平移。滚轮控制视野的放大缩小。
通过相机的位置坐标来控制相机的移动范围
相机使用的是正交模式。
然后将下面脚本挂载在相机上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//巡游模式摄像机控制
public class CameraController : MonoBehaviour
{


    private Vector3 dirVector3;
    private Vector3 rotaVector3;
    [SerializeField]
    private float paramater = 1f;

    private float dis = 1;
    //相机缩放范围
    public int MinOrthographicSize=10;
    public int MaxOrthographicSize = 120;

    //相机移动的范围
    public Vector2 MoveX=new Vector2(-215f, 85f);
    public Vector2 MoveY = new Vector2(-75f, 92f);
    void Awake()
    {

    }

    private void Start()
    {
      
    }
    private void Update()
    {
        //移动
        dirVector3 = Vector3.zero;

        if (Input.GetKey(KeyCode.W)||Input.GetKey(KeyCode.UpArrow))
        {
            dirVector3.y = 1;
        }
        if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
        {
            dirVector3.y = -1;
        }
        if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
        {
            dirVector3.x = -1;
        }
        if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
        {
            dirVector3.x = 1;
        }

        if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            //限制size大小
            transform.GetComponent<Camera>().orthographicSize = Mathf.Clamp(transform.GetComponent<Camera>().orthographicSize, MinOrthographicSize, MaxOrthographicSize);
            //滚轮改变
            transform.GetComponent<Camera>().orthographicSize =
            transform.GetComponent<Camera>().orthographicSize - Input.GetAxis
            ("Mouse ScrollWheel") * 20;
        }         

        //在不同的缩放下  相对的降低相机的移动速度 
        if (80< transform.GetComponent<Camera>().orthographicSize&&transform.GetComponent<Camera>().orthographicSize<100)
        {           
            paramater = 0.8f;        
        }
        if (50 < transform.GetComponent<Camera>().orthographicSize && transform.GetComponent<Camera>().orthographicSize < 80)
        {
            paramater = 0.5f;
        }
        if (30 < transform.GetComponent<Camera>().orthographicSize && transform.GetComponent<Camera>().orthographicSize < 50)
        {
            paramater = 0.25f;
        }
        if (10 < transform.GetComponent<Camera>().orthographicSize && transform.GetComponent<Camera>().orthographicSize < 30)
        {
            paramater = 0.15f;
        }
        if ( transform.GetComponent<Camera>().orthographicSize < 10)
        {
            paramater = 0.05f;
        }
        transform.Translate(dirVector3 * paramater, Space.Self);
        //限制摄像机范围
       
        float TempX = Mathf.Clamp(transform.position.x, MoveX.x, MoveX.y);
        float TempY = Mathf.Clamp(transform.position.y, MoveY.x,MoveY.y);
       
        transform.position = new Vector3(TempX, TempY, 30);
    }
    // Update is called once per frame
    void FixedUpdate()
    {
       
    }
}

具体组件、参数设置如下图所示:
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值