[Unity3d]第一人称和第三人称视角完美切换

简介: 最近一直在搞3D漫游,在第一人称和第三人称视角切换碰到些问题,视角的例子我是导入的官方的character controller包,不得不佩服官方脚本语言的写法,看了一下写的很完美,新手估计比较难看懂,里面涉及到一些角度,还有向量等的计算,这就要求有一定的图形学的...

最近一直在搞3D漫游,在第一人称和第三人称视角切换碰到些问题,视角的例子我是导入的官方的character controller包,不得不佩服官方脚本语言的写法,看了一下写的很完美,新手估计比较难看懂,里面涉及到一些角度,还有向量等的计算,这就要求有一定的图形学的基础,我将官方的第一人称视角和第三人称视角结合了一下,但发现还是不那么容易,不仅仅只是简单的摄像机的切换和position以及rotation的赋值而已,当然这种方法适合第三人称切换至第一人称,而第一人称切换至第三人称你会发现根本方向就切换不过来,位置是对了,但方向还是原来的方向,这就让我有点苦恼,然后不得已只能硬着头皮去看官方写的控制第三人称人物运行的脚本ThirdPersonController,里面有一些英文的注解,这脚本写的还是有一定的技术含量,毕竟是官方的嘛,想要看懂还是要慢慢静下心来看的。

实现步骤:                                                                                                                                                                                                        

1.导入官方的第一人称和第三人称的Person,会发现,第三人称的Main Camera是在model的外面而第一人称的Main Camera是在model的里面,这里最好统一一下,我将第三人称的那个model拉到我新建的一个空物体下(记得reset这空物体),然后将主摄像机也拖放到这个空物体下,最好确保camera和3rdPersonController平级。这里还要说一下的,将3rdPersonController也reset一下,然后设置PositionY跟相机的Y一样,我这里设置的是51大概。

2.创建视角切换的脚本viewpointSwitch,挂在GUI的物体上,这个物体挂了一些关于GUI还有控制鼠标隐藏显示的脚本
鼠标隐藏和显示:
void Update() 
{
	 if (Input.GetKey(KeyCode.H))
	// Lock the cursor inside gameview
	 Screen.lockCursor = true;
	// Hide mouse cursor
	Screen.showCursor = false;
	
	if(Input.GetKey(KeyCode.U))
	 // Lock the cursor inside gameview
	Screen.lockCursor = false;
	//Show mouse cursor
	Screen.showCursor = true;
}

viewpointSwitch:

using UnityEngine;
using System.Collections;

public class ViewpointSwitch : MonoBehaviour {
    //从场景中拖入的object
    public GameObject Obj_3rd;
    public GameObject cam_3rd;
    public GameObject gobj_3rd;

    public GameObject Obj_1fs;
    public GameObject cam_1fs;
    public GameObject gobj_1fs;

    //记录刚进入第一人称视角时候的欧拉角和离开第一视角时候的欧拉角(Y方向)
    float pre1fsAngle = 0;
    float cur1fsAngle = 0;

	// Update is called once per frame
	void Update ()
    {
        //切换至第一人称视角
        if (Input.GetKey(KeyCode.F1))
        {
            //记录一开始
            //pre1fsAngle = cam_1fs.transform.eulerAngles.y;
            pre1fsAngle = cam_3rd.transform.eulerAngles.y;  //记录的第一人称(这里取的是第三人称,其实是一样的)一开始的y方向欧拉角,这里没用上面注释掉的写法是防止重复按f1键切换然后覆盖初始值导致旋转角度差值缩小
            if (!Obj_1fs.activeSelf)
            {
                Obj_1fs.SetActive(true);
                GameObject.Find("Main Character Controller").transform.localPosition = GameObject.Find("3rd Person Controller").transform.localPosition;
                GameObject.Find("Main Character Controller").transform.localRotation = GameObject.Find("3rd Person Controller").transform.localRotation;
                Obj_3rd.SetActive(false);
            }
        }
        //切换至第三人称视角
        if (Input.GetKey(KeyCode.F2))
        {
            cur1fsAngle = cam_1fs.transform.eulerAngles.y;  //记录
            if (!Obj_3rd.activeSelf)
            {
                Obj_3rd.SetActive(true);
                GameObject.Find("3rd Person Controller").transform.localPosition = GameObject.Find("Main Character Controller").transform.localPosition;
                //注意这里Mathf里面的方法是幅度,我这里就进行了一个角度转幅度的计算:幅度=角度*pi/180
                float angle = (cur1fsAngle - pre1fsAngle) * Mathf.PI / 180;
                gobj_3rd.GetComponent<ThirdPersonController>().v = Mathf.Cos(angle);
                gobj_3rd.GetComponent<ThirdPersonController>().h = Mathf.Sin(angle);
                print("旋转角度:" + (cur1fsAngle-pre1fsAngle));
                gobj_3rd.GetComponent<ThirdPersonController>().flag = true;  //这个flag标志是让ThirdPersonController的update方法执行改变上面的v,h一次,然后第二帧的时候就执行v=Input.GetAxisRaw("Vertical")和h=Input.GetAxisRaw("Horizontal")
                Obj_1fs.SetActive(false);
            }
        }
	}
}
备注:
//w(1) & s(-1)(前后运动)
v = Input.GetAxisRaw("Vertical");
 //a(-1) & d(1)(左右运动)
 h = Input.GetAxisRaw("Horizontal");
