您的位置:首页 > 职场人生

总结一下今天做的面试题(三):第三人称相机控制

2020-03-06 18:18 821 查看

同样是先看需求:

整个地方最难的在于,相机被挤压时要怎么处理。

由于没玩过上面两款游戏,也不知道是怎么处理的,我自己的想法是让相机直接旋转180度。

首先贴一下人物控制脚本,别忘了给人物加上Charactor Controll组件

using UnityEngine;
using System.Collections;

public class move_controll : MonoBehaviour {
Transform m_transform,m_camera;
CharacterController controller;
float MoveSpeed = 1.0f;
string[] clipName={"idle","shamble"};
Animation m_animation;
// Use this for initialization
void Start () {
m_transform = this.transform;
m_camera = GameObject.FindGameObjectWithTag ("MainCamera").transform;
controller=GetComponent<CharacterController>();
m_animation = m_transform.GetComponent<Animation> ();
}

// Update is called once per frame
void Update () {
if ((Input.GetKey (KeyCode.W)) || (Input.GetKey (KeyCode.S)) || (Input.GetKey (KeyCode.A)) || (Input.GetKey (KeyCode.D))) {
m_animation.Play (clipName[1]);
if (Input.GetKey (KeyCode.W)) {
controller.transform.eulerAngles = new Vector3 (0, m_camera.transform.eulerAngles.y, 0);//the eulerAngles depend on camera's eulerAngles
}

if (Input.GetKey (KeyCode.S)) {
controller.transform.eulerAngles = new Vector3 (0, m_camera.transform.eulerAngles.y+180f, 0);
}

if (Input.GetKey (KeyCode.A)) {
controller.transform.eulerAngles = new Vector3 (0, m_camera.transform.eulerAngles.y+270f, 0);
}

if (Input.GetKey (KeyCode.D)) {
controller.transform.eulerAngles = new Vector3 (0, m_camera.transform.eulerAngles.y+90f, 0);
}

controller.Move(m_transform.forward * Time.deltaTime * MoveSpeed);
}
else
//idle
m_animation.Play (clipName[0]);
//gravity
if (!controller.isGrounded) {
controller.Move(new Vector3(0,-10f*Time.deltaTime,0));
}
}
}

随后是相机控制,这里提供两个版本,一个是用滚轮控制镜头远近的(我从别的地方抄的):

// ====================================================================================================================
// Simple rotation and tilt of camera around a pivot object
// Created by Leslie Young
// http://www.plyoung.com/ or http://plyoung.wordpress.com/
// ====================================================================================================================

using UnityEngine;

public class CameraOrbit : MonoBehaviour
{
public Transform pivot;                            // the object being followed
public Vector3 pivotOffset = Vector3.zero;        // offset from target's pivot
public Transform target;                        // like a selected object (used with checking if objects between cam and target)

public float distance = 10.0f; // distance from target (used with zoom)
public float minDistance = 2f;
public float maxDistance = 15f;
public float zoomSpeed = 1f;

public float xSpeed = 250.0f;
public float ySpeed = 120.0f;

public bool allowYTilt = true;
public float yMinLimit = 30f;
public float yMaxLimit = 80f;

private float x = 0.0f;
private float y = 0.0f;

private float targetX = 0f;
private float targetY = 0f;
private float targetDistance = 0f;
private float xVelocity = 1f;
private float yVelocity = 1f;
private float zoomVelocity = 1f;

void Start()
{
var angles = transform.eulerAngles;
targetX = x = angles.x;
targetY = y = ClampAngle(angles.y, yMinLimit, yMaxLimit);
targetDistance = distance;
}

void LateUpdate()
{
if (pivot)
{
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// scroll wheel used to zoom in/out
float scroll = Input.GetAxis("Mouse ScrollWheel");

if (scroll > 0.0f) targetDistance -= zoomSpeed;
else if (scroll < 0.0f) targetDistance += zoomSpeed;
targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// right mouse button must be held down to tilt/rotate cam
// or player can use the left mouse button while holding Ctr
if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) ))
{
targetX += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
if (allowYTilt)
{
targetY -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
targetY = ClampAngle(targetY, yMinLimit, yMaxLimit);
}
}
x = Mathf.SmoothDampAngle(x, targetX, ref xVelocity, 0.3f);
if (allowYTilt) y = Mathf.SmoothDampAngle(y, targetY, ref yVelocity, 0.3f);
else y = targetY;
Quaternion rotation = Quaternion.Euler(y, x, 0);
distance = Mathf.SmoothDamp(distance, targetDistance, ref zoomVelocity, 0.5f);

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// apply
Vector3 position = rotation * new Vector3(0.0f, 0.0f, -distance) + pivot.position + pivotOffset;
transform.rotation = rotation;
transform.position = position;

}
}

