zoukankan      html  css  js  c++  java
  • Unity3d中第三人称摄像机跟随的实现

      最简单的一种就是先设置好摄像机跟物体的相对距离,
    在脚本里就可以由物体的位置,跟相对距离,就可以求出摄像机的位置,
    用插值的方法可以让摄像机平滑跟随。
     1 public class CamFollow1 : MonoBehaviour
     2 {
     3 
     4     private Vector3 offset;
     5     public Transform player;
     6 
     7     void Start()
     8     {
     9         offset = player.position - transform.position;
    10     }
    11 
    12     void Update()
    13     {
    14         transform.position = Vector3.Lerp(transform.position, player.position - offset,Time.deltaTime*5);
    15     }
    16 }

    实现一种注视的效果,可以对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);
        }

    这样子,人物在走动的时候,摄像机就是一边注视着人物,一边跟着移动。

     

    但是,当有墙体,或其他高大的物体遮挡住人物,

    摄像机就无法看到人物,玩家自然也看不到,
    在上面的基础上做更近一步的扩展
    在人物头顶往下看,肯定可以看得到人物,
    所以我们要做的就是把摄像机的位置向人物头顶去调整,直到可以看到人物。
     
     1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class CamFollow3 : MonoBehaviour
     5 {
     6 
     7     
     8     private Transform player;//英雄位置
     9     private Vector3 offset; //摄像机和英雄相对位置
    10     private float distance;//距离
    11     private Vector3[] points = new Vector3[5];//5个点作为摄像机位置的选择
    12     
    13     private Vector3 targetPos;//筛选后的摄像机位置
    14 
    15     void Awake()
    16     {
    17         player = GameObject.FindWithTag("Player").transform;
    18         offset = transform.position - player.position;
    19         distance = offset.magnitude;
    20     }
    21 
    22     void FixedUpdate()
    23     {
    24         //更新5个点的位置
    25         points[0] = player.position + offset;
    26         points[4] = player.position + Vector3.up*distance;
    27 
    28         points[1] = Vector3.Lerp(points[0], points[4], 0.25f);
    29         points[2] = Vector3.Lerp(points[0], points[4], 0.5f);
    30         points[3] = Vector3.Lerp(points[0], points[4], 0.75f);
    31         points[4] = Vector3.Lerp(points[0], points[4], 0.9f);
    32 
    33        targetPos = FindCameraTarget();
    34         
    35         AdjustCamera();
    36     }
    37 
    38     private Vector3 FindCameraTarget()
    39     {
    40         Vector3 result = points[points.Length - 1];//头顶位置
    41 
    42         //从低到高遍历
    43         for (int i = 0; i < points.Length; ++i)
    44         {
    45             if (IsHitPlayer(points[i], player.position))
    46             {
    47                 result = points[i];
    48                 break;
    49             }
    50         }
    51 
    52         return result;
    53     }
    54 
    55     private Ray ray;
    56     private RaycastHit hit;
    57     /// <summary>
    58     /// 从origin发射一条射线检测是否碰到player,
    59     /// 碰到则表示摄像机在此位置可以看到player
    60     /// </summary>
    61     /// <param name="origin"></param>
    62     /// <param name="target"></param>
    63     /// <returns></returns>
    64     bool IsHitPlayer(Vector3 origin, Vector3 target)
    65     {
    66         bool result = false;
    67 
    68         Vector3 dir = target - origin;
    69         ray = new Ray(origin,dir);
    70         if (Physics.Raycast(ray, out hit))
    71         {
    72             if (hit.transform.tag == "Player")
    73             {
    74                 result = true;
    75             }
    76         }
    77         return result;
    78     }
    79 
    80     /// <summary>
    81     /// 调整摄像机位置
    82     /// </summary>
    83     void AdjustCamera()
    84     {
    85 
    86         transform.position = Vector3.Slerp(transform.position, targetPos, Time.deltaTime * 6);
    87        
    88         Quaternion rotation = Quaternion.LookRotation(player.position - transform.position);
    89         transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 33f);
    90     
    91     }
    92 }

     

     
  • 相关阅读:
    运维安全、架构、日志管理等要安装的东西,一直在更新,欢迎大家评论
    http协议的发展史
    uni-app实现通话录音实时上传、后端php-安卓手机
    uni-app H5 plus.io 获取手机指定路径目录下所有文件
    Laravel框架部署过程中的步骤:安装 composer、切换镜像、安装laravel、创建项目
    vue 强制修改el-input样式
    ide激活码,可激活goland、phpstorm、webstorm、Pycharm
    PHP转Go函数库
    Uni-app父组件如何调用子组件的方法 | 父页面如何调用子页面的方法
    Uni-app子组件如何调用父组件的方法 | 子页面如何调用父页面的方法
  • 原文地址:https://www.cnblogs.com/dongz888/p/4909819.html
Copyright © 2011-2022 走看看