Unity学习-相机的拉伸、跟随、旋转

原创,转载请注明出处@JeroChan

学习了siki的黑暗之光,在学习老师的实现代码之余自己网上还查找了其他的实现方法,为了以后项目方便自己独立封装了旋转、拉伸的方法,使耦合度尽量降低。

定义

private GameObject playerObject;
private Camera cameraObject;
private Vector3 offSetPos; //偏移(相机与目标的差)
public float fieldViewMax = 90f; //拉伸距离最远距离
public float fieldViewMin = 10f; //拉伸距离最近距离
public float scrollSpeed = 40f; //拉伸速度
public float rotateSpeed = 10f; //旋转速度
private bool isRotate = false; //旋转状态标识符

跟随及主代码

使用LateUpdate控制相机,在Update处理完角色逻辑后LateUpdate处理相机逻辑,防止相机跟丢角色。

    void Start () {

        cameraObject = this.GetComponent<Camera>();
        playerObject = GameObject.FindGameObjectWithTag("Player");
        offSetPos = this.transform.position - playerObject.transform.position;
        transform.LookAt(playerObject.transform);
    }
    void LateUpdate ()
    {
        //相机跟随(使用固定偏移方法)
        this.transform.position = offSetPos + playerObject.transform.position;
        //视野拉伸(使用Camera.fieldOfView方法)
        ScrollOfView(cameraObject,fieldViewMin, fieldViewMax, scrollSpeed);
        //视野旋转(使用Transform.RotateAround方法)
        RotateOfView(cameraObject.transform, playerObject.transform,ref offSetPos,ref isRotate,rotateSpeed);
    }

相机视野拉伸代码

滚轮控制相机视野拉伸(挂载相机上)
_camera     ---->相机
_fieldViewMin  ---->最近视野
_fieldViewMax  ---->最大视野
_scrollSpeed   ---->拉伸速度(默认40)
    void ScrollOfView(Camera _camera, float _fieldViewMin, float _fieldViewMax,float _scrollSpeed=40)
    {
        _camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel") * _scrollSpeed;
        _camera.fieldOfView = Mathf.Clamp(_camera.fieldOfView, _fieldViewMin, _fieldViewMax);
    }

相机视野旋转代码

右键拖动旋转视野(挂载相机上)
_cameraTransform ---->相机的transform
_targetTransform ---->目标的transform
_offSetPos    ---->相机与目标的偏移位置(可传递)
_isRotate     ---->旋转状态标识符(可专递)
_rotateSpeed   ---->旋转速度(默认为10)
    void RotateOfView(Transform _cameraTransform, Transform _targetTransform,ref Vector3 _offSetPos,ref bool _isRotate,float _rotateSpeed=10)
    {
        //当鼠标右键按下切换旋转状态,抬起表示结束旋转状态
        if (Input.GetMouseButtonDown(1))
            _isRotate = true;
        if (Input.GetMouseButtonUp(1))
            _isRotate = false;
        //旋转状态
        if (_isRotate)
        {
            Vector3 originalPosition = _cameraTransform.position;
            Quaternion originalRotation = _cameraTransform.rotation;
            _cameraTransform.RotateAround(_targetTransform.position, _targetTransform.up, _rotateSpeed * Input.GetAxis("Mouse X"));
            _cameraTransform.RotateAround(_targetTransform.position, _cameraTransform.right, -_rotateSpeed * Input.GetAxis("Mouse Y"));
            //限制上下旋转角度
            if (_cameraTransform.eulerAngles.x > 80 || _cameraTransform.eulerAngles.x < 10)
            {
                _cameraTransform.position = originalPosition;
                _cameraTransform.rotation = originalRotation;
            }
            //更新偏移
            _offSetPos = _cameraTransform.position - _targetTransform.position;
        }
    }

函数写的相对直观,就不多做笔记表明了,欢迎大神有更好的方法请指教。

