• Unity3d


    前期工程实现了角色移动,现需要完成镜头的跟随及控制。

    一、镜头的跟随

    思路很简单,首先取得镜头初始与角色的距离向量值,然后让相机与角色持续保持该向量距离即可。脚本如下:

    NameSpace FollowPlayer

    private Transform player;

    private Vector3 offsetPosition;

    void Start( )

    {

        player = GameOject.FindGameObjectWithTag("player").transform;

        offsetPosition = transform.position - player.position;

    }

    Void Update( )

    {

        transform.position = player.position + offsetPosition;

    }

    以上便实现了镜头跟随角色移动的效果。

    二、镜头的控制

    镜头的控制分解为镜头拉伸和旋转。

    2.1 镜头的拉伸

    镜头的拉伸本质就是变更镜头于角色间的向量差,在上述脚本生效后,镜头于角色的向量差就是offsetPosition,而且是一个定值,那么现在就是需要把这个定值根据操作进行变化而已。

    使用Input.GetAxis("Mouse ScrollWheel")来记录该值。

    对上述脚本进行更新为:

    NameSpace FollowPlayer

    public float scrollspeed = 5;

    void SrollView( )

    {

        float distance = offsetPosition.magnitude; //却得offsetPosition的向量方差

        distance += Input.GetAxis("Mouse ScrollWheel"); //根据鼠标中键变更向量方差值

        distance = Math.Clamp(distance,2.5f,17); //限制distance在2.5-17之间,不至于显示视野失常

        offsetPosition = offsetPosition.normalized * distance; //先将向量变为标准向量,再乘以方差,变成目标距离向量

    }

    在void Upadate( )中调用就可以了。

     2.2 镜头的左右旋转

    思路:读取鼠标在屏幕上X向滑动数值,然后使用tranform.RotateAround()方法使镜头围绕角色旋转即可。脚本如下:

    Namespace FollowPlayer

    public isRotating = false; //声明标识位

    public float rotatespeed = 20;

    void RotateView()

    {

        if( Input.GetMouseDown(1))

        {

            isRotating = true;

        }

        else

        {

            isRotating = false;

        }

        if( isRotating )

        {

            tranform.RotateAround(player.position,Vector3.up,Input.GetAixs("Mouse X")*rotatespeed*Time.deltatime);

            offsetPosition = transform.position - player.position;

            // 注意:此处的重置offsetPosition非常重要,如果不重置offsetPosition,那么当角色固定时,旋转镜头,镜头受限于前期定义的offsetPosition固定,position是不能变得,这样的话镜头只是角度转了,那么显示的状态势必导致主角不在镜头中央。

            //此处可以理解为卫星沿地球运动,不止角度要变,而且位置要变化,但是其需要保持跟地球的相对距离不变,因此,需要刷新卫星于地球向量差;

            //扩展:向量差变化了,并不代表其距离就变化了,现在是要保证其距离不变的情况下,变动其向量差。

        }

    }

    2.3 镜头的上下旋转

    类似的,我们在上述的if(isRotating)块中加入上下旋转的控制语句就可以了,脚本如下:

    if(isRotating)

    {

        transform.RotateAround(palyer.position,player.up,Input.GetAixs("Mouse X")*rotatespeed*Time.deltaTime);

        transform.RotateAround(player.position,transform.right,Input.GetAixs("Mouse Y")*rotatespeed*Time.deltaTime);

        offsetPosition = transform.position - player.position;

        //关于transform.rigth,上下调整镜头其实就是沿某轴去调整相机角度而已。将视图放到2D来看,明显是调整X轴(forward对应Z轴,up对应Y轴,right对应X轴)

        //那么是player的X轴呢,还是镜头的X轴?还是以卫星与地球的模型来想象,初始状态,镜头与角色的X轴是一致的,因此无论如何旋转都可以;

        //但是当镜头左右旋转后呢?它与物体的X轴就不在一线了,如果要求它沿角色的X轴来旋转的话,肯定会连同Z轴一并旋转,这样角色在屏幕就偏斜了

        //反而是镜头沿自身X轴旋转,它在屏幕的投影角度是不变的,因此毫无疑问,应该沿镜头的X轴旋转

    }

    但是这样的话,上下旋转的角度没有限制,是不对的,正如上文提到,上下旋转本质是镜头沿其X轴进行旋转,使X轴规范在一个范围内,注意此处并不能使用Math.Clamp,因为上文说过,镜头的不仅旋转而且还移动了,当旋转受限制了,那么移动还使可以正常移动的,所以需要换一种思路:

        首先记录角色位置及角度信息,如果角度X轴超出范围了,那么返回记录的位置。脚本如下:

    if(isRotating)

    {

        Vector3 originalPosition = transform.position;

        Quaternion originalRotation = transform.rotation;

        transform.RotateAround(palyer.position,player.up,Input.GetAixs("Mouse X")*rotatespeed*Time.deltaTime);

        transform.RotateAround(player.position,transform.right,Input.GetAixs("Mouse Y")*rotatespeed*Time.deltaTime);

        float x = tranform.eulerAugles.x; //读取Rotation的x值

        if(x < 20 || x > 70)

       {

            transform.position = originalPosition;

            transform.rotation = originalRotation;

        }

        offsetPosition = transform.position - player.position;

    }

    这样就可以了。今日的总结到此为止。

  • 相关阅读:
    Unity3d 4.3 通过代码动态更改SpriteRender的Sprite
    使用Unity3D的50个技巧:Unity3D最佳实践
    仿照wtform自定义Form组件
    flask-script
    Django中的信号
    浅淡python中with的用法,上下文管理器
    类和对象的创建过程(元类,__new__,__init__,__call__)
    flask-wtforms
    flask-session组件
    Flask-信号(blinker)
  • 原文地址:https://www.cnblogs.com/yanbenxin/p/5792846.html
Copyright © 2020-2023  润新知