【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)

03-03 2226阅读 0评论

需要源码和资源文件请点赞关注收藏后评论区留言私信~~~

下面我们将实现一个3D游戏 跑酷小子 类似于之前大火的神庙逃亡 效果展示和代码在文章末尾 下面为实现步骤

一、前期准备

在项目开始前 需要新建项目 将模型资源导入 模型资源存放在资源文件夹中

新建项目 注意选择3D模板 导入后如下图

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第1张

ParkourDemoModel.unitypackage是主角模型资源 RoadModel.unitypackage是路段及障碍物模型资源 将这两个资源包依次导入 全部导入后目录结构如下

 【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第2张

二、路段设置

 在Project视图中的Models->SimpleRoadwoek->Prefabs文件夹中 可以找到需要的各类模型,包括路面 路标 障碍物等等 接下来我们进行路段摆放

将路段拖入Scenes视图后 进行复制摆放到镜像位置,然后复制十次依次摆放形成路面 效果如下

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第3张

接下来在路面上摆放装饰物,读者可以按照自己的想法摆放 接着做一面特殊的墙,用来检测玩家是否到达路段的中端,如果玩家到达路段中端,就切换路段,切换的逻辑会在后面实现

然后把上述资源全部放在一个对象下然后复制两次,并且设置另外两个对象的开始值,分别是50,0,0和100,0,0 这样总共有三条路段拼接在一起 

三、障碍物设置

只有路段 我们还需要在上面摆放障碍物来增加难度

读者可以自行根据喜好摆放 效果如下图

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第4张

接着我们将障碍物拖入一个物体下面进行复制 跟上面路段的操作类似 复制到后面的路段上

 【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第5张

四、主角设置

接下来就是最重要的主角设置,包括对模型的设置 动画切换 主角的移动和摄像机的跟随等等

 将主角模型直接拖入Scenes视图中即可,接着设置主角动画,在Project视图中右击 选择Create-

> Animator Control命令  新建一个动画控制器 把主角的动画控制逻辑弄好 如下图所示

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第6张

接下来还要设置主角移动 主角死亡判定以及摄像机跟随等等业务逻辑 由于用代码控制 此处不再赘述

五、效果展示

 运行程序 3D游戏效果如下

可以看到场景十分逼真 读者可以根据自己喜好进行修改

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第7张

 【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细) 第8张

 六、代码

部分代码如下

1

