游戏开发 浅谈各类游戏中的第三人称相机实现

        一眨眼,在网易的Mini项目结束了,终于有时间可以写点东西了,一看时间,又是好几个月没有更过博客了,回想起来,这几个月其实也不像去年那种什么东西都没学实在没东西写的状态,只是的确做Mini项目有点太忙了,趁着项目完成这段时间,赶紧写点东西吧,因为在做Mini项目的时候有关人物控制以及相机的操作都是我来做的,并且游戏中的相机视角为第三人称,在开发的过程中也算对这方面有了更深一层的理解,所以小编今天就来浅谈一下各类游戏中的相机分类以及实现方法。

        相机其实本质上来说就是玩家的眼睛,玩家在游戏中所能看到的都是在游戏场景中的相机所看到的。首先我们先来分析一下游戏中的视角,说到游戏过程中的视角,一般来说我们可以将视角分为第一人称和第三人称,除此之外,还可能会有一些非玩家控制的视角,比如过场动画。说到第一人称视角的游戏,可能让大家第一时间想到的就是射击类游戏,大部分射击类游戏都是采用第一人称视角,当然也有TPS类游戏(第三人称射击),比如绝地求生就会有TPP模式,但是由于射击类游戏大部分都强调公平射击视野,也就是目标在视野内的同时,自己也在目标的视野内,所以大部分射击类游戏都是采用的第一人称的视角。在第一人称的游戏中,由于视野几乎是和人物朝向绑定的,所以完全可以将相机绑定在人物骨骼模型上,通过旋转来控制人物朝向的同时,转动相机。但是这种简单粗暴的方式是不能使用在第三人称的模式下,因为在第三人称的视角下,相机的朝向不再是百分之一百和人物朝向对等,当然这也是有特殊情况可以分的,同样可以通过绝地求生来举例,在绝地求生的TPP模式下,当我们按住右键进行腰射时,我们的人物朝向也几乎是和相机的朝向相同,假如我们做的游戏也是需要我们一直保持相机和人物的朝向相同,我们也可以直接把相机绑定在人物骨骼上。类似与鬼泣,大部分的第三人称游戏的相机都是围绕着我们的人物转动,但是朝向并不是绑定人物朝向,而是玩家可以自己通过操作来转动相机,同时我们在移动人物时的移动方向却是根据我们相机的方向来决定,所以在这样的条件下,我们是不能将相机绑定在人物模型上的,此时我们则需要三个关键的参数来控制相机的位置:1.相机的观察点 2.相机朝向 3.相机和观察点的距离。

        首先小编先解释一下这个相机观察点,假如我们在玩这种第三人称类的游戏时,我们把相机的位置往前调,你会发现有的游戏相机往前后并不一定是对准人物中心的,那么这个点,我们称之为相机的观察点,这个观察点我们可以绑定人物模型上,因为它是随时跟随着人物的移动来更新位置的,有了这个观察点后,我们就可以通过相机的朝向以及相机距离来确定相机的位置,根据这三个参数,我们的相机就能保证它的实现本质是一直围绕着玩家转。

if (Target != null)
{
    //print(CrossPlatformInputManager.GetAxis("Mouse X") + " " + CrossPlatformInputManager.GetAxis("Mouse Y"));
    mX += CrossPlatformInputManager.GetAxis("Mouse X") * SpeedX * 0.1f;
    mY += -CrossPlatformInputManager.GetAxis("Mouse Y") * SpeedY * 0.1f;
    mY = ClampAngle(mY, MinLimitY, MaxLimitY);
    mRotation = Quaternion.Euler(mY, mX, 0);
    if (isNeedDamping)
    {
        transform.rotation = Quaternion.Lerp(transform.rotation, mRotation.normalized, Time.deltaTime * Damping);
    }
    else
    {
        transform.rotation = mRotation;
    }
}
d = Distance;
RaycastHit hit;
int layerMask = ~(1 << 12);
if (Physics.SphereCast(Target.position, 0.2f, -transform.forward, out hit, Distance, layerMask))
{
    //print(hit.collider.name);
    GameObject hitG = hit.collider.gameObject;
    AIControl AI = hitG.GetComponent<AIControl>();
    Door door = hitG.GetComponent<Door>();
    DoorCollider doorCollider = hitG.GetComponent<DoorCollider>();
    if (AI == null && door == null && doorCollider == null)
    {
        d = Mathf.Clamp(hit.distance, 0.0f, Distance);
    }

}
if (d < 1.0f)
{
    player_mesh.SetActive(false);
}
else
{
    player_mesh.SetActive(true);
}
Vector3 mPosition = mRotation * new Vector3(0, 0, -d) + Target.position;
if (isNeedDamping)
{
    transform.position = Vector3.Lerp(transform.position, mPosition, Time.deltaTime * Damping);
}
else
{
    transform.position = mPosition;
}

猜你喜欢

转载自blog.csdn.net/RaAlGhul/article/details/93519891
今日推荐