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虽然 ...
随机推荐
- 使用 jekyll + github pages 搭建个人博客
1. 新建 github.io 项目 其实 github pages 有两个用途,大家可以在官方网页看到.其中一个是作为个人/组织的主页(每个账号只能有一个),另一个是作为 github 项目的项目主 ...
- 使用C#获取Windows Phone手机的各种数据(转)
转自:http://www.sum16.com/desinger/use-c-sharp-get-windows-phone-information.html 使用C#获取Windows Phone手 ...
- 未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider,
未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft ...
- CHECKEDLISTBOX用法总结
C# CHECKEDLISTBOX用法总结 一般认为:foreach (object obj in checkedListBox1.SelectedItems)即可遍历选中的值. 其实这里遍历的只 ...
- PReLU与ReLU
PReLU激活函数,方法来自于何凯明paper <Delving Deep into Rectifiers:Surpassing Human-Level Performance on Image ...
- WorldWind源码剖析系列:绘制参数类DrawArgs
绘制参数类DrawArgs主要对绘制时需要的对象如:设备对象Microsoft.DirectX.Direct3D.Device.Microsoft.DirectX.Direct3D.Font字体对象. ...
- 第9章 初识STM32固件库
第9章 初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- odoo明细表汇总数据
一.在主表中#改动地方 总结算金额 求和:def _get_subtotal2(self, cr, uid, ids, field_name, arg, context=None): # 初始化 re ...
- Docker一键部署Hadoop心得(一)
最近一直在折腾使用docker一键部署全分布式hadoop集群,虽然一键部署的脚本写好了并且可以成功运行出各个节点,但在运行一个wordcount实例时出现了错误,错误如下: java.io.IOEx ...
- vi学习
刚开始学习vi,所以,一步一步开始 先贴出一个相关的学习链接https://www.cnblogs.com/ranjiewen/p/5901181.html 这个学习链接里面的东西还是比较详细的,但是 ...