最后附上PlayerFollow.cs源码

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4
 5 public class FollowPlayer : MonoBehaviour {
 6
 7
 8     private GameObject playerObject;
 9     private Camera cameraObject;
10     private Vector3 offSetPos;          //偏移(相机与目标的差)
11     public float fieldViewMax = 90f;    //拉伸距离最远距离
12     public float fieldViewMin = 10f;    //拉伸距离最近距离
13     public float scrollSpeed = 40f;     //拉伸速度
14     public float rotateSpeed = 10f;     //旋转速度
15     private bool isRotate = false;      //旋转状态标识符
16
17
18     void Start () {
19
20         cameraObject = this.GetComponent<Camera>();
21         playerObject = GameObject.FindGameObjectWithTag("Player");
22         offSetPos = this.transform.position - playerObject.transform.position;
23         transform.LookAt(playerObject.transform);
24     }
25
26
27     void LateUpdate ()
28     {
29         //相机跟随(使用固定偏移方法)
30         this.transform.position = offSetPos + playerObject.transform.position;
31         //视野拉伸(使用Camera.fieldOfView方法)
32         ScrollOfView(cameraObject,fieldViewMin, fieldViewMax, scrollSpeed);
33         //视野旋转(使用Transform.RotateAround方法)
34         RotateOfView(cameraObject.transform, playerObject.transform,ref offSetPos,ref isRotate,rotateSpeed);
35     }
36
37
38
39
40
41     /// <summary>
42     /// 滚轮控制相机视野拉伸(挂载相机上)
43     /// </summary>
44     /// <param name="_camera">相机</param>
45     /// <param name="_fieldViewMin">最近视野</param>
46     /// <param name="_fieldViewMax">最大视野</param>
47     /// <param name="_scrollSpeed">拉伸速度(默认40)</param>
48     void ScrollOfView(Camera _camera, float _fieldViewMin, float _fieldViewMax,float _scrollSpeed=40)
49     {
50         _camera.fieldOfView -= Input.GetAxis("Mouse ScrollWheel") * _scrollSpeed;
51         _camera.fieldOfView = Mathf.Clamp(_camera.fieldOfView, _fieldViewMin, _fieldViewMax);
52     }
53
54
55
56
57     /// <summary>
58     /// 右键拖动旋转视野(挂载相机上)
59     /// </summary>
60     /// <param name="_cameraTransform">相机的transform</param>
61     /// <param name="_targetTransform">目标的transform</param>
62     /// <param name="_offSetPos">相机与目标的偏移位置(可传递)</param>
63     /// <param name="_isRotate">旋转状态标识符(可专递)</param>
64     /// <param name="_rotateSpeed">旋转速度(默认为10)</param>
65     void RotateOfView(Transform _cameraTransform, Transform _targetTransform,ref Vector3 _offSetPos,ref bool _isRotate,float _rotateSpeed=10)
66     {
67         //当鼠标右键按下切换旋转状态,抬起表示结束旋转状态
68         if (Input.GetMouseButtonDown(1))
69             _isRotate = true;
70         if (Input.GetMouseButtonUp(1))
71             _isRotate = false;
72         //旋转状态
73         if (_isRotate)
74         {
75             Vector3 originalPosition = _cameraTransform.position;
76             Quaternion originalRotation = _cameraTransform.rotation;
77             _cameraTransform.RotateAround(_targetTransform.position, _targetTransform.up, _rotateSpeed * Input.GetAxis("Mouse X"));
78             _cameraTransform.RotateAround(_targetTransform.position, _cameraTransform.right, -_rotateSpeed * Input.GetAxis("Mouse Y"));
79             //限制上下旋转角度
80             if (_cameraTransform.eulerAngles.x > 80 || _cameraTransform.eulerAngles.x < 10)
81             {
82                 _cameraTransform.position = originalPosition;
83                 _cameraTransform.rotation = originalRotation;
84             }
85             //更新偏移
86             _offSetPos = _cameraTransform.position - _targetTransform.position;
87         }
88     }
89
90 }

PlayerFollow.cs

时间: 2024-10-10 04:46:43

Unity学习-相机的拉伸、跟随、旋转的相关文章

unity学习--003:角色控制器(中)

