Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果
Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果
梗概:
一. 摄像机围绕目标物体旋转, 即摄像机离目标物体有一定的距离且旋转轴心为该物体的位置.
二. 当目标物体被障碍物挡住后, 需要将摄像机移动到障碍物前方能看见目标物体的位置.
思路:
一. 摄像机绕轴心旋转, 可以在轴心处创建一个空物体, 将摄像机设为该轴心的子物体. 如图: 







这样便可以简单地实现摄像机旋转轴心 (注意: 旋转时应旋转轴心而不是单独旋转摄像机) . 还应注意, 如果摄像机的目标物体可以移动的话, 就应每帧将轴心的坐标设为目标物体的坐标 (尽量不要直接将轴心设为目标物体的子物体! 除非有特别需要) .
二. 当目标物体被障碍物挡住后, 可以在目标物体处发射一条射线, 射线原点就是目标物体的坐标 (也就是轴心) , 射线方向就是从原点到摄像机的方向. 此时射线的碰撞点就是将要把摄像机调整到的位置. 



三. 当将摄像机移动到后方没有障碍物的位置时, 就应将摄像机移回至原距离. 

过程:
创建任意目标物体;
创建一个空物体并命名, 这个空物体就是轴心, 并将其 Tag 设为 "3rdCameraAxle":


