返回首页DA系统C#IDE文件同步服务屏保 今天是: 2026-05-05    "立夏"  夏季的第一个节气,表示盛夏时节的正式开始

搜索
热搜: linux 技术
Hi~登录注册
查看: 2185|回复: 0

[原创] 【原创】三维数学练习--根据用户输入的方向(使用键盘虚拟按钮)旋转物体,并向前移动

[复制链接]
发表于 2021-9-7 12:34:30 | 显示全部楼层 |阅读模式
本帖最后由 da11 于 2021-9-7 13:01 编辑

    //小练习:根据用户输入的方向(使用键盘虚拟按钮)旋转物体,并向前移动

    //==========================================================================
    //自做练习代码:
    /*

    private float speedF;  //旋转速度变量

    private float speedWalk;   //移动速度变量

    private float HorizontalCache = 0;   //InputManager左右移动缓存值

    private float VerticalCache = 0;     //InputManager上下移动缓存值

    private void Start()
    {
        //赋值各移动速度
        speedF = 1F;

        speedWalk = 0.01F;
    }

    private void Update()
    {
        //左右旋转并左右移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Horizontal"))  //检测虚拟按钮Horizontal,对应的绑定按键为d、a、小键盘右、小键盘左
        {
            //平面左右旋转,欧拉角使用的是y轴!!
            //Debug.Log(HorizontalCache - Input.GetAxis("Horizontal"));

            //判定InputManager左右移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按a键向左,按钮移动值则往 -1 相减,按d键向右,按钮移动值则往 1 相加。
            //既,向左按按钮a键,0 -(-1),肯定大于0,由此判断应该向右旋转。
            //既,向右按按钮a键,0 -(1),肯定小于0,由此判断应该向左旋转。
            if (HorizontalCache - Input.GetAxis("Horizontal") > 0)
            {
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 270, 0);  

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 270, 0), 0.1f);
            }
            else
            {
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, -270, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, -270, 0), 0.1f);
            }

            //使用Translate方法,参数Vector3.forward,乘上移动速度变量值,使物体移动
            this.transform.Translate(Vector3.forward * speedWalk);
        }

        //前后旋转并前后移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Vertical"))  //检测虚拟按钮Vertical,对应的绑定按键为s、w、小键盘下、小键盘上
        {
            //平面前后旋转,Vector3坐标使用的是y轴!!

            //判定InputManager前后移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按w键向前,按钮移动值则往 -1 相减,按s键向后,按钮移动值则往 1 相加。
            //既,向前按按钮w键,0 -(-1),肯定大于0,由此判断应该向前旋转。
            //既,向后按按钮s键,0 -(1),肯定小于0,由此判断应该向后旋转。
            if (VerticalCache - Input.GetAxis("Vertical") > 0)
            {
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 180, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 180, 0), 0.1f);
            }
            else
            {
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 0, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 0, 0), 0.1f);
            }

            //使用Translate方法,参数Vector3.forward,乘上移动速度变量值,使物体移动
            this.transform.Translate(Vector3.forward * speedWalk);
        }
    }
//代码演示图,图片较大,加载速度较慢,请耐心等候



    */

    //==========================================================================

    //案例教学方法:

    private float speedF = 0.1F;  //旋转速度变量

    private float speedWalk = 0.01F;   //移动速度变量

    private float HorizontalCache;   //InputManager左右移动缓存值

    private float VerticalCache;     //InputManager上下移动缓存值



    private void Update()
    {
        HorizontalCache = Input.GetAxis("Horizontal");
        VerticalCache = Input.GetAxis("Vertical");
        rotianFF(HorizontalCache, VerticalCache);

        if (HorizontalCache != 0 || VerticalCache != 0)
        {
            this.transform.Translate(Vector3.forward * speedF);
        }


    }

    private void rotianFF(float hor,float ver)
    {
        Quaternion rotainFX = Quaternion.LookRotation(new Vector3(hor, 0, ver));
        this.transform.rotation = Quaternion.Lerp(this.transform.rotation, rotainFX, speedF);
    }