在上篇 unity学习--003:角色控制器(上)中,看了点角色控制的基本实现方法,鼠标和键盘控制比较粗糙的实现. 在这篇中,主要介绍几个unity封装的角色控制方法, 然后预计在下篇中综合介绍几种主流的角色控制方法. 话不多说,开搞: 依旧是上次拖过来的几个模型 不过,这次添加了地形,素材,和天空盒,自然光,至于怎么加的,请看这里 添加地形等 不在黑黑的,心情也好点了,下面来介绍几种unity自带的角色控制操作.(这些方法都是unity自带的API) 1.CharacterController

【程序员编程艺术】学习记录1:左旋转字符串之指针翻转法

[程序员编程艺术]学习记录1:左旋转字符串之指针翻转法 题目:左旋转字符串 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部,如把字符串abcdef左旋转2位得到字符串cdefab.请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(n) 思路一.暴力移位法 //暴力移位法 void leftshiftone(char *s, int n) { char t = s[0]; for(int i = 1;i < n; i++) s[i-1]

Unity学习疑问记录之正交与透视

Unity中相机的投影是2种方式,正交和透视 这是透视方式 正交方式: //计算屏幕宽度 float height = 2.0f * Camera.main.orthographicSize;//正交的size screenWidthInPoints = height * Camera.main.aspect; //长宽比 orthographicSize指的是屏幕中心到顶部的距离,所以*2,印射到真实宽度就是*实际手机比例就行了.

【程序员编程艺术】学习记录2:左旋转字符串之循环移位法

[程序员编程艺术]学习记录2:左旋转字符串之循环移位法 GCD算法:(辗转相除法/欧几里得算法) gcd是求最大公约数的算法,作为TAOCP第一个算法 gcd算法流程: 首先给定两个整数m,n(m大于等于n)如果小于则直接交换再处理 ①求余数 r=m%n ②假如r=0,算法结束,n即为所求 否则,重新令m <- n, n <-r 之后循环 <<<<<<<<<<<<<<<<<<<&l

unity学习之总结比较

1.for与while循环 while 循环用于循环次数不是确定的情况for 循环用于循环次数确定的情况下使用 for: for ( int i = 0; i < 100; i++) { Debug.Log("第:"+(i+1)+"次输出!"); } while: int i=0; while(i<100){Debug.Log("第:"+(i+1)+"次输出!"); i++;} http://wanjushu.bl

Unity3d学习 相机的跟随

最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码:  简单相机移动 可以很容易的理解上述的代码: 在初始化时计算与对应物体的向量差值,然后在LateUpdate中对相机位置进行及时更新,至于为什么要放在LateUpdate,因为LateUpdate是等所有脚本的Update跑完之后 在更新自己的逻辑,这样相机得到物体的位置往往是最新的 .具体可以看 Unity关于脚本生

Unity 鼠标点击左右移动,人物跟随旋转

上代码: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { private Vector3 startPosition; //鼠标按钮的坐标点 private float x; public bool isDown; //表示鼠标是否按下 public void OnMouseDown() { isDown = true; startPosition = Input.mousePosi

Unity学习笔记之五为Prefab添加材质

本次笔记中,我们将利用unity来创建并使用材质,把材质添加到我们的Prefab中去. 这一系列教程以及素材均参考自人人素材翻译组出品的翻译教程<Unity游戏引擎的基础入门视频教程>,下载链接附在第二篇学习笔记中. 继续上次笔记中所记录的东西,在Project视图中,ImportedAssets-Meshes-Materials下我们可以看到一个没有纹理的材质球,这个材质是跟随我们的3d Max模型来的默认材质.因为这里我们要添加自己的材质,所以我们直接把这个材质球删除. 删除后,我们看到本

【转载】Unity中矩阵的平移、旋转、缩放

By:克森 简介 在这篇文章中,我们将会学到几个概念:平移矩阵.旋转矩阵.缩放矩阵.在学这几个基本概念的同时,我们会用到 Mesh(网格).数学运算.4x4矩阵的一些简单的操作.但由于克森也是新手,文章的严谨性可能不是很高,还请大神们多多指教. 创建项目 首先创建一个Unity工程,克森把他命名为“Matrix of China”(中国的矩阵),基本配置如下图所示: 为了便于查找,让我们在 Assets 目录下新建三个文件夹,分别命名为“Scripts”.“Shader”.“Materials”