或者将其 Tag 设为你喜欢的一个都可以;
创建摄像机, 将其 Tag 设为 "MainCamera", 并设为刚创建的轴心的子物体;
创建任意障碍物.
代码:
一. 此时绕物体旋转摄像机便可简化为直接旋转轴心, 代码也简化了许多:
定义鼠标灵敏度:
public float mouseSensitivity = ;
定义目标物体的 Transform :
public Transform targetTrans;
定义轴心 Transform 与轴心旋转角度:
Transform thirdPCamAxle;
Vector3 thirdPCamEuler;在 void Start() 下对其赋值:
void Start () {
thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform; //括号里的引号中也可以写上你自己对轴心设的 Tag.
thirdPCamEuler = thirdPCamAxle.localEulerAngles; //推荐写 localEulerAngles, 要不之后处理起来会比较麻烦.
}定义摄像机:
Camera thirdPCam;
在 void Start() 下对其赋值:
void Start () {
thirdPCam = Camera.main;
}定义并赋值摄像机离物体的最大距离, 摄像机离物体的当前距离:
float camForwardMaxDistance = ;
float camForwardDistance;
float camBackDistance;在 void Update() 下写:
thirdPCamAxle.position = targetTrans.position; //将摄像机旋转轴心位置设为目标物体位置
//定义旋转量
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
thirdPCamEuler.y += mouseX; //控制摄像机左右旋转
//控制摄像机上下旋转, 并且上下旋转范围不能超过90°或-90°, 此方法适用于 localEulerAngles.
if (thirdPCamEuler.z < && mouseY > ) { thirdPCamEuler.z += mouseY; }
if (thirdPCamEuler.z > - && mouseY < ) { thirdPCamEuler.z += mouseY; }
thirdPCamAxle.localEulerAngles = thirdPCamEuler; //将旋转量应用到摄像机上.
至此, 控制摄像机旋转完成. 此部分代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPCamC : MonoBehaviour {
public float mouseSensitivity = ;
public Transform targetTrans;
Transform thirdPCamAxle;
Vector3 thirdPCamEuler;
Camera thirdPCam;
float camForwardMaxDistance = ;
float camForwardDistance;
float camBackDistance;
void Start () {
thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform;
thirdPCamEuler = thirdPCamAxle.localEulerAngles;
thirdPCam = Camera.main;
} void Update () {
thirdPCamAxle.position = targetTrans.position;
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
thirdPCamEuler.y += mouseX;
if (thirdPCamEuler.z < && mouseY > ) { thirdPCamEuler.z += mouseY; }
if (thirdPCamEuler.z > - && mouseY < ) { thirdPCamEuler.z += mouseY; }
thirdPCamAxle.localEulerAngles = thirdPCamEuler;
}
}
二. 摄像机避开障碍物, 并在后方没有障碍物时移回原距离 (原距离可通过设置对 camForwardMaxDistance 的赋值来改变):
在 void Update() 下写:
Ray camForwardRay = new Ray(thirdPCam.transform.position, thirdPCam.transform.forward); //在摄像机处发射一条向前的射线, 用来检测摄像机当前离目标的距离 (此处不必担心射线碰撞处是障碍物的情况).
RaycastHit forwardRayHit; //定义射线碰撞.
if (Physics.Raycast(camForwardRay, out forwardRayHit)) //当射线有碰撞物时 (也就是目标物体),
{
camForwardDistance = Vector3.Distance(thirdPCam.transform.position, forwardRayHit.point); //计算从摄像机到碰撞点的距离 (碰撞点也可以改为目标物体的位置).
}
Vector3 dir = thirdPCam.transform.position - targetTrans.position; //定义从目标物体到摄像机的方向.
dir = dir.normalized; //将方向单位化.
Ray ray = new Ray(targetTrans.position, dir); //在目标物体处发射一条射线, 方向即为刚刚定义的向量.
RaycastHit hit; //定义射线碰撞.
if (Physics.Raycast(ray, out hit)) //当该射线有碰撞, 即目标物体被障碍物挡住时,
{
thirdPCam.transform.position = hit.point; //将摄像机位置设为碰撞点位置.
}
else //如果没有碰撞, 即目标物体没有被障碍物挡住,
{
if (camForwardDistance < camForwardMaxDistance) //并且当前距离没有超过最大距离时,
{
thirdPCam.transform.Translate(Vector3.back * Time.deltaTime * ); //将摄像机缓慢后移至最大距离.
}
}
全部代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPCamC : MonoBehaviour {
public float mouseSensitivity = ;
public Transform targetTrans;
Transform thirdPCamAxle;
Vector3 thirdPCamEuler;
Camera thirdPCam;
float camForwardMaxDistance = ;
float camForwardDistance;
float camBackDistance;
void Start () {
thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform;
thirdPCamEuler = thirdPCamAxle.localEulerAngles;
thirdPCam = Camera.main;
} void Update () {
thirdPCamAxle.position = targetTrans.position;
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
thirdPCamEuler.y += mouseX;
if (thirdPCamEuler.z < && mouseY > ) { thirdPCamEuler.z += mouseY; }
if (thirdPCamEuler.z > - && mouseY < ) { thirdPCamEuler.z += mouseY; }
thirdPCamAxle.localEulerAngles = thirdPCamEuler;
Ray camForwardRay = new Ray(thirdPCam.transform.position, thirdPCam.transform.forward);
RaycastHit forwardRayHit;
if (Physics.Raycast(camForwardRay, out forwardRayHit))
{
camForwardDistance = Vector3.Distance(thirdPCam.transform.position, forwardRayHit.point);
}
Vector3 dir = thirdPCam.transform.position - targetTrans.position;;
dir = dir.normalized;
Ray ray = new Ray(targetTrans.position, dir);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Debug.DrawLine(ray.origin, hit.point, Color.green);
thirdPCam.transform.position = hit.point;
}
else
{
if (camForwardDistance < camForwardMaxDistance)
{
thirdPCam.transform.Translate(Vector3.back * Time.deltaTime * );
}
}
}
}
最终效果图:


