zoukankan      html  css  js  c++  java
  • 摄像机俯视跟随游戏角色的实现

     1 // CameraMovement.cs
     2 using UnityEngine;
     3 using System.Collections;
     4  
     5 public class CameraMovement : MonoBehaviour
     6 {
     7     public float smooth = 1.5f;         // 摄像机跟踪速度
     8      
     9      
    10     private Transform player;           // 引用角色位置
    11     private Vector3 relCameraPos;       // 摄像机与角色的相对位置
    12     private float relCameraPosMag;      // 摄像机到角色的距离向量长度
    13     private Vector3 newPos;             // 摄像机的新位置
    14  
    15      
    16     void Awake ()
    17     {
    18         // 引用角色位置
    19         player = GameObject.FindGameObjectWithTag(Tags.player).transform;
    20          
    21         //获取摄像机与角色的相对位置
    22         relCameraPos = transform.position - player.position; // 相对位置 = 摄像机位置 - 角色位置
    23         relCameraPosMag = relCameraPos.magnitude - 0.5f; // 相对位置向量的长度 = 相对位置的长度 - 0.5f  防止光线投射碰撞地面
    24     }
    25      
    26      
    27     void FixedUpdate ()
    28     {
    29         // 摄像机初始位置 = 角色位置 + 角色与摄像机的相对位置
    30         Vector3 standardPos = player.position + relCameraPos;
    31          
    32         // 俯视位置 = 角色位置 + 角色正上方 * 相对位置向量的长度
    33         Vector3 abovePos = player.position + Vector3.up * relCameraPosMag;
    34          
    35         // 创建长度为5的数组 储存5个摄像机位置
    36         Vector3[] checkPoints = new Vector3[5];
    37          
    38         // 第一个检测 摄像机标准位置
    39         checkPoints[0] = standardPos;
    40          
    41         // 这三个检测位置为 标准位置到俯视位置之间的三个位置 插值分别为25% 50% 75%
    42         checkPoints[1] = Vector3.Lerp(standardPos, abovePos, 0.25f);
    43         checkPoints[2] = Vector3.Lerp(standardPos, abovePos, 0.5f);
    44         checkPoints[3] = Vector3.Lerp(standardPos, abovePos, 0.75f);
    45          
    46         // 最后检测位置为 摄像机俯视位置
    47         checkPoints[4] = abovePos;
    48          
    49         // 通过循环检测每个位置是否可以看到角色
    50         for(int i = 0; i < checkPoints.Length; i++)
    51         {
    52             // 如果可以看到角色
    53             if(ViewingPosCheck(checkPoints[i]))
    54                 // 跳出循环
    55                 break;
    56         }
    57          
    58         // 让摄像机位置 从当前位置 平滑转至 新位置
    59         transform.position = Vector3.Lerp(transform.position, newPos, smooth * Time.deltaTime);
    60          
    61         // 确保摄像机朝向角色方向
    62         SmoothLookAt();
    63     }
    64      
    65      
    66     bool ViewingPosCheck (Vector3 checkPos)
    67     {
    68         RaycastHit hit;
    69          
    70         // 如果光线投射碰撞到某个对象
    71         if(Physics.Raycast(checkPos, player.position - checkPos, out hit, relCameraPosMag))
    72             // 如果光线投射碰撞点不是角色位置
    73             if(hit.transform != player)
    74                 // 当前检测位置不合适 返回false
    75                 return false;
    76          
    77         // If we haven't hit anything or we've hit the player, this is an appropriate position.如果光线投射没有碰撞到任何东西 或者碰撞点为角色位置时 更新当前检测位置为摄像机的新位置
    78         newPos = checkPos;
    79         return true;
    80     }
    81      
    82      
    83     void SmoothLookAt ()
    84     {
    85         // 创建从摄像机到角色的向量
    86         Vector3 relPlayerPosition = player.position - transform.position;
    87          
    88         // 根据摄像机到角色的向量 创建旋转角度 
    89         Quaternion lookAtRotation = Quaternion.LookRotation(relPlayerPosition, Vector3.up);
    90          
    91         // 让摄像机从 当前角度 平划转至创建的旋转角度
    92         transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, smooth * Time.deltaTime);
    93     }
    94 }

     取自unity官方教程Survival Shooter。

  • 相关阅读:
    bzoj2748:[HAOI2012]音量调节
    bzoj2287:[POJ Challenge]消失之物
    bzoj1485:[HNOI2009]有趣的数列
    Codeforces 620E New Year Tree
    CF813E Army Creation
    527D.Clique Problem
    4337: BJOI2015 树的同构
    Codeforces Round #443 (Div. 1) C. Tournament
    [BZOJ4913][SDOI2017]遗忘的集合
    [八省联考2018]林克卡特树lct
  • 原文地址:https://www.cnblogs.com/suoluo/p/5260123.html
Copyright © 2011-2022 走看看