using System.Collections.Generic;
using UnityEngine;
public class Control_Scenes : MonoBehaviour
{
    //是否到达第一段路
    bool m_ISFirst;
    //所有的路段对象
    public GameObject[] m_RoadArray;
    //障碍物数组对象
    public GameObject[] m_ObstacleArray;
    //障碍物的位置
    public List m_ObstaclePosArray = new List();
    void Start()
    {
        //游戏开始自动生成3组障碍物
        for (int i = 0; i  

2

using UnityEngine;
public class Control_Player : MonoBehaviour
{
    //前进速度
    public float m_ForwardSpeeed = 7.0f;
    //动画组件
    private Animator m_Anim;
    //动画现在状态
    private AnimatorStateInfo m_CurrentBaseState;
    //动画状态参照
    static int m_jumpState = Animator.StringToHash("Base Layer.jump");
    static int m_slideState = Animator.StringToHash("Base Layer.slide");
    void Start()
    {
        //获得主角身上的Animator组件
        m_Anim = GetComponent();
    }
    void Update()
    {
        //主角向前跑
        transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
        //获得现在播放的动画状态
        m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
        if (Input.GetKeyDown(KeyCode.W))
        {
            m_Anim.SetBool("jump", true);//切换跳状态
        }
        else if (Input.GetKeyDown(KeyCode.S))
        {
            m_Anim.SetBool("slide", true);//切换下滑状态
        }
        else if (Input.GetKeyDown(KeyCode.A))
        {
            Change_PlayerZ(true);//移动主角向左移动
        }
        else if (Input.GetKeyDown(KeyCode.D))
        {
            Change_PlayerZ(false);//移动主角向右移动
        }
        if (m_CurrentBaseState.fullPathHash == m_jumpState)
        {
            m_Anim.SetBool("jump", false);//改变动画状态
        }
        else if (m_CurrentBaseState.fullPathHash == m_slideState)
        {
            m_Anim.SetBool("slide", false);//改变动画状态
        }
    }
    public void Change_PlayerZ(bool IsAD)
    {
        if (IsAD)//当按下键盘的A 也就是向左移动
        {
            //主角在最左边
            if (transform.position.z == -5f)
                return;
            //主角在中间
            else if (transform.position.z == -10f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
            }
            //主角在最右边
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
            }
        }
        else//当按下键盘的D 也就是向右移动
        {
            //主角在最右边
            if (transform.position.z == -15f)
                return;
            //主角在中间
            else if (transform.position.z == -10f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
            }
            //主角在最左边
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
            }
        }
    }
}

3

using UnityEngine;
using UnityEngine.SceneManagement;
public class Control_Player : MonoBehaviour
{
    //前进速度
    public float m_ForwardSpeeed = 7.0f;
    //动画组件
    private Animator m_Anim;
    //动画现在状态
    private AnimatorStateInfo m_CurrentBaseState;
    //动画状态参照
    static int m_jumpState = Animator.StringToHash("Base Layer.jump");
    static int m_slideState = Animator.StringToHash("Base Layer.slide");
    void Start()
    {
        //获得主角身上的Animator组件
        m_Anim = GetComponent();
    }
    void Update()
    {
        //主角向前跑
        transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
        //获得现在播放的动画状态
        m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
        if (Input.GetKeyDown(KeyCode.W))
        {
            m_Anim.SetBool("jump", true);//切换跳状态
        }
        else if (Input.GetKeyDown(KeyCode.S))
        {
            m_Anim.SetBool("slide", true);//切换下滑状态
        }
        else if (Input.GetKeyDown(KeyCode.A))
        {
            Change_PlayerZ(true);//移动主角向左移动
        }
        else if (Input.GetKeyDown(KeyCode.D))
        {
            Change_PlayerZ(false);//移动主角向右移动
        }
        if (m_CurrentBaseState.fullPathHash == m_jumpState)
        {
            m_Anim.SetBool("jump", false);//改变动画状态
        }
        else if (m_CurrentBaseState.fullPathHash == m_slideState)
        {
            m_Anim.SetBool("slide", false);//改变动画状态
        }
        if (m_IsEnd && Input.GetKeyDown(KeyCode.F1))
        {
            //重新开始游戏
            SceneManager.LoadScene(0);
        }
    }
    public void Change_PlayerZ(bool IsAD)
    {
        if (IsAD)//当按下键盘的A 也就是向左移动
        {
            //主角在最左边
            if (transform.position.z == -5f)
                return;
            //主角在中间
            else if (transform.position.z == -10f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
            }
            //主角在最右边
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
            }
        }
        else//当按下键盘的D 也就是向右移动
        {
            //主角在最右边
            if (transform.position.z == -15f)
                return;
            //主角在中间
            else if (transform.position.z == -10f)
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
            }
            //主角在最左边
            else
            {
                transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
            }
        }
    }
    //游戏结束
    bool m_IsEnd = false;
    void OnGUI()
    {
        if (m_IsEnd)
        {
            GUIStyle style = new GUIStyle();
            style.alignment = TextAnchor.MiddleCenter;
            style.fontSize = 40;
            style.normal.textColor = Color.red;
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100), "你输了~点击F1重新开始游戏", style);
        }
    }
    void OnTriggerEnter(Collider other)
    {
        //主角如果碰撞到障碍物
        if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
        {
            m_IsEnd = true;
            m_ForwardSpeeed = 0;
            m_Anim.SetBool("idle", true);
        }
    }
}

创作不易 觉得有帮助请点赞关注收藏~~~


免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,2226人围观)

还没有评论,来说两句吧...

目录[+]