当前位置:   article > 正文

UNITY自用笔记-摄像机几种跟随方式_摄像机怎么跟随人物

摄像机怎么跟随人物

1.第一种方法

摄像机视角锁死方法,具体做法就是事先调试好视角,然后聚焦,然后用代码事先固定视角,其代码如下:

//  挂载对象:主相机
// 功能:相机跟随人物
/ 注意:相机只能跟随人物移动,但是如果人物转向或者做某些动作,摄像机并不跟随

using UnityEngine;
using System.Collections;
public class CameraShareScript : MonoBehaviour
{
        //摄像机于要跟随物体的距离
         Vector3 Dir;
//要跟随的物体
public  GameObject m_Player;
// Use this for initialization
void Start ()
       {
//获取到摄像机于要跟随物体之间的距离
Dir = m_Player.transform.position - transform.position;
}

// Update is called once per frame
void LateUpdate ()
{
//摄像机的位置
transform.position = m_Player.transform.position - Dir;
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2.第二种方法:

这种方法是上种方法的优化,可以实现跟随人物移动,跟随人物旋转等基本功能,但是缺点是如果添加刚体组件,摄像机无法穿墙跟随人物,其代码如下:

//  挂载对象:主相机
// 功能:把要跟随的人物Tag修改为Player
// 注意:
using UnityEngine;
using System.Collections;


public class CameraFindPlayerScript : MonoBehaviour
{
//相机距离人物高度
float m_Height = 5f;
//相机距离人物距离
float m_Distance = 5f;
//相机跟随速度
float m_Speed = 4f;
//目标位置
Vector3 m_TargetPosition;
//要跟随的人物
Transform follow;
// Use this for initialization
void Start ()
{
// 通过Tag得到这个要跟随的人物
follow = GameObject.FindWithTag ("Player").transform;
}

// Update is called once per frame
//相机平滑的跟随人物移动
void LateUpdate ()
{
//得到这个目标位置
m_TargetPosition = follow.position + Vector3.up * m_Height - follow.forward * m_Distance;
//相机位置
transform.position = Vector3.Lerp (transform.position, m_TargetPosition, m_Speed * Time.deltaTime);
//相机时刻看着人物
transform.LookAt (follow);


}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

3.第三种方法

第三种方法:射线检测,保证不论主角在哪摄像机永远可以看到主角,并且把摄像机的y轴和z轴锁死,使玩家视野不晕

using UnityEngine;
using System.Collections;
/// <summary>
/// Camera move.
/// 挂载对象:摄像机
/// 作用:摄像机跟随人物
/// </summary>
public class CameraMove : MonoBehaviour
{
//摄像机的移动速度
public float moveSpeed = 3f;
//摄像机的旋转速度
public  float turnSpeed = 10f;
//定义私有玩家
private Transform m_Player;
//摄像机与玩家之间的初始偏移量
private Vector3 offset;
//射线的碰撞信息
private RaycastHit hit;
//摄像机与玩家之间的距离
private float distance;
//摄像机的观察点
private Vector3[] currentPoints;
//通过Awake拿到自身的组件
void Awake ()
{
//通过tag找到人物组件
m_Player = GameObject.FindWithTag (TagsScript.Player).transform;
//定义一个v3类型的数组,里面有5个元素
currentPoints = new Vector3[5];
}
//初始化游戏对象
void Start ()
{
//游戏开始时摄像机与玩家之间的距离
distance = Vector3.Distance (transform.position, m_Player.position);
//摄像机指向玩家
//玩家与摄像机之间的偏移量
offset = m_Player.position - transform.position;
}


//物理引擎相关的放到FixedUpdate中
//LateUpdate可以避免卡顿
void LateUpdate ()
{
//摄像机观察的第一个点
Vector3 startPosition = m_Player.position - offset;
//摄像机的最后一个点
Vector3 endPosition = m_Player.position + Vector3.up * distance;
//把摄像机的五个观察点放到数组中,并且1,2,3三个观察点使用线性插值让摄像机平滑移动Slerp
currentPoints [1] = Vector3.Slerp (startPosition, endPosition, 0.25f);
currentPoints [2] = Vector3.Slerp (startPosition, endPosition, 0.5f);
currentPoints [3] = Vector3.Slerp (startPosition, endPosition, 0.75f);
currentPoints [0] = startPosition;
currentPoints [4] = endPosition;
//定义一个变量用来存储固定帧可以看到玩家的观察点
//viewposition = currentPoints [0]
Vector3 viewposition = currentPoints [0];
//for循环遍历这些点,如果找到最合适的点就把那个当前点赋值给可以看到玩家的观察点CheckView检测某个点能否看到玩家
for (int i = 0; i < currentPoints.Length; i++) {
//如果检测到某个点可以看到玩家
if (CheckView (currentPoints [i])) {
//把这个当前点赋值给viewposition
viewposition = currentPoints [i];
//之后返回不在继续遍历
break;
}
}
//把摄像机移动到观察点
transform.position = Vector3.Lerp (transform.position, viewposition, Time.deltaTime * moveSpeed);
//调用摄像机旋转方法
SmoothRotate ();
}
/// <summary>
/// Checks the view.
/// 检测某个点是否可以看到玩家
/// </summary>
/// <returns><c>true</c>, if view was checked, <c>false</c> otherwise.</returns>
/// <param name="pos">Position.</param>
//检测某个点能否看到玩家的方法bool类型
bool CheckView (Vector3 pos)
{
//定义玩家与观察点之间的方向向量
Vector3 dir = m_Player.position - pos;
//发射射线
if (Physics.Raycast (pos, dir, out hit)) {
//如果射线打到玩家
if (hit.collider.tag == TagsScript.Player) {
//返回true
return true;
}
}
//不然返回false
return false;
}
/// <summary>
/// Smooths the rotate.
/// 摄像机旋转的方法
/// </summary>
/// 摄像机旋转的方法
void SmoothRotate ()
{
//指向起始位置
//摄像机到玩家的向量
Vector3 m_Dir = m_Player.position - transform.position;
//要旋转的角度
Quaternion qua = Quaternion.LookRotation (m_Dir);
transform.rotation = Quaternion.Lerp (transform.rotation, qua, Time.deltaTime * turnSpeed);
//把摄像机x,y轴锁死
transform.eulerAngles = new Vector3 (transform.eulerAngles.x, 0, 0);

}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

4.第四种方法

固定摄像机方法,常用于RPG游戏

UnityEngine;
using System.Collections;
 
/// <summary>
/// Third person camera.
/// </summary>
public class TheThirdPersonCamera : MonoBehaviour
{
	public float distanceAway=1.7f;			
	public float distanceUp=1.3f;			
	public float smooth=2f;				// how smooth the camera movement is
		
	private Vector3 m_TargetPosition;		// the position the camera is trying to be in)
	
	Transform follow;        //the position of Player
	
	void Start(){
		follow = GameObject.FindWithTag ("Player").transform;	
	}
	
	void LateUpdate ()
	{
		// setting the target position to be the correct offset from the 
		m_TargetPosition = follow.position + Vector3.up * distanceUp - follow.forward * distanceAway;
		
		// making a smooth transition between it's current position and the position it wants to be in
		transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth);
		
		// make sure the camera is looking the right way!
		transform.LookAt(follow);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

5.第五种方法

摄像机替代主角方法,常用于第一人称射击
直接用摄像机替代主角视角,摄像机看到的便是玩家在游戏场景中看到的。首先在Hierachy视图中建立空物体作为Player,使其旋转方向与摄像机保持一致。

		// 摄像机Transform
		Transform m_camTransform;
     
        // 摄像机旋转角度
        Vector3 m_camRot;
     
        // 摄像机高度(即表示主角的身高)
        float m_camHeight = 1.4f;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
     void Start () {
     
            m_transform = this.transform;
            
             
            // 获取摄像机
            m_camTransform = Camera.main.transform;
     
            // 设置摄像机初始位置
            m_camTransform.position = m_transform.TransformPoint(0, m_camHeight, 0);    //摄像机初始位置从本地坐标转化成世界坐标,且在X-Z平面的初始位置
     
            // 设置摄像机的旋转方向与主角一致
            //rotation为物体在世界坐标中的旋转角度,用Quaternion赋值
            m_camTransform.rotation = m_transform.rotation;  
            //Quaternion赋值
            //在本游戏实例中用欧拉角表示旋转
            m_camRot = m_camTransform.eulerAngles;    
            }

			

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
void Control()
    {
 
        //获取鼠标移动距离
        float rh = Input.GetAxis("Mouse X");
        float rv = Input.GetAxis("Mouse Y");
 
        // 旋转摄像机
        m_camRot.x -= rv;
        m_camRot.y += rh;
        m_camTransform.eulerAngles = m_camRot;   //通过改变XYZ轴的旋转改变欧拉角
 
        // 使主角的面向方向与摄像机一致
        Vector3 camrot = m_camTransform.eulerAngles;
        camrot.x = 0; camrot.z = 0;
        m_transform.eulerAngles = camrot;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

6.第六种方法 对准目标

 public float distance = 8;
    //横向角度
    public float rot = 0;    //用弧度表示
    //纵向角度
    private float roll = 30f * Mathf.PI * 2 / 360;    //弧度
    //目标物体
    private GameObject target;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
 void Start()
    {
        //找到坦克
        target = GameObject.Find("Tank");
        
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
void LateUpdate() 
    {
        //一些判断
        if (target == null)
            return;
        if (Camera.main == null)
            return;
        //目标的坐标
        Vector3 targetPos = target.transform.position;
        //用三角函数计算相机位置
        Vector3 cameraPos;
        float d = distance *Mathf.Cos (roll);
        float height = distance * Mathf.Sin(roll);
        cameraPos.x = targetPos.x +d * Mathf.Cos(rot);
        cameraPos.z = targetPos.z + d * Mathf.Sin(rot);
        cameraPos.y = targetPos.y + height;
        Camera.main.transform.position = cameraPos;
        //对准目标
        Camera.main.transform.LookAt(target.transform);
     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/122990
推荐阅读
相关标签
  

闽ICP备14008679号