Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果

梗概:

一. 摄像机围绕目标物体旋转, 即摄像机离目标物体有一定的距离且旋转轴心为该物体的位置.

二. 当目标物体被障碍物挡住后, 需要将摄像机移动到障碍物前方能看见目标物体的位置.

思路:

一. 摄像机绕轴心旋转, 可以在轴心处创建一个空物体, 将摄像机设为该轴心的子物体. 如图:

这样便可以简单地实现摄像机旋转轴心 (注意: 旋转时应旋转轴心而不是单独旋转摄像机) . 还应注意, 如果摄像机的目标物体可以移动的话, 就应每帧将轴心的坐标设为目标物体的坐标 (尽量不要直接将轴心设为目标物体的子物体! 除非有特别需要) .

二. 当目标物体被障碍物挡住后, 可以在目标物体处发射一条射线, 射线原点就是目标物体的坐标 (也就是轴心) , 射线方向就是从原点到摄像机的方向. 此时射线的碰撞点就是将要把摄像机调整到的位置.

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

过程:

  1. 创建任意目标物体;

  2. 创建一个空物体并命名, 这个空物体就是轴心, 并将其 Tag 设为 "3rdCameraAxle":

    或者将其 Tag 设为你喜欢的一个都可以;

  3. 创建摄像机, 将其 Tag 设为 "MainCamera", 并设为刚创建的轴心的子物体;

  4. 创建任意障碍物.

代码:

一. 此时绕物体旋转摄像机便可简化为直接旋转轴心, 代码也简化了许多:

  1. 定义鼠标灵敏度:

    public float mouseSensitivity = ;
  1. 定义目标物体的  Transform  :

    public Transform targetTrans;
  1. 定义轴心  Transform  与轴心旋转角度:

    Transform thirdPCamAxle;
    Vector3 thirdPCamEuler;

    在  void Start()  下对其赋值:

    void Start () {
    thirdPCamAxle = GameObject.FindGameObjectWithTag("3rdCameraAxle").transform; //括号里的引号中也可以写上你自己对轴心设的 Tag.
    thirdPCamEuler = thirdPCamAxle.localEulerAngles; //推荐写 localEulerAngles, 要不之后处理起来会比较麻烦.
    }
  2. 定义摄像机:

    Camera thirdPCam;

    在  void Start()  下对其赋值:

    void Start () {
    thirdPCam = Camera.main;
    }
  3. 定义并赋值摄像机离物体的最大距离, 摄像机离物体的当前距离:

    float camForwardMaxDistance = ;
    float camForwardDistance;
    float camBackDistance;
  4. 在  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 简易制作摄像机围绕物体随鼠标旋转效果的更多相关文章

  1. Unity摄像机围绕物体旋转两种实现方式

    第一种,使用Transform 函数 RotateAround. 代码如下: public Transform target;//获取旋转目标 private void camerarotate() ...

  2. Unity 3d 实现物体跟随摄像机视野运动

    https://blog.csdn.net/qq_31411825/article/details/61623857 Unity 3d 实现物体跟随摄像机视野运动Created by miccall ...

  3. Unity 3D使用GameObject创建一个简单的可移动物体

    于Unity 3D游戏的开发.游戏脚本需要3D模拟组合,该脚本将被写入阻力3D为了达到效果对象. 以下是一个小实例,使用Unity 3D实现一个可控制移动的小人.小人能够向前.向后.向左和向右移动. ...

  4. Unity KGFMapSystem插件制作小地图

    KGFMapSystem版本:2.3 在我们开发游戏或者虚拟现实中,一般都会用到小地图,如果要我们去写小地图,可以用到unity 3d中就有一个插件,是专门开发小地图用的,这个插件就是KGFMapSy ...

  5. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

  6. Unity 3D入门简介

    最近在刚开始学习Unity 3D,在这里记录一下学习心得和学习笔记,边学边写,可能会比较零散.好了,废话不多说,今天从Unity 3D入门写起,主要简要介绍一下Unity 3D的和一些学习资料.以下如 ...

  7. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门演示样例

    一. 工作区域具体解释 1. Scence视图 (场景设计面板) scence视图简单介绍 : 展示创建的游戏对象, 能够对全部的游戏对象进行 移动, 操作 和 放置; -- 演示样例 : 创建一个球 ...

  8. Unity 3D 游戏上线之后的流水总结

    原地址:http://tieba.baidu.com/p/2817057297?pn=1 首先.unity 灯光烘焙 :Unity 3D FBX模型导入.选项Model 不导入资源球.Rig 不导入骨 ...

  9. C#程序员整理的Unity 3D笔记(十五):Unity 3D UI控件至尊–NGUI

    目前,UGUI问世不过半年(其随着Unity 4.6发布问世),而市面上商用的产品,UI控件的至尊为NGUI:影响力和广度(可搜索公司招聘Unity 3D,常常能看到对NGUI关键词). NGUI虽然 ...

随机推荐

  1. Orange Pi 3 GPIO 笔记

    这是我写过的最水的文章 设备:Orange pi H6,Pi 3 引脚图: (使用Wiringpi 查看GPIO) +------+-----+----------+------+---+Orange ...

  2. SDN2017 第四次实验作业

    实验目的 1.使用图形化界面搭建拓扑如下并连接控制器 2.使用python脚本搭建拓扑如下并通过命令行连接控制器 3.使用任一种方法搭建拓扑连接控制器后下发流表 实验步骤 建立以下拓扑,并连接上ODL ...

  3. Python高级知识点总结

    一.可迭代对象.迭代器对象和生成器 像list, tuple等这些序列是可以使用for...in ...语句来进行遍历输出的.这是为什么呢?这就需要知道可迭代对象(Iterable).迭代器对象(It ...

  4. apache-httpd工作模式

    [root@app1 conf]# ../bin/apachectl -lCompiled in modules: core.c mod_access.c mod_auth.c mod_include ...

  5. leetcode-844 Backspace String Compare

    Given two strings S and T, return if they are equal when both are typed into empty text editors. # m ...

  6. ansible 远程以普通用户执行命令

    1. ansible 10.0.0.1 -m raw -a "date" -u www 2.在ansible的主机配置文件中指定ssh_uservi/etc/ansible/hos ...

  7. 计算机视觉-sift(1)原理

    1999年由David Lowe首先发表于计算机视觉国际会议(International Conference on Computer Vision,ICCV),2004年再次经David Lowe整 ...

  8. jquery的$(document).ready()与js的window.onload区别

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  9. LNMP搭建 源码包

    LNMP源码包搭建 linux    CentOS-6.5-x86_64-bin-DVD1 nginx   版本1.8.0  下载地址:http://nginx.org/en/download.htm ...

  10. 1.4《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——编辑命令

    在编辑模式中,命令行包括几个重复之前命令的功能.这些以及其他很多命令功能时常设计键盘上的特殊键,所以给出Table 1作为参考,给出了许多键在典型的Macintosh键盘上的标记符号.若你的键盘不太一 ...