CPP组技术分享——UNITY角色移动与视角控制方法论

Hoji 2022-10-18 20:49:01

目录

 

unity中的坐标

人物移动与视角控制

1.基于3D的2D横板游戏

2.第三人称或第一人称视角3D游戏

3.俯视角游戏


unity中的坐标

在介绍具体的方法前我们先来了解一下unity中的坐标,unity的坐标采用的是左手坐标轴而不是我们常见的右手坐标轴,

 

 unity中的世界坐标系类比于地球的经纬度,可以确定一个物体在世界中的位置,而物体的自身坐标系则是以这个物体为原点建立的坐标系,在控制物体移动的过程中我们会更多的用到物体的自身坐标系

人物移动与视角控制

我们这次只考虑控制器为“键盘+鼠标”的组合,手柄等控制器不在考虑范围内,在撰写控制人物移动和视角控制的脚本前,我们通过对游戏玩法的设想,将人物的移动大致分为以下几种类型

1.基于3D的2D横板游戏

虽然unity也提供2D游戏的开发工具和开发模板,但本次只涉及3D部分的内容,在整体游戏为3D的情况下采用2D视角的横向卷轴游戏做到了一种伪2D,自3D游戏诞生以来,采用此种方式开发的卷轴游戏不在少数,如《新超级马里奥兄弟》《星之卡比 Wii》等

 同样的,在考虑人物移动与视角控制时我们仍按照开发2D游戏的思路即可,只获取X轴方向上的控制器信号,并为人物加上X轴方向的力

    public Rigidbody rd;
    void Start()
    {
        rd = GetComponent<Rigidbody>();
    }
    void Update()
    {
        float h = Input.GetAxis("Horizontal");//'A''D'控制水平方向移动
        rd.AddForce(new Vector3(h, 0, 0));
    }

撰写控制跳跃的代码

    private bool grounded;//定义一个变量用于判定是否接地,毕竟我们不能让人物左脚踩右脚上天(
    void Start()
    {
        grounded = true;//默认接地
    }
    void Update()
    {
        if (Input.GetButtonDown("Jump"))//对应键盘的空格
        {
            if (grounded == true)//接地判定
            {
                rd.velocity += new Vector3(0, 5, 0);
                rd.AddForce(Vector3.up * 50);
                grounded = false;//更改控制变量,如果希望角色能二段跳也可以通过此变量控制
            }
        }
    }
    void OnTriggerEnter(Collider other)
    {
            grounded = true;//接地后更改控制变量
    }

视角控制脚本只需要摄像机固定跟随人物移动即可

    public Transform playerTransform;
    private Vector3 offset;
    void Start()
    {
        offset = transform.position - playerTransform.position;//计算摄像机与人物位置的偏移
    }
    void Update()
    {
        transform.position = playerTransform.position + offset;//改变摄像机位置
    }

2.第三人称或第一人称视角3D游戏

第一人称与第三人称的区别取决于我们摄像机的摆放,与脚本无关,在撰写脚本时的关注点是视角旋转与视角跟随

第一种方法同上,只需要补上Z轴方向的控制即可,但要控制角色的转向(角色朝向)需要另外撰写脚本

    void Update()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");//'W''S'控制垂直方向移动(前进后退)
        rd.AddForce(new Vector3(h, 0, v));
    }

第二种方法,我们让W、S控制角色前进后退,用A、D控制人物转向,这种控制逻辑在赛车游戏上较为常见

    void Update()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        transform.Translate(Vector3.forward * Time.deltaTime * v, Space.Self);
        transform.Rotate(Vector3.up * Time.deltaTime * h * 60, Space.Self);
	}

再考虑回视角控制,如果我们不想使用固定视角,那么最好的办法是让视角随着鼠标移动

    public enum RotationAxes
    { 
        MouseXAndY = 0,
        MouseX = 1,
        MouseY = 2 
    }
    public RotationAxes axes = RotationAxes.MouseXAndY;
    public float sensitivityX = 15F;
    public float sensitivityY = 15F;

    public float minimumX = -360F;
    public float maximumX = 360F;//水平方向视角控制,数字是限制的角度

    public float minimumY = -60F;
    public float maximumY = 60F;//垂直方向视角控制,数字是限制的角度

    float rotationY = 0F;

    void Start()
    {
        if (GetComponent<Rigidbody>())
            GetComponent<Rigidbody>().freezeRotation = true;//防止刚体影响镜头旋转
    }

    void Update()
    {
        if (axes == RotationAxes.MouseXAndY)
        {
            float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;

            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
        }
        else if (axes == RotationAxes.MouseX)
        {
            transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
        }
        else
        {
            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp(rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
        }
    }

3.俯视角游戏

 俯视角的游戏,如LOL,大都考虑让角色移动到鼠标点击位置的控制逻辑,要实现这一逻辑并不难,实际上unity为我们提供了一套导航系统,只需用导航系统烘焙出导航网格,再给人物加上NavMeshAgent组件就可以实现自动寻路

 

using UnityEngine.AI;//记得加上这个

    public NavMeshAgent agent;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//在鼠标点击处发射一条由屏幕坐标发出的射线
            RaycastHit hit;//记录下射线映射的位置
            if(Physics.Raycast(ray, out hit))
            {
                agent.SetDestination(hit.point);//寻路
            }
        }
    }

 

...全文
230 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,040

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学CSDN高校俱乐部聚焦校内IT技术爱好者,通过构建系统化的内容和运营体系,旨在将中南民族大学CSDN社区变成校内最大的技术交流沟通平台。
经验分享 高校 湖北省·武汉市
社区管理员
  • c_university_1575
  • WhiteGlint666
  • wzh_scuec
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

欢迎各位加入中南民族大学&&CSDN高校俱乐部社区(官方QQ群:908527260),成为CSDN高校俱乐部的成员具体步骤(必填),填写如下表单,表单链接如下:
人才储备数据库及线上礼品发放表单邀请人吴钟昊:https://ddz.red/CSDN
CSDN高校俱乐部是给大家提供技术分享交流的平台,会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接,希望大家一起努力加油!共同建设中南民族大学良好的技术知识分享社区。

注意:

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台,可以相互探讨、交流学习经验,尽量不在社区谈论其他无关话题。

试试用AI创作助手写篇文章吧