【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)

2023-10-27

陆陆续续又开始更新自己的博客,看来自我驱动能力还是不够啊= =,废话不多说了,之前的内容大概说了一下Unity的一些基础知识,接下来我们将要对一些基本功能做一些学习。大家都知道,一个游戏,少不了摄像机的参与(这不是废话么!没摄像机怎么玩!画面都不呈现了好伐!)摄像机,总体来说分为了三大类别:上帝视角,也就是俗称的第三人称视角,以一种凌驾于游戏object的方式存在,玩家跟上帝一般俯瞰整个游戏;主角视角,第一人称视角,以主角的角度观看游戏的发展状态;观察视角,关注于某个物体的视角,这个视角在一些密室逃脱类游戏里经常有。

下面我们来学习一下简单的第三人称视角

一、第三人称跟随视角

这个视角是摄像机始终处于被观察物体(主角)的某个角度,跟随着主角的移动来调整自己的位置并始终观察着主角。

现在我们点开Window->AssetStore,搜索UnityChan,这是一个精美并且免费的模型,我们可以用它来作为demo,下载并导入场景

这里写图片描述

接下来我们就要编写摄像机的脚本了,这个脚本比较简单

using UnityEngine;
using System.Collections;

public class CameraFollow : MonoBehaviour {

    public Transform target;
    public float distanceH = 7f;
    public float distanceV = 4f;


    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    void LateUpdate()
    {
        Vector3 nextpos = Vector3.forward * -1 * distanceH + Vector3.up * distanceV + target.position;
        this.transform.position = nextpos;
        this.transform.LookAt(target);
    }
}

只要把上面的脚本付给摄像头,然后在Inspector界面把主角拖进Target里面,运行,移动主角的时候我们就能发现摄像头也在跟着主角移动了。

细心的朋友可能也发现了,就是如果转动主角的时候,摄像机还是处于一个角度观察主角,如果说我希望摄像头始终在主角的背面,那怎么办呢。我们只需要做一些小小的改动就可以了

 void LateUpdate()
    {
        Vector3 nextpos = target.forward * -1 * distanceH + target.up * distanceV + target.position;

        this.transform.position = nextpos;

        this.transform.LookAt(target);
    }

这样,大家试试转动主角,可以发现,摄像机始终都是看到主角的背面了~一个非常简单实用的跟随摄像机就出来了~

PS:下面我们说一些小技巧

  • 摄像机的更新最好在LateUpdate()里面执行,因为这个时候游戏的所有行为基本上已经处理完,在这个时候来进行摄像机的更新是最好的时候,能够把游戏最新的状态呈现出来
  • 如果想要摄像机缓慢跟随,可以加上平滑,具体代码如下:
public float smoothSpeed = 10f; //平滑参数

void LateUpdate()
    {
        Vector3 nextpos = target.forward * -1 * distanceH + target.up * distanceV + target.position;

        this.transform.position =Vector3.Lerp(this.transform.position, nextpos, smoothSpeed * Time.deltaTime); //平滑插值

        this.transform.LookAt(target);
    }

二,第三人称自由视角

这个模式,说白了就是将视角当成一个object来进行移动,就跟你在Scene界面里面的操作一样

using UnityEngine;
using System.Collections;

public class CameraMover : MonoBehaviour
{

    public float cameraMoveSpeed = 10f;
    public float cameraRotSpeed = 30f;
    bool isRotateCamera = false;

    private float trans_y = 0;
    private float trans_x = 0;
    private float trans_z = 0;

    private float eulerAngles_x;
    private float eulerAngles_y;

    // Use this for initialization
    void Start()
    {

        Vector3 eulerAngles = this.transform.eulerAngles;//当前物体的欧拉角

        this.eulerAngles_x = eulerAngles.y;

        this.eulerAngles_y = eulerAngles.x;
    }


    void FixedUpdate()
    {


        if (Input.GetMouseButton(1))
        {

            this.eulerAngles_x += (Input.GetAxis("Mouse X") * this.cameraRotSpeed) * Time.deltaTime;

            this.eulerAngles_y -= (Input.GetAxis("Mouse Y") * this.cameraRotSpeed) * Time.deltaTime;

            Quaternion quaternion = Quaternion.Euler(this.eulerAngles_y, this.eulerAngles_x, (float)0);

            this.transform.rotation = quaternion;

            moveCameraByKey(cameraMoveSpeed);
        }


        this.trans_z = (Input.GetAxis("Mouse ScrollWheel") * this.cameraMoveSpeed * 2) * Time.deltaTime;
        this.transform.Translate(Vector3.forward * this.trans_z);

        //if (Input.GetMouseButton(2))
        //{
        //    this.trans_y = (Input.GetAxis("Mouse Y") * this.ySpeed / 2) * 0.02f;
        //    this.trans_x = (Input.GetAxis("Mouse X") * this.xSpeed / 2) * 0.02f;

        //    this.transform.Translate(-1 *Vector3.right * this.trans_x);
        //    this.transform.Translate(-1 *Vector3.up * this.trans_y);
        //}
    }


    void moveCameraByKey(float speed)
    {

        if (Input.GetKey(KeyCode.Q))
        {
            this.transform.Translate(Vector3.down * speed * Time.deltaTime);
        }

        if (Input.GetKey(KeyCode.E))
        {
            this.transform.Translate(Vector3.up * speed  *Time.deltaTime);
        }

        float moveV = Input.GetAxis("Vertical");
        float moveH = Input.GetAxis("Horizontal");

        this.transform.Translate(Vector3.forward * speed * moveV * Time.deltaTime + Vector3.right * speed * moveH * Time.deltaTime);
    }

}

