2019年7月18日 学习日记

本文详细介绍了一款横版跳跃游戏的开发过程,包括角色控制、动画设置、碰撞检测及死亡逻辑等内容。通过实例讲解如何使用Unity3D进行游戏开发。

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

由于今天没有边看视频边写,事情有一点多,我就在一起总结了。这第三个游戏是横版跳跃游戏,其实仔细想想和第三个游戏差不多,其模型的给予大大降低了我们制作游戏的难度。我会从第一步到最后一步慢慢滤清思路,而不像昨天一样列出重点后写一坨。44:30

  1. 加入材质包

  2. 拉入过关所需台阶,并赋予其不同颜色,tag也要改变,以便于做出区别。游戏的规则是人和台阶不同颜色的时候会死,因此设置触发器也要有相应的判断依据,tag应运而生。

  3. 拉入Player,日常创建PlayerCharacter,且将角色mode拉入,在根目录加上rigiBody和BoxCollider,将BoxCollider和任务较好的重叠。

  4. 创建PlayerCharacter脚本,写入基本方法,如Move、Jump、Die、ChangeColorState等

  5. 由于角色的任何动作都依附于其物理脚本,这里创建各类型变量,并进行连接。如rigiBody、Renderer、Animator

  6. 在移动过程中,速度依旧是原来那么定义,不同的是我们只对x上的速度进行直接的定义,因为我们是横版跳跃游戏,有一个轴的速度是没有用的,另外一个轴的值只和跳跃和下落有关。这里在取到物体的速度后,要点儿出x速度,等式右边也是一样:
    vel.x = (Vector3.left * speed).x;不要忘了创建speed变量来控制速度的大小
    其实这里出现了一些小插曲,因为物体面向方向的问题,我点出的z速度并不是老师点处的z速度,我等效的根据面向方向点出了x轴速度并重新给原物体赋值速度。

  7. 创建Controller脚本,创建PlayerCharacter型变量之后取到此脚本依附组件以调用其方法。在上一个脚本后我们已经写完了move函数,这里就是需要调用move函数让物体动起来

  8. 有的脚本不是在本组件上而是在根节点的组件上,这时候要是想通过创建变量得到这个组件就需要用GetConponentInChildren方法来得到组件。

  9. 我们在运行后发现游戏内的角色有滚动的现象。这个时候我们就要锁定游戏中rigiBody的xyz轴rotate,并锁定z轴,让它稳定的存在于我们所限定的游戏空间内。
    10.这时候为了让静止的标准角色动起来就要创建Animator脚本并在角色的根节点或者创建Anamator脚本的运行组件,直接将run拖到里面,就能让角色跑起来。创建了动画脚本后不要忘了拖入动画控件内哦

  10. 拖入相机,这个相机***比较奇怪。先说基本的,把角色的根组件拖到相机的目标脚本内,这样相机就会跟随。但相机由三个部分组成***,第一部分是不能随意拖动的,这个部分确定了相机和物体的相对关系,第二个部分可以调整相机相对于物体的位置,第三个就是相机本身了。这个比较特殊 ,相机还需要好好看U3d基础,不然还很迷糊

  11. 然后角色会跑了,就要让角色跳起来,因为这个游戏由二段跳的功能,就要对其跳跃次数进行计数,即jumpCount。和判断是否在地面的 isGround

  12. jump函数

    public void Jump()
    {
        if (!isAlive)//判断是否成活
        {
            return;
        }
        if (jumpCount < 2)//限制其最多跳跃两次
        {
            if (jumpCount == 0)//第一次跳跃
            {
                rigid.velocity = new Vector3(rigid.velocity.x, 0, rigid.velocity.z);//其实一般情况下不需要这段代码,这段代码是应对特殊情况用的,主要作用于第二次跳跃。作用是清空y轴速度让其以y轴速度为0为初始条件进行跳跃(AddForce)
                rigid.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);//脉冲型AddForce,并取jumpforce
            }
            else if (jumpCount == 1)
            {
                rigid.velocity = new Vector3(rigid.velocity.x, 0, rigid.velocity.z);//第一段跳后按空格实现第二段跳的时候先让y速度变为零之后以此为基础i进行第二次跳跃
                rigid.AddForce(Vector3.up * doubleForce, ForceMode.Impulse);//第一段和第二段跳的舜力是不同的
            }
            jumpCount++;//跳跃计数变多,超过1则停止跳跃
        }
    }