//代码演示图,图片较大,加载速度较慢,请耐心等候



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
 楼主| 发表于 2021-9-13 18:33:28 | 显示全部楼层
本帖最后由 da11 于 2021-9-25 17:06 编辑

//补充:坐标系练习1:在1楼代码的基础上,增加要求:如果超出屏幕,停止运动,并可以向相反方向运动。



//练习相机位置图示:

    private Camera cameraVar;   //存放相机类型变量

    Vector3 ScreenVar;          //存放屏幕坐标系的值变量

    private float speedF;  //旋转速度变量

    private float speedWalk;   //移动速度变量

    private float HorizontalCache = 0;   //InputManager左右移动缓存值

    private float VerticalCache = 0;     //InputManager上下移动缓存值

    private bool RightBool = true;      //右方向状态值--练习1变量

    private bool leftBool = true;       //左方向状态值--练习1变量

    private bool GoBool = true;         //前进方向状态值--练习1变量

    private bool BackBool = true;       //后退方向状态值--练习1变量


    private void Start()
    {
        //赋值各移动速度
        speedF = 1F;

        speedWalk = 0.1F;

        //Camera.main为获取主相机的方法,相机中的标签必须为MainCamera才能使用此方法,否则请使用另外的获取相机的方法!
        cameraVar = Camera.main;



        //物体自身position世界坐标转换成摄像机坐标并赋值 Vector3类型 的 ScreenVar变量
        ScreenVar = cameraVar.WorldToViewportPoint(this.transform.position);

    }

    private void Update()
    {
        //判断屏幕坐标,防止越界移动--坐标系练习!!------------------------------------
        //练习1:如果超出屏幕,停止运动,并可以向相反方向运动。
        //练习2;左边越界了,立马在右边回来,反之,右边越界了,立马在左边回来。上下同理。

        //左右旋转并左右移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Horizontal"))  //检测虚拟按钮Horizontal,对应的绑定按键为d、a、小键盘右、小键盘左
        {
            //平面左右旋转,欧拉角使用的是y轴!!
            //Debug.Log(HorizontalCache - Input.GetAxis("Horizontal"));

            //判定InputManager左右移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按a键向左,按钮移动值则往 -1 相减,按d键向右,按钮移动值则往 1 相加。
            //既,向左按按钮a键,0 -(-1),肯定大于0,由此判断应该向右旋转。
            //既,向右按按钮a键,0 -(1),肯定小于0,由此判断应该向左旋转。
            if (HorizontalCache - Input.GetAxis("Horizontal") > 0)   //左转
            {
                //Debug.Log("左转");

                //状态互锁互解开逻辑代码,左转的时候,右转状态为可用状态。
                RightBool = true;


                //Debug.Log(Input.GetAxis("Horizontal"));

                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 270, 0);

                ////变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 270, 0), 0.1f);

                //左转状态可用时才可以移动
                if (leftBool == true)

                {
                    //根据速度匀速前进
                    this.transform.Translate(Vector3.forward * speedWalk);
                }

            }
            else if (HorizontalCache - Input.GetAxis("Horizontal") < 0) //Input.GetAxis("Horizontal") < 0 右转
            {
                //Debug.Log("右转");

                //状态互锁互解开逻辑代码,右转的时候,左转状态为可用状态。
                leftBool = true;


                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, -270, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, -270, 0), 0.1f);

                //右转状态可用时才可以移动
                if (RightBool == true)
                {
                    //根据速度匀速前进
                    this.transform.Translate(Vector3.forward * speedWalk);
                }


            }

            //转向状态可用控制中枢
            if (ScreenVar.x < 0.1)      //摄像机坐标的x轴小于0.1,左转可用状态即为false
            {
                leftBool = false;
            }
            else if (ScreenVar.x > 0.9) //摄像机坐标的x轴大于0.9,右转可用状态即为false
            {
                RightBool = false;
            }     
     

        }

        //前后旋转并前后移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Vertical"))  //检测虚拟按钮Vertical,对应的绑定按键为s、w、小键盘下、小键盘上
        {
            //Debug.Log(Input.GetAxis("Vertical"));
            //平面前后旋转,Vector3坐标使用的是y轴!!

            //判定InputManager前后移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按w键向前,按钮移动值则往 -1 相减,按s键向后,按钮移动值则往 1 相加。
            //既,向前按按钮w键,0 -(-1),肯定大于0,由此判断应该向前旋转。
            //既,向后按按钮s键,0 -(1),肯定小于0,由此判断应该向后旋转。
            if (VerticalCache - Input.GetAxis("Vertical") > 0)    //后退
            {
                //状态互锁互解开逻辑代码,向后转的时候,向前转状态为可用状态。
                GoBool = true;


                //Debug.Log("后退");
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 180, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 180, 0), 0.1f);

                //向后转状态可用时才可以移动
                if (BackBool == true)
                {
                    this.transform.Translate(Vector3.forward * speedWalk);
                }

            }
            else if (VerticalCache - Input.GetAxis("Vertical") < 0)   //Input.GetAxis("Vertical") < 0  前进
            {
                //状态互锁互解开逻辑代码,向前转的时候,向后转状态为可用状态
                BackBool = true;


                //Debug.Log("前进");
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 0, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 0, 0), 0.1f);

                //向前转状态可用时才可以移动
                if (GoBool == true)
                {
                    //根据速度匀速前进
                    this.transform.Translate(Vector3.forward * speedWalk);
                }

            }

            //转向状态可用控制中枢
            if (ScreenVar.y < 0.15)     //摄像机坐标的y轴小于0.15,向后转可用状态即为false
            {
                BackBool = false;
            }
            else if (ScreenVar.y > 0.9) //摄像机坐标的y轴大于0.9,向前转可用状态即为false
            {
                GoBool = false;
            }

        }

    }