希望本篇教程能够帮到大家!
源码: [GitHub](https://github.com/JadMax/Unity3D-Miscellaneous/blob/master/ThirdpersonCameraController.cs)
Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果的更多相关文章
- Unity摄像机围绕物体旋转两种实现方式
第一种,使用Transform 函数 RotateAround. 代码如下: public Transform target;//获取旋转目标 private void camerarotate() ...
- Unity 3d 实现物体跟随摄像机视野运动
https://blog.csdn.net/qq_31411825/article/details/61623857 Unity 3d 实现物体跟随摄像机视野运动Created by miccall ...
- Unity 3D使用GameObject创建一个简单的可移动物体
于Unity 3D游戏的开发.游戏脚本需要3D模拟组合,该脚本将被写入阻力3D为了达到效果对象. 以下是一个小实例,使用Unity 3D实现一个可控制移动的小人.小人能够向前.向后.向左和向右移动. ...
- Unity KGFMapSystem插件制作小地图
KGFMapSystem版本:2.3 在我们开发游戏或者虚拟现实中,一般都会用到小地图,如果要我们去写小地图,可以用到unity 3d中就有一个插件,是专门开发小地图用的,这个插件就是KGFMapSy ...
- 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例
一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...
- Unity 3D入门简介
最近在刚开始学习Unity 3D,在这里记录一下学习心得和学习笔记,边学边写,可能会比较零散.好了,废话不多说,今天从Unity 3D入门写起,主要简要介绍一下Unity 3D的和一些学习资料.以下如 ...
- 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门演示样例
一. 工作区域具体解释 1. Scence视图 (场景设计面板) scence视图简单介绍 : 展示创建的游戏对象, 能够对全部的游戏对象进行 移动, 操作 和 放置; -- 演示样例 : 创建一个球 ...
- Unity 3D 游戏上线之后的流水总结
原地址:http://tieba.baidu.com/p/2817057297?pn=1 首先.unity 灯光烘焙 :Unity 3D FBX模型导入.选项Model 不导入资源球.Rig 不导入骨 ...
- C#程序员整理的Unity 3D笔记(十五):Unity 3D UI控件至尊–NGUI
目前,UGUI问世不过半年(其随着Unity 4.6发布问世),而市面上商用的产品,UI控件的至尊为NGUI:影响力和广度(可搜索公司招聘Unity 3D,常常能看到对NGUI关键词). NGUI虽然 ...
随机推荐
- Linux内核参数基础优化
web 服务负载均衡器常规网站服务器优化的基本配置: net.ipv4.tcp_fin_timeout =2 net.ipv4.tcp_tw_reuse =1 net.ipv4.tcp_tw_recy ...
- 【转】Nginx学习---深入浅出Nginx的介绍
[原文]https://www.toutiao.com/i6595428119933354500/ Nginx是一款轻量级的Web服务器.反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在 ...
- 利用windows的计划任务和eKing.CmdReadFileAndSendEmailOper(控制台小程序)实现远程登录服务器的邮件告警提醒
一.场景摘要: 1.windows计划任务中,有一个用户登录时候触发的事件 2.cmd命令:netstat -ano | find "3389" 可以看到当前远程登录的IP 3 ...
- Apache的权限设置与构建虚拟web主机
实验拓扑图: 实验要求: 1. 搭建WEB服务器,能访问默认站点,并使用awstats软件能监控到默认站点的访问情况. 2. 修改Apache的主配置文件,设置1.10只能访问awstats网站, ...
- SQL语句:查看排名前五的SQL语句耗时情况
total_worker_time , last_worker_time , max_worker_time , min_worker_time , ) , ( ( CASE statement_en ...
- sed和awk学习整理
Awk和Sed的基本使用 可以用大至相同的方式调用sed 和awk .命令行讲法是:command [options] script filename几乎和所有的unlx程序一样,sed和awk都可以 ...
- SDN期末验收
队名:取个队名真难 一.网络拓扑 二.负载均衡程序 1.建立拓扑的代码 拓扑 2.下发组表流表的代码 下发流表 三.演示视频 1.目的 服务器h2,h3,h4上各自有不同的服务,h1是客户端.实现一个 ...
- Java多线程学习笔记之一线程基础
1.进程与线程 1.1 进程:是正在运行中的程序的实例,一个运行中idea就是一个进程.进程有它自己的地址空间,一般情况下,包括文本区域(text region).数据区域(data region)和 ...
- Vue2.0中v-for迭代语法变化(key、index)【转】
转自:http://blog.csdn.net/sinat_35512245/article/details/53966788 Vue2.0的代码中发现 $key这个值并不能渲染成功,问题如下:但是v ...
- XAML 布局StackPanel
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/Fanbin168/article/details/24768459 <Window x:Cla ...