也不要忘记写完了跳跃方法,要在controller中进行调用,并调用input中的getkeydown来得到我们按下的键盘以此触发方法
13.可是,我们在进行第一次跳跃之后,就不能再进行跳跃。这是因为我们没用清空我们的jumpCount。我们要再Character脚本中写入这个方法:

    private void OnCollisionEnter(Collision collision)
    {
        jumpCount = 0;
        collisionRet = collision;//这个是碰撞物体,在之后用于调用碰撞物体的tag以判断是否应该死亡
    }

14.这里在Character中有个奇怪的方法:Colloder

    public bool GroundCheck()
    {
        Collider[] colliders = Physics.OverlapSphere(transform.position, 0.3f);//0.3f和物体大小有关
        //本函数一旦被调用,将会返回以参数1为原点和参数2为半径的球体内“满足一定条件”的碰撞体集合,此时我们把这个球体称为 3D相交球。
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)//判断跳跃后是否落在同一块台阶上,要是在同一块就不算是落地。跳起来的时候其半径内只有角色本身,因此只有相同的时候才能判断不在地板,只要有有一个不相等就说明多了接触物,即在地板上。
            {
                return true;
            }
        }
        return false;//循环结束后,要是都没有就没有落地
    }

15.继续设置双向Animator控件,创建触发器OnGround,要是跳起来后在空中,OnGround为false则可以判断为跳跃动画。
并在update中写入onGround = GroundCheck(); animator.SetBool("OnGround", onGround);
先判断,再把得到的bool类型变量写入就可以得到想要的动画。这里有一个细节就是在跳跃状态转换为奔跑状态的时候不能勾选 Has Exit Time这一项,要是这一次的跳跃动作没完成,要可能在台阶上完成跳跃动作,多滑稽,所以不要勾选。
16、我们需要通过碰撞结果来判断角色是否死亡,检测是在update中:

private void OnCollisionEnter(Collision collision)
    {
        jumpCount = 0;
        collisionRet = collision;
    }
    private void OnCollisionStay(Collision collision)
    {
        collisionRet = collision;
    }
    private void OnCollisionExit(Collision collision)
    {
        collisionRet = null;
    }

分别表示进入持续和离开,对碰撞触发器进行调整。
在update中进行刷新的判断函数:

private void Update()
    {
        if (!isAlive)
        {
            return;
        }
        if (collisionRet != null)//要是存在碰撞物体
        {
            if (collisionRet.gameObject.CompareTag("Red"))//要是碰撞的台阶标签为红
            {
                if (colorCurrent != TransColor.Red)//要是角色的颜色不为红色
                {
                    Die();//死亡
                }
            }
            else if (collisionRet.gameObject.CompareTag("Green"))
            {
                if (colorCurrent != TransColor.Green)
                {
                    Die();
                }
            }
            else//碰到黑色的
            {
                Die();
            }
        }
        onGround = GroundCheck();
        animator.SetBool("OnGround", onGround);
    }

17、死亡函数的书写:

    public void Die()
    {
        isAlive = false;
        render.enabled = false;//停止对角色的渲染
        rigid.velocity = Vector3.zero;//速度清零
        Invoke("Restart", 2);//几秒后执行这个项目
    }
    public void Restart()//重新开始
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene("Start");//调用
    }

判断死亡的标志:public bool isAlive;
要记着在所有动作的前面都要判断是否死亡。
判断本身色彩变化的逻辑:

    public void ChangeColorState()
    {
        if (!isAlive)
        {
            return;
        }
        if (colorCurrent==TransColor.Red)//本体颜色为红色
        {
            colorCurrent = TransColor.Green;//本体颜色变为绿色
            render.material.color = Color.green;//渲染材质变为绿色
        }
        else if (colorCurrent==TransColor.Green)
        {
            colorCurrent = TransColor.Red;
            render.material.color = Color.red;
        }
        animator.SetTrigger("ChangeColor");//触发animator中的ChangeColor触发器
    }

加入死亡特效:public ParticleSystem dieParticle;//粒子特效,在唤醒的时候stop的时候play

在砖块中可以加movepoint脚本,让砖块上下移动,嘿嘿嘿。这里需要注意的是因为上下移动需要两个目标点,来回平移,目标点是以tag来判断的,需要创建两个组件放在scene中当作Waypoint。因此要创建新的Waypoint标签,不过这都是根据给出的脚本写出的。

最后再复习一下,怎么插入音乐
首先实例化控件:public AudioClip PickMusic;
再在需要插入声音的脚本或者直接唤醒播放音乐:

 AudioSource.PlayClipAtPoint(PickMusic, transform.position);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值