private float ClampAngle(float angle, float min, float max)
{
if (angle < -360) angle += 360;
if (angle > 360) angle -= 360;
return Mathf.Clamp(angle, min, max);
}

// ====================================================================================================================
}
CameraOrbit

然后我以这个脚本为基础来该,首先是人物被遮挡时,相机要拉近:

采用射线的方式进行检测:

RaycastHit hit;//ues a ray to make camera not be blocked
if (Physics.Linecast (position, pivot.position,out hit)) {
string name = hit.collider.gameObject.tag;
if (name =="Untagged") {
targetDistance=(hit.point-pivot.position).magnitude;//if the hit object's tag is Untagged,change the distance
}
}

然后是相机被挤压导致距离极低时的旋转:

if (distance > distanceLimit) {
position = rotation * new Vector3 (0.0f, 0.0f, -distance) + pivot.position + pivotOffset;
} else {
rotation = Quaternion.Euler(y, x+180f, 0);
position = rotation * new Vector3 (0.0f, 0.0f, -m_distance) + pivot.position + pivotOffset;
targetX = targetX + 180;
x = x + 180;
}

整个脚本:

using UnityEngine;
using System.Collections;

public class Camera_Controll : MonoBehaviour {
public Transform pivot;
public Vector3 pivotOffset = Vector3.zero;
public float distance = 10.0f; // distance from target (used with zoom)
public float distanceLimit=3f;//distance when camera change Angles for 180
public float zoomSpeed = 1f;
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;

public bool allowYTilt = true;
public float yMinLimit = -60f;
public float yMaxLimit = 60f;

private float x = 0.0f;
private float y = 0.0f;
private float targetX = 0f;
private float targetY = 0f;
private float targetDistance = 0f;
private float xVelocity = 1f;
private float yVelocity = 1f;
private float zoomVelocity = 1f;
private float m_distance;
// Use this for initialization
void Start () {

var angles = transform.eulerAngles;
targetX = x = angles.x;
targetY = y = ClampAngle(angles.y, yMinLimit, yMaxLimit);
targetDistance = distance;
m_distance = distance;
}

// Update is called once per frame
void LateUpdate () {
if (pivot)
{
targetDistance = m_distance;

if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) ))
{
targetX += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
if (allowYTilt)
{
targetY -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
targetY = ClampAngle(targetY, yMinLimit, yMaxLimit);
}
}
x = Mathf.SmoothDampAngle(x, targetX, ref xVelocity, 0.3f);
if (allowYTilt) y = Mathf.SmoothDampAngle(y, targetY, ref yVelocity, 0.3f);
else y = targetY;
Quaternion rotation = Quaternion.Euler(y, x, 0);
Vector3 position = rotation * new Vector3(0.0f, 0.0f, -m_distance) + pivot.position;//calculate the true camera positon
RaycastHit hit;//ues a ray to make camera not be blocked
if (Physics.Linecast (position, pivot.position,out hit)) {
string name = hit.collider.gameObject.tag;
if (name =="Untagged") {
targetDistance=(hit.point-pivot.position).magnitude;//if the hit object's tag is Untagged,change the distance
}
}
distance = Mathf.SmoothDamp(distance, targetDistance, ref zoomVelocity, 0.5f);
if (distance > distanceLimit) {
position = rotation * new Vector3 (0.0f, 0.0f, -distance) + pivot.position + pivotOffset;
} else {
rotation = Quaternion.Euler(y, x+180f, 0);
position = rotation * new Vector3 (0.0f, 0.0f, -m_distance) + pivot.position + pivotOffset;
targetX = targetX + 180;
x = x + 180;
}
transform.rotation = rotation;
transform.position = position;
}
}
private float ClampAngle(float angle, float min, float max)
{
if (angle < -360) angle += 360;
if (angle > 360) angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}
Camera_Controll.cs

 

转载于:https://www.cnblogs.com/Swallowtail/p/6183161.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
aiwanliao4788 发布了0 篇原创文章 · 获赞 0 · 访问量 68 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: