赞
踩
游戏开发中,不可避免地会涉及摄像机的跟随和控制,摄像机的位置以及角度朝向都需要在不断的调试中,以确认出对玩家比较友好的方案。本篇中将讨论几种在Unity3D中摄像机跟随的方案。
如字面意思,将摄像机作为需要跟随的目标的子物体,在操纵目标进行移动旋转时,摄像机也会跟随父物体进行移动旋转。
优点:简单直观,不需要写代码。
不足:由于是跟随父物体一起运动,会随着父物体的旋转而旋转,当父物体的旋转不当时,摄像机的角度无法进行调整。
这里有几个参数需要介绍一下
水平偏移角度:摄像机在x轴和z轴平面中,与目标位置形成的角度
垂直偏移角度:摄像机在x轴和y轴平面中,与目标位置形成的角度
距离:摄像机与目标之间的距离
现在我们分别从水平平面和垂直平面中求得摄像机的x、y、z坐标。
height = distance * Mathf.Sin(roll)
temp= distance * Mathf.Cos(roll)
在垂直平面中,我们求得摄像机距目标的相对高度,即摄像机的y坐标,和求x、z坐标的一个中间值
cameraPos.x = targetPos.x + temp * Mathf.Cos(rot);
cameraPos.z = targetPos.z + temp * Mathf.Sin(rot);
通过中间值temp,我们便可以求得摄像机的x、z坐标
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class CameraFollow : MonoBehaviour {
- //距离
- public float distance = 8;
- //横向角度
- public float rot = 0;
- //纵向角度
- private float roll = 30f * Mathf.PI * 2 / 360;
- //目标物体
- private GameObject target;
- //横向旋转速度
- public float rotSpeed = 0.2f;
- //纵向角度范围
- private float maxRoll = 70f * Mathf.PI * 2 / 360;
- private float minRoll = -10f * Mathf.PI * 2 / 360;
- //纵向旋转速度
- private float rollSpeed = 0.2f;
- //距离范围
- public float maxDistance = 22f;
- public float minDistance = 5f;
- //距离变化速度
- public float zoomSpeed = 0.2f;
-
- void Start() {
- //找到坦克
- //SetTarget(GameObject.Find("tank"));
- }
-
- 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);
- //横向旋转
- Rotate();
- //纵向旋转
- Roll();
- //调整距离
- Zoom();
- }
-
- //设置目标
- public void SetTarget(GameObject target) {
- if (target.transform.Find("cameraPoint") != null)
- this.target = target.transform.Find("cameraPoint").gameObject;
- else
- this.target = target;
- }
-
- //横向旋转
- void Rotate() {
- float w = Input.GetAxis("Mouse X") * rotSpeed;
- rot -= w;
- }
-
- //纵向旋转
- void Roll() {
- float w = Input.GetAxis("Mouse Y") * rollSpeed * 0.5f;
-
- roll -= w;
- if (roll > maxRoll)
- roll = maxRoll;
- if (roll < minRoll)
- roll = minRoll;
- }
-
- //调整距离
- void Zoom() {
- if (Input.GetAxis("Mouse ScrollWheel") > 0) {
- if (distance > minDistance)
- distance -= zoomSpeed;
- } else if (Input.GetAxis("Mouse ScrollWheel") < 0) {
- if (distance < maxDistance)
- distance += zoomSpeed;
- }
- }
- }
优点:比较严谨摄像机跟随方案,可进行进一步的摄像机控制,例如视角的操控
缺点:实现过程稍麻烦,需要理解摄像机与跟随目标的三角函数关系
Vector3 TargetPos = new Vector3(0, 3f, -3f);
transform.position = Vector3.Lerp(transform.position, playerTransform.position + TargetPos, speed * Time.deltaTime);
使用Lerp函数是为了摄像机移动的更平滑些。
Quaternion TargetRotation = Quaternion.LookRotation(playerTransform.position - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, speed * Time.deltaTime);
使用Slerp函数与使用Lerp函数同理
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class FollowPlayer : MonoBehaviour
- {
- public float speed = 2f;
-
- private Transform playerTransform;
-
- void Start ()
- {
- playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
- }
-
-
- void Update ()
- {
- if (playerTransform == null)
- return;
- Vector3 TargetPos = new Vector3(0, 3f, -3f);
- transform.position = Vector3.Lerp(transform.position, playerTransform.position + TargetPos, speed * Time.deltaTime);
-
- Quaternion TargetRotation = Quaternion.LookRotation(playerTransform.position - transform.position);
- transform.rotation = Quaternion.Slerp(transform.rotation, TargetRotation, speed * Time.deltaTime);
-
- }
- }
优点:代码实现简单,可以做出不错的摄像机跟随效果。
不足:不便于进行视角的操控
由于博主能力有限,在学习过程中,总结了这三种摄像机跟随的实现方案,实现是比较简单的,而且能满足基本的需求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。