2019年7月25日 自我思考的第一天

本文详细探讨了Unity游戏开发中实现角色搬运箱子功能的步骤与挑战,包括解决箱子虚化、碰撞和射线问题,以及优化旋转速度和相机跟随。作者分享了在3D与2D转化、关卡设计和游戏意义提升方面的思考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天其实是一个激动人心的日子,因为我们要开始我们的创作了,让我们先梳理一下思路。
现在的人物已经能够实现跳跃奔跑和搬运,遇到的敌人也可以通过踩头杀死。
第一个要实现的功能——给搬起来的箱子一个实体,光有力灵魂可没用

不过有一个很难受的bug,其实也不能算是bug,就是在搬起箱子的时候,箱子挂在的grabSocket上,但我们为了让箱子不受其他力的作用,我们将箱子rigid中的kinematic勾选上了,这个选项会让箱箱子处于一个不受其他任何外力作用的状态,这里我们选择禁用一下Kinematic。自己创建了一个bool变量,这个bool变量是用于判断是否举起箱子的,这个时候我们需要将箱子的位置不停刷新,因为箱子可能会受外力,如重力,因此这个时候就需要没一帧的刷新让其与角色的相对位置进行一个重置,即保持每一帧不变。我发现了这里我们在方法中已经用了:

        if (grabObject != null && rotateComplete)
        {
            //如果有抓取物体,且转向完成
            grabObject.transform.SetParent(null);//当前抓取物的父节点设为空
                                                 //--  grabObject.GetComponent<Rigidbody>().isKinematic = false;//非动力学状态
                                                 //  grabObject.GetComponent<Rigidbody>().velocity=playercharacter.rigidbody.
            grabObject = null;//自己设置为空
        }

看到Object为null了么?这里Object就是我们抓取后需要挂在grabSocket上面的物体。即可以直接把这个当作判读用的bool变量:

    protected override void Update()//重载函数
    {
        animator.SetBool("Grab", grabObject ? true : false);
        if (grabObject != null)
        {
            grabObject.transform.localPosition = grabSocket.localPosition;
        }
        base.Update();//调用之后再进行一次主刷新函数
    }

这里丰富了我们进行重载的刷新函数,加入了判断,我们角色的本地位置和抓取物的本地位置进行绑定,可是这里就会出现一些问题。即绑定了位置,箱子就会进行“虚化”,即可以穿过除了同样是GrabBox的所有材质,这会让游戏显得不真实。
这里我想到了一个办法,就是让角色举起箱子的位置做出一下改变,从水平变成竖直。之后用charactercontroller中的类collier属性来对这两个东西进行包裹。随后我发现这其中出现了一些逻辑问题,我会细说,因为每个人的思考方式都独一无二。
1、我选择直接对charactercontroller中的胶囊碰撞collider进行拉伸,变成竖直可以直接装下人和转的长度,但人物的一般行动如跳跃就被最直接的限制了。当然,我也当即想到了相应的解决方法,不过不太可行。就是在人物抓取之前人物的胶囊碰撞范围为人物大小,之后将hight进行改变,想象都是美好的,这里问题就出在,胶囊碰撞的高度改变都伴随着center的改变,中心的变化就会影响射线的射出方向,因此我们搬箱子又受到了影响。就算经过很多修改之后可能达到预想的效果,不过我知道这不是我想要的。
2、我选择多建立一个boxCollider进行拼接,刚开始进行隐藏,在Object不为null即有搬运物的时候取消隐藏用角色本身的collider来包裹物体。这个时候依旧遇到了问题,即一个角色在一般情况下只能拥有一个collider,且其物理材质貌似是charactercontroller优先使用,因此,尽管我设置了位置且没有隐藏,其依旧不影响我创建的角色的碰撞,其碰撞框架也仅仅是原来的胶囊碰撞框架。
3、我对原Character脚本中的Rotate方法中的转动速度进行了更改。调用的地方是在PlayerController中,我将旋转的速度改的非常快即瞬间转身,不然若旋转太慢会出现很多由碰撞引发的bug。
4、相机的修改,原来的相机只是实时接收我们角色的xz轴,下面我们还需要实时接收y轴transform.position.y这有利于我们角色的跟随。这和我们的关卡设计也有关系,我们设置的不是那种玩一张图加载一张图的模式,我们的关卡需要一次加载完毕,内存相对比一张图大,因为我们关卡的转换需要借助位置的移动,也就是说我们的不同关卡是处在不同的位置,因此这个相机的跟随也势必要的。
5、对前一二的总结,并纠正错误,胶囊碰撞并不能决定射出射线的位置,只能影响碰撞体积,射线设置的点和所挂的组件有关,即根节点。这里先将模型和根节点分离调整根节点的中心让其与角色中心对齐,之后对角色的charactercontroller在后台进行调整就好了:

        if (grabObject != null && rotateComplete)
        {
            cc.center = new Vector3(0, 0.05f, 0);
            cc.height = 1.47f;
            //如果有抓取物体,且转向完成
            grabObject.transform.SetParent(null);//当前抓取物的父节点设为空
                                                 //--  grabObject.GetComponent<Rigidbody>().isKinematic = false;//非动力学状态
                                                 //  grabObject.GetComponent<Rigidbody>().velocity=playercharacter.rigidbody.
            grabObject = null;//自己设置为空
        }