//练习动图展示,动图较大,请耐心等待






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-15 18:44:57 | 显示全部楼层
本帖最后由 da11 于 2021-9-25 17:08 编辑

//补充:坐标系练习2:在1楼代码的基础上,增加要求:左边越界了,立马在右边回来,反之,右边越界了,立马在左边回来。上下同理。   


    //自做练习代码:

    private Camera cameraVar;   //存放相机类型变量

    Vector3 ScreenVar;          //存放屏幕坐标系的值变量

    private float speedF;  //旋转速度变量

    private float speedWalk;   //移动速度变量

    private float HorizontalCache = 0;   //InputManager左右移动缓存值

    private float VerticalCache = 0;     //InputManager上下移动缓存值

    private bool RightBool = true;      //右方向状态值--练习1变量

    private bool leftBool = true;       //左方向状态值--练习1变量

    private bool GoBool = true;         //前进方向状态值--练习1变量

    private bool BackBool = true;       //后退方向状态值--练习1变量


    private void Start()
    {
        //赋值各移动速度
        speedF = 1F;

        speedWalk = 0.1F;

        //Camera.main为获取主相机的方法,相机中的标签必须为MainCamera才能使用此方法,否则请使用另外的获取相机的方法!
        cameraVar = Camera.main;

        //物体自身position世界坐标转换成摄像机坐标并赋值 Vector3类型 的 ScreenVar变量
        ScreenVar = cameraVar.WorldToViewportPoint(this.transform.position);

    }


    private void Update()
    {


        //判断屏幕坐标,防止越界移动--坐标系练习!!------------------------------------
        //练习2;左边越界了,立马在右边回来,反之,右边越界了,立马在左边回来。上下同理。

        //左右旋转并左右移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Horizontal"))  //检测虚拟按钮Horizontal,对应的绑定按键为d、a、小键盘右、小键盘左
        {
            //平面左右旋转,欧拉角使用的是y轴!!
            //Debug.Log(HorizontalCache - Input.GetAxis("Horizontal"));

            //判定InputManager左右移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按a键向左,按钮移动值则往 -1 相减,按d键向右,按钮移动值则往 1 相加。
            //既,向左按按钮a键,0 -(-1),肯定大于0,由此判断应该向右旋转。
            //既,向右按按钮a键,0 -(1),肯定小于0,由此判断应该向左旋转。
            if (HorizontalCache - Input.GetAxis("Horizontal") > 0)   //左转
            {
                //Debug.Log("左转");

                //Debug.Log(Input.GetAxis("Horizontal"));

                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 270, 0);

                ////变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 270, 0), 0.1f);

                this.transform.Translate(Vector3.forward * speedWalk);

            }
            else if (HorizontalCache - Input.GetAxis("Horizontal") < 0) //Input.GetAxis("Horizontal") < 0 右转
            {
                //Debug.Log("右转");

                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, -270, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, -270, 0), 0.1f);

                this.transform.Translate(Vector3.forward * speedWalk);

            }

            //转向状态可用控制中枢
            if (ScreenVar.x < 0.1)      //摄像机坐标的x轴小于0.1,左转可用状态即为false
            {
                Vector3 ZXZT = Camera.main.ViewportToWorldPoint(new Vector3(0.85F, ScreenVar.y, ScreenVar.z));
                this.transform.position = new Vector3(ZXZT.x,ZXZT.y,ZXZT.z);
            }
            else if (ScreenVar.x > 0.9) //摄像机坐标的x轴大于0.9,右转可用状态即为false
            {
                //RightBool = false;
                Vector3 ZXZT = Camera.main.ViewportToWorldPoint(new Vector3(0.15F, ScreenVar.y, ScreenVar.z));
                this.transform.position = new Vector3(ZXZT.x, ZXZT.y, ZXZT.z);
            }

        }

        //前后旋转并前后移动,实现方案,先使物体旋转,再使用this.transform.Translate使物体前进
        if (Input.GetButton("Vertical"))  //检测虚拟按钮Vertical,对应的绑定按键为s、w、小键盘下、小键盘上
        {
            //Debug.Log(Input.GetAxis("Vertical"));
            //平面前后旋转,Vector3坐标使用的是y轴!!

            //判定InputManager前后移动缓存值与实际按钮移动值相减是否大于0
            //比如不按按钮的时候按钮移动值为0,按w键向前,按钮移动值则往 -1 相减,按s键向后,按钮移动值则往 1 相加。
            //既,向前按按钮w键,0 -(-1),肯定大于0,由此判断应该向前旋转。
            //既,向后按按钮s键,0 -(1),肯定小于0,由此判断应该向后旋转。
            if (VerticalCache - Input.GetAxis("Vertical") > 0)    //后退
            {

                //Debug.Log("后退");
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 180, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 180, 0), 0.1f);


                this.transform.Translate(Vector3.forward * speedWalk);

            }
            else if (VerticalCache - Input.GetAxis("Vertical") < 0)   //Input.GetAxis("Vertical") < 0  前进
            {
                //Debug.Log("前进");
                //直接瞬移旋转,实际案例不可取
                //this.transform.rotation = Quaternion.Euler(0, 0, 0);

                //变速旋转,实际案例常用案例
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 0, 0), 0.1f);


                //根据速度匀速前进
                this.transform.Translate(Vector3.forward * speedWalk);

            }

            //转向状态可用控制中枢
            if (ScreenVar.y < 0.1)     //摄像机坐标的y轴小于0.15,向后转可用状态即为false
            {
                Vector3 ZXZT = Camera.main.ViewportToWorldPoint(new Vector3(ScreenVar.x, 0.85F, ScreenVar.z));
                this.transform.position = new Vector3(ZXZT.x, ZXZT.y, ZXZT.z);
            }
            else if (ScreenVar.y > 0.9) //摄像机坐标的y轴大于0.9,向前转可用状态即为false
            {
                Vector3 ZXZT = Camera.main.ViewportToWorldPoint(new Vector3(ScreenVar.x, 0.15F, ScreenVar.z));
                this.transform.position = new Vector3(ZXZT.x, ZXZT.y, ZXZT.z);
            }
        }


    }



//案例演示动图,图片较大,请耐心等待:










本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
回复 支持 反对

使用道具 举报

游客
回复
*滑块验证:

DA论坛飞机票来了~
快速回复 返回顶部 返回列表