相机第三人称视角跟随

最简单的一种就是先设置好摄像机跟物体的相对距离,
在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置,用差值的方法可以让摄像机平滑跟随。

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);
    }
}

实现一种注视的效果,可以对rotation做下处理

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);
    }

这样子,人物在走动的时候,摄像机就是一边注视着人物,一边跟着移动
但是,当有墙体,或其他高大的物体遮挡住人物,

摄像机就无法看到人物,玩家自然也看不到,
在上面的基础上做更近一步的扩展
在人物头顶往下看,肯定可以看得到人物,
所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。

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);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值