这里是扔掉箱子后,人物胶囊碰撞框架的属性。


        else
        {
            //如果没有抓取物
            var dist = cc.radius;
            RaycastHit hit;            
            if (Physics.Raycast(transform.position, transform.forward, out hit, dist + 1f))//位置,方向,输出out,检测半径
            {
                if (hit.collider.CompareTag("GrabBox"))
                {
                    cc.center =new Vector3 (0, 0.41f, 0);
                    cc.height = 2.26f;
                    grabObject = hit.transform;//调取碰撞物的transform字段
                    grabObject.SetParent(grabSocket);//将grabSocket设置为hit的父节idan
                                                     //grabSocket.localPosition=Vector3(this.transform.position.x,,0)
                    grabObject.localPosition = Vector3.zero;//局部位置设定为0,0,0
                    grabObject.localRotation = Quaternion.identity;//旋转坐标(四元数),即指Quaternion(0,0,0,0)
                    //-- grabObject.GetComponent<Rigidbody>().isKinematic = true;//设置射线击中的物体被抓取后不受外力控制,即有固定的位置,由grabSocket决定                
                }
            }
        }

这里是加长版胶囊,箱子的属性不变,用人物本身的控件成功实现了这个功能。哈哈啊哈哈哈哈

6、我想实现在3D与2D之间的转化。网上查了一篇文章,还没有仔细研读

https://blog.youkuaiyun.com/weixin_33691817/article/details/90806398

7、我想设置一关,就像是男人就下一百层一样,不过也有一些不一样,其中也有随机生成的木块和随时间上升的场景。角色一旦超过一个高度就会死亡,当然这里也会有触发条件,我都想好了,就用整体的position来限定其横坐标就好。判断之后再判断是否该死亡。
8、自己找一些比较有趣的音频
9、怎样让游戏变得更加有意义,让大家着实感受到我们参与其中。我决定设置一面墙,在通关的时候可以出现,随着角色的走动,一张张照片浮现,我们曾来过。(感觉会很简单,建立移动的横坐标关于照片旋转的函数,当然要按照顺序调用!!!)

今天没有跟着视频进行学习都是自己在摸索,在思考,真的是好多东西都要自己想办法解决,感谢csdn各位大佬的博客,我找到了很多有用 的东西。我还得学一遍基础,通过项目来增加自己的基础的本末倒置的,尽管我会C#,这毕竟只是一种调用unity方法的用到的语言。加油!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值