这里的v和h变量要解释一下,v代表前后方向,如果按下前方向w键,这里Input.GetAxisRaw("Vertical")会有一个-1~1的一个变化,如果是遥感就会有浮点数,但如果是键盘的话,一般就是0,-1,1三个状态,按下w前进方向键,v会变成1,如果按下后退键s,v就会变成-1,如果不按则是0。h就是代表水平左右轴向,a键按下h=-1,d按下h=1,不按则代表0。
Third PersonController.js人物旋转的方向是始终转向一个前进的方向向量,var targetDirection = h * right + v * forward;
这里的right和forward分表表示X轴(forward方向)和Z轴(right方向)的单位向量
var forward = cameraTransform.TransformDirection(Vector3.forward);
var right = Vector3(forward.z, 0, -forward.x);

效果图:                                                                                                                                                                                                              

1.刚开始启动,第三人称的模型朝向以及旋转坐标
    

2.按一下D键,也就是右键,人物旋转,90度,朝向以及旋转坐标,以及v,h(控制旋转方向的一个系数,上文有介绍)的值





在线展示:                                                                                                                  

http://ueige123.oicp.net/dingxiaowei/13viewpointswitch/13viewpointswitch.html



==================== 迂者 丁小未 CSDN博客专栏=================

MyBlog:http://blog.csdn.net/dingxiaowei2013             MyQQ:1213250243

Unity QQ群:375151422         cocos2dx QQ群:280818155

====================== 相互学习,共同进步 ===================

 

转载请注明出处:http://blog.csdn.net/dingxiaowei2013/article/details/18281261

欢迎关注我的微博:http://weibo.com/u/2590571922



相关文章
|
3月前
|
API
【threejs教程】场景视角切换的神器:轨道控制器
【8月更文挑战第5天】threejs教程:场景视角切换的神器,轨道控制器
156 1
【threejs教程】场景视角切换的神器:轨道控制器
|
2月前
|
前端开发 图形学 开发者
【独家揭秘】那些让你的游戏瞬间鲜活起来的Unity UI动画技巧:从零开始打造动态按钮,提升玩家交互体验的绝招大公开!
【9月更文挑战第1天】在游戏开发领域,Unity 是最受欢迎的游戏引擎之一,其强大的跨平台发布能力和丰富的功能集让开发者能够迅速打造出高质量的游戏。优秀的 UI 设计对于游戏至关重要,尤其是在手游市场,出色的 UI 能给玩家留下深刻的第一印象。Unity 的 UGUI 系统提供了一整套解决方案,包括 Canvas、Image 和 Button 等组件,支持添加各种动画效果。
122 3
|
3月前
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
126 3
|
3月前
|
开发者 图形学 C#
深度解密:Unity游戏开发中的动画艺术——Mecanim状态机如何让游戏角色栩栩如生:从基础设置到高级状态切换的全面指南,助你打造流畅自然的游戏动画体验
【8月更文挑战第31天】Unity动画系统是游戏开发的关键部分,尤其适用于复杂角色动画。本文通过具体案例讲解Mecanim动画状态机的使用方法及原理。我们创建一个游戏角色并设计行走、奔跑和攻击动画,详细介绍动画状态机设置及脚本控制。首先导入动画资源并添加Animator组件,然后创建Animator Controller并设置状态间的转换条件。通过编写C#脚本(如PlayerMovement)控制动画状态切换,实现基于玩家输入的动画过渡。此方法不仅适用于游戏角色,还可用于任何需动态动画响应的对象,增强游戏的真实感与互动性。
88 0
|
3月前
|
图形学 C# 开发者
Unity粒子系统全解析:从基础设置到高级编程技巧,教你轻松玩转绚丽多彩的视觉特效,打造震撼游戏画面的终极指南
【8月更文挑战第31天】粒子系统是Unity引擎的强大功能,可创建动态视觉效果,如火焰、爆炸等。本文介绍如何在Unity中使用粒子系统,并提供示例代码。首先创建粒子系统,然后调整Emission、Shape、Color over Lifetime等模块参数,实现所需效果。此外,还可通过C#脚本实现更复杂的粒子效果,增强游戏视觉冲击力和沉浸感。
156 0
|
3月前
|
开发者 图形学 Java
Unity物理引擎深度揭秘:从刚体碰撞到软体模拟,全面解析实现复杂物理交互的技巧与秘诀,助你打造超真实游戏体验
【8月更文挑战第31天】物理模拟在游戏开发中至关重要,可让虚拟世界更真实。Unity作为强大的跨平台游戏引擎,内置物理系统,支持从刚体碰撞到布料模拟的多种功能。通过添加Rigidbody组件,可实现物体受力和碰撞;使用AddForce()施加力;通过关节(如Fixed Joint)连接刚体以模拟复杂结构。Unity还支持软体物理,如布料和绳索模拟,进一步增强场景丰富度。掌握这些技术,可大幅提升游戏的真实感和玩家体验。
89 0
|
5月前
|
图形学
【unity小技巧】unity3d环境带雾的昼夜系统变化
【unity小技巧】unity3d环境带雾的昼夜系统变化
42 0
|
11月前
|
图形学
Unity小游戏——怪物出现模式的管理
Unity小游戏——怪物出现模式的管理
122 0
|
图形学
【unity每日一记】--控制游戏人物移动的细节
【unity每日一记】--控制游戏人物移动的细节
190 0
|
存储 安全 C#
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(二)
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(二)