这一篇就先到这了,下一篇我们会学习一下观察视角~希望大家能支持吧(●’◡’●)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角) 的相关文章

  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 【支持M1】MacDroid for Mac:Mac和Android安卓设备数据互通

    Mac和Android组合始终存在的唯一问题是无法在这些设备之间足够快地传输数据 但是MacDroid for mac填补了这一空白 MacDroid mac版是Macos上一款安卓手机数据传输助手 MacDroid mac下载支持Mac和
  • 码蹄集 ---- 供水管线 kruskal算法

    供水管线 kruskal算法 克鲁斯卡尔算法 最小生成树算法 应用场景 从连通图中找出最小生成树 和实际相结合的有 水管共线 公交车站路线图 城市间修路等 算法主要思想 将连通网中所有的边按照权值大小做升序排序 从权值最小的边开始选择 只要
  • C语言调用libusb访问USB驱动

    目录 一 环境搭建 1 下载库文件 2 解压 3 配置VS工程 3 1 头文件的配置
  • SyntaxError: unexpected EOF while parsing

    SyntaxError unexpected EOF while parsing 这是典型的没有验证函数参数是否有效 原因是eval str 的字符串为空 你可以运行如下代码 观察输出 try print eval except Excep
  • 六句话给出 Synchronized 和 Lock 的区别

    1 Synchronized 内置的 Java 关键字 Lock 是一个 Java 类 2 Synchronized 无法判断获取锁的状态 Lock 可以判断是否获取到了锁 3 Synchronized 会自动释放锁 Lock 必须要手动释
  • Windows下Anaconda3下载安装详细步骤

    第一步 去官网下载Anaconda Individual Editionhttps www anaconda com products individual 第二步 点击Download 在安装之前 要先安装python的版本 这里我先安装
  • C++ 实验8 继承

    编写一个学生和教师数据输入和显示程序 学生数据有编号 姓名 班级和成绩 教师数据有编号 姓名 职称和部门 要求将编号 姓名输入和显示设计成一个类person 并作为学生类student和教师类teacher的基类 类图如下 代码如下 头文件
  • Win10笔记本(机械革命)亮度调节快捷键失效-已解决

    Win10笔记本 机械革命 亮度调节快捷键失效 已解决 1 确定你已经安装了核心显卡驱动 驱动精灵检查一下 2 右击此电脑 管理 系统工具 设备管理器 监视器 单击展开 卸载dpms 卸载Generic Monitor 选中删除相关驱动 3
  • iText包对每页pdf文件加水印

    https ishare iask sina com cn f 31zwqlKmIwM html
  • 用户编写的python程序、无需修改就可以_python的笔记(一)

    Python的基本特点一种动态解释型的编程语言 规范的代码 Python 采用强制缩进的方式使得代码具有极佳的可读性 高级语言特性 封装内存管理等 可移植性 程序如果避免使用依赖于系统的特性 那么无需修改就可以在任何平台上运行 解释性 直接
  • 带你入门TypeScript

    一 为何学习TS 1 TypeScript 在社区的流行度越来越高 它非常适用于一些大型项目 也非常适用于一些基础库 极大地帮助我们提升了开发效率和体验 2 TypeScript 可以编译出纯净 简洁的 JavaScript 代码 并且可以
  • python画玫瑰图_python windrose(风玫瑰图)

    conda install c https conda anaconda org conda forge windrose b 用pip install windrose可以成功 但是安装的路径 python找不到 from windros
  • 多表联查优化

    多表联查优化我总结有以下几点 优化sql语句 索引优化 反范式设计 业务代码优化 使用缓存 优化sql语句 sql性能分析 查看执行频次 查看执行频次 select insert delete update shwo global sess
  • Python应该怎么学,如何系统地自学Python?

    这是一份kaggle上的银行的数据集 研究该数据集可以预测客户是否认购定期存款y 这里包含20个特征 1 分析框架 2 数据读取 数据清洗 导入相关包 import numpy as np import pandas as pd 读取数据
  • 厉害了,用 Java 也能实现图片识别!

    点击上方 Java基基 选择 设为星标 做积极的人 而不是积极废人 源码精品专栏 原创 Java 2020 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 Rock
  • VS2010 编译 sqlite3 生成动态库和链接库

    如果想以dll的方式使用sqlite而新建空的dll工程 添加sqlite源文件 会发现能生成dll 但缺乏lib函数信息映射库 单独使用dll文件是比较麻烦的 而网上多数做法是通过lib exe手动生成lib 这当然不是我想要的 结合几篇
  • 给NVMe设备发送一个SCSI READ_10命令

    0 READ 10命令 READ 6命令只能支持块大小为512B设备的2GB范围的寻址 因此官方推荐将READ 6迁移到READ 10 READ 10具有2TB的寻址能力 对于800G的NVMe设备来说当然是极好的 其实READ 10具有更
  • 【解决】手机安卓已经导入burp证书,但仍提示此证书并非来自被信任的机构

    安卓手机已经安装burpsuite证书 但app应用软件仍无法访问https联网 浏览器可以访问http但https提示此证书并非来自被信任的机构 这问题应该是安卓独有的 博主之前的模拟器访问完全没问题 最近突然无法访问 用控制变量法 我改
  • 2013年11月26日星期二(t3dlib1剩余部分---2)

    接下来 继续进行T3DLIB1剩余部分 倒着进行 先进行bob碰撞检测 int DDraw BOB Collision BOBS BOB PTR bob1 BOB PTR bob2 if bob1 bob2 return 0 int wid
  • 【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)

    陆陆续续又开始更新自己的博客 看来自我驱动能力还是不够啊 废话不多说了 之前的内容大概说了一下Unity的一些基础知识 接下来我们将要对一些基本功能做一些学习 大家都知道 一个游戏 少不了摄像机的参与 这不是废话么 没摄像机怎么玩 画面都不