Unity3d中第三人称摄像机跟随的实现

整理了一下网络上一些关于unity中视角跟随的一些方法

通过同步摄像机的位置使其跟随Player的position变化

    void Rot_moves()
    {
        float y = Input.GetAxis("Mouse X");
        float x = Input.GetAxis("Mouse Y");
        camAms.x -= x;
        camAms.y += y;
        camTrans.eulerAngles = camAms;
        //float Camx = this.transform.position.x + 2.0f;
        camTrans.position = new Vector3(this.transform.position.x , camTrans.position.y, this.transform.position.z );
        float camy = camAms.y;
        this.transform.eulerAngles = new Vector3(this.transform.eulerAngles.x, camy, this.transform.eulerAngles.z);
        Vector3 stratpro = transform.position;
        stratpro.y += camnHight;
        camTrans.position = stratpro;
    }

但这种方法非常诡异,视角移动的非常不自然,而且视角相对固定,无法避免障碍物阻挡视角。

(但万一用上了呢?)

由物体的位置,跟相对距离,就可以求出摄像机的位置,用插值的方法可以让摄像机平滑跟随。

public class CamFollow1 : MonoBehaviour
{

    private Vector3 offset;
    public Transform player;

    void Start()
    {
        offset = player.position - transform.position;
    }

    void Update()
    {
        transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5);
        Quaternion rotation = Quaternion.LookRotation(player.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation,Time.deltaTime*3f);
    }
}

其中的rotation的设置可以造成一些注视的效果,

这个方法虽然还是无法避免障碍物阻挡视线,但视角的变化已经非常平滑,个人感觉对付部分情景已经可以了。

 

但是!在我这个诡异的项目是不能满足的!

 

在平滑跟随的基础上避免障碍物阻挡视角

摄像机就无法看到人物,玩家自然也看不到,
在上面的基础上做更近一步的扩展
在人物头顶往下看,肯定可以看得到人物,
所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。
但是为什么我的写出来是痴汉视角。。。。
先放上教程源代码吧
我好对比着魔改……
using UnityEngine;
using System.Collections;

public class CamFollow3 : MonoBehaviour
{

    
    private Transform player;//英雄位置
    private Vector3 offset; //摄像机和英雄相对位置
    private float distance;//距离
    private Vector3[] points = new Vector3[5];//5个点作为摄像机位置的选择
    
    private Vector3 targetPos;//筛选后的摄像机位置

    void Awake()
    {
        player = GameObject.FindWithTag("Player").transform;
        offset = transform.position - player.position;
        distance = offset.magnitude;
    }

    void FixedUpdate()
    {
        //更新5个点的位置
        points[0] = player.position + offset;
        points[4] = player.position + Vector3.up*distance;

        points[1] = Vector3.Lerp(points[0], points[4], 0.25f);
        points[2] = Vector3.Lerp(points[0], points[4], 0.5f);
        points[3] = Vector3.Lerp(points[0], points[4], 0.75f);
        points[4] = Vector3.Lerp(points[0], points[4], 0.9f);

       targetPos = FindCameraTarget();
        
        AdjustCamera();
    }

    private Vector3 FindCameraTarget()
    {
        Vector3 result = points[points.Length - 1];//头顶位置

        //从低到高遍历
        for (int i = 0; i < points.Length; ++i)
        {
            if (IsHitPlayer(points[i], player.position))
            {
                result = points[i];
                break;
            }
        }

        return result;
    }

    private Ray ray;
    private RaycastHit hit;
    /// <summary>
    /// 从origin发射一条射线检测是否碰到player,
    /// 碰到则表示摄像机在此位置可以看到player
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    bool IsHitPlayer(Vector3 origin, Vector3 target)
    {
        bool result = false;

        Vector3 dir = target - origin;
        ray = new Ray(origin,dir);
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.transform.tag == "Player")
            {
                result = true;
            }
        }
        return result;
    }

    /// <summary>
    /// 调整摄像机位置
    /// </summary>
    void AdjustCamera()
    {

        transform.position = Vector3.Slerp(transform.position, targetPos, Time.deltaTime * 6);
       
        Quaternion rotation = Quaternion.LookRotation(player.position - transform.position);
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 33f);
    
    }
}

2019-12-19 16:39:03

整理:菰冭

posted @ 2019-12-19 16:40  菰冭  阅读(502)  评论(1编辑  收藏  举报