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虽然 ...
随机推荐
- 根据IP查找计算机名
查找10.10.10.X段的计算机名称 $r="10.10.10." $s=1..254 foreach ($a in $s) { $ip = $r + [string]$a $i ...
- win7 win10双系统开机系统引导
以win7启动管理器引导作为启动引导 安装一个easybcd 然后里面添加引导选项(添加新条目---->编辑引导菜单(选择倒计时30秒)把use metro bootloader勾去掉就是默认的 ...
- css清楚浮动
在各种浏览器中显示效果也有可能不相同,这样让清除浮动更难了,下面总结8种清除浮动的方法,测试已通过 ie chrome firefox opera,需要的朋友可以参考下 浮动会使当前标签产生向上浮的效 ...
- node学习笔记_03 express框架
express api地址:http://www.expressjs.com.cn/starter/static-files.html 一.安装依赖 npm i --save express npm ...
- jQuery UI dialog插件出错信息:$(this).dialog is not a function
使用jQuery UI 1.7.2 dialog插件,遇到这样的错误: [img]http://dl.iteye.com/upload/attachment/308166/97c428e4-2ce2- ...
- 为什么Github要把代码合并请求称为pull request而不是push request?
问题: 我的理解是:我做了一些修改,我请求把我的修改push到你的仓库,然后你review一下我的代码,如果没问题就接受请求merge,这样的话叫做push request岂不是更合适?因为这个操作是 ...
- 有意思的flex 色子布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Spark项目之电商用户行为分析大数据平台之(七)数据调研--基本数据结构介绍
一.user_visit_action(Hive表) 1.1 表的结构 date:日期,代表这个用户点击行为是在哪一天发生的user_id:代表这个点击行为是哪一个用户执行的session_id :唯 ...
- vue实例的属性和方法
vue实例的属性和方法 1. 属性 vm.$el #指定要绑定的元素 vm.$data #Vue 实例的数据对象 vm.$options #获取自定义属性的值 new Vue({ customOpti ...
- ActivityCapture
Index: ActivityCapture.java =================================================================== --- ...