100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > unity第三人称视角下的摄像机控制及防穿墙

unity第三人称视角下的摄像机控制及防穿墙

时间:2021-07-05 11:31:51

相关推荐

unity第三人称视角下的摄像机控制及防穿墙

unity第三人称视角下使用手柄的摄像机控制及防穿墙

有关手柄的设置参考下面这个帖子,这里不再重复

/qq_45919090/article/details/109397608

要让相机跟随角色,首先可以让相机成为角色的子物体,或在初始时得到相机与角色的偏移量,在运动过程中让角色的位置加上这个偏移量即可。为了更好适应角色所处环境及实现其他功能,可以采用以下方法:

创建一个空物体Empty,在Empty下创建一个子物体Position,最后使相机成为Position的子物体。接下来我们需要设置这几个物体(在代码中),让Empty的position等于人物的position,让Position的位置等于人物的位置的Y方向加1.0f(其实可以随意设置),再把相机设置到合适的位置使之看向角色(设置相机可以在Scene模式下设置)。

创建一个C#脚本,将其挂载在Empty上,定义以下变量,并在Start方法中获取刚才设置的物体的Transform组件以及相机与Postion的偏移量

private Transform charactor;//获取当前角色private Transform pos;//获取Empty的子物体posprivate Vector3 offset;//获取初始时镜头相对于pos的偏移量private float R_H;//获取摇杆的返回值-水平轴private float R_V;//获取摇杆的返回值-垂直轴private float lookAngle;//镜头说水平旋转的角度private float tiltAngle;//镜头垂直旋转的角度(实质为父物体pos的垂直旋转角度)private float moveSpeed = 10f;//用于设置镜头跟随的速度private float turnSpeed = 1.5f;//用于设置镜头在两个方向上旋转的角度private Transform mainCamera;// Use this for initializationvoid Start(){charactor = GameObject.FindGameObjectWithTag("Charactor").GetComponent<Transform>();pos = GameObject.FindGameObjectWithTag("Pos").GetComponent<Transform>();mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Transform>();offset = mainCamera.position - pos.position;}

相机跟随角色可以采用以下方法:

private void FollowCharactor(float deltaTime){//注意需要把offset转为pos的局部坐标mainCamera.position = Vector3.Lerp(mainCamera.position, pos.position + pos.TransformDirection(offset), deltaTime * moveSpeed);}

引入deltaTime参数和Lerp方法可以使镜头变换更加平滑顺畅

接下来是控制镜头左右和上下旋转,镜头的水平方向旋转由Empty控制,垂直方向的旋转由pos控制,这么做可以防止镜头注视角色的时候旋转出现问题,比如在自身Z轴上发生旋转

private void HandleCameraRotate(){transform.position = charactor.position;//设定水平旋转角度lookAngle += R_H * turnSpeed;transform.localEulerAngles = new Vector3(0, lookAngle, 0);//将得到的角度赋值给empty的localEulerAnglestiltAngle -= turnSpeed * R_V;//设定垂直旋转角度tiltAngle = Mathf.Clamp(tiltAngle, -80, 50);//对旋转角度加以限制pos.localEulerAngles = new Vector3(tiltAngle, pos.localEulerAngles.y, pos.localEulerAngles.z);//将得到的角度赋值给pos的localEulerAngles}

这样基本的控制就做完了,可以在Update()方法中调用(实测FixedUpdate和LateUpdate方法中调用效果不好)

void Update(){R_H = Input.GetAxis("Horizontal_Right");R_V = Input.GetAxis("Vertical_Right");HandleCameraRotate();FollowCharactor(Time.deltaTime);}

对于防镜头穿墙的方法,这是我个人想出来的可能算是比较简单的一种写法,在Update中调用即可

从pos的位置开始,创建一条指向相机的射线,长度为offset,判断射线碰撞到的物体的标签

private void AvoidCrossWall(){RaycastHit hit;if (Physics.Raycast(pos.position, mainCamera.position - pos.position, out hit, offset.magnitude)){if (hit.collider.tag == "Obstacle"){mainCamera.position = hit.point;}}}

本方法需要把不想让墙穿过的所有物体的标签设置为Obstacle

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。