linux下跑酷游戏编程,【Unity3D开发小游戏】《跑酷小游戏》Unity开发教程

2023-10-19 14:30

本文主要是介绍linux下跑酷游戏编程,【Unity3D开发小游戏】《跑酷小游戏》Unity开发教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

最近跑酷游戏比较流行,开发教程也很多,但是大部分都是不太详细,这篇文章就带着大家一步一步开发出来一个跑酷类的游戏,教程比较基础,适合大部分Unity开发的初学者。

还有就是,此专栏已经开通收费,里面整合的都是小游戏的开发教程,想要学习Unity开发游戏的,都可以订阅一下。

如果文章出现什么问题,就及时联系我

二、效果图&下载链接

f43358d02094

在这里插入图片描述

Github地址:https://github.com/764424567/Game_Parkour

三、教程

在教程开始之前,我们分析一下跑酷类游戏制作思路。

首先是道路和障碍物,我们可以先设置三段道路,然后障碍物随机生成

道路中间有抵达点,角色到达抵达点判断是否将后面的道路移动到前面接起来。

首先到达第一段的抵达点,肯定是不切换

到达第二段的抵达点,将1号路段移动到最前面

到达第三段的抵达点,将2号路段移动到最前面

循环往复,无穷尽也

然后是主角的移动脚本,躲避障碍物,移动位置固定三个点,可以跳,可以铲地

主角碰到障碍物就挂,游戏结束

1、新建项目

博主的Unity版本是Unity5.6.1f1,推荐大家使用我这个版本,或者其他的5.6.x版本,不然可能会出现各种各样奇奇怪怪的问题。

f43358d02094

在这里插入图片描述

文件目录的话就按照我这个目录来,比较清晰明了。

2、导入资源

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

3、处理动画资源

f43358d02094

在这里插入图片描述

可以看到所有的动画文件都有。

接着我们就可以新建一个Animator Controller文件来管理动画文件。

f43358d02094

在这里插入图片描述

命名随意。

f43358d02094

在这里插入图片描述

接着我们将动画剪辑拖到Animator处理面板中:

f43358d02094

在这里插入图片描述

默认状态是run,然后有jump 、slide、idle

f43358d02094

在这里插入图片描述

接着就是“Take Transition”将run和jump 以及 run 、slide、idle连下线。

设置两个bool值,来控制动画的切换:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

接下来我们就可以在场景中看一下动画效果了:

f43358d02094

在这里插入图片描述

4、处理路段模型

f43358d02094

在这里插入图片描述

首先我们找到导入的资源SimpleRoadwork,里面有一个Demo场景,点进去可以看一下各类模型:

f43358d02094

在这里插入图片描述

在Prefabs文件夹中,可以找到我们需要的各类模型,包括路面、路标、障碍物:

f43358d02094

在这里插入图片描述

接下来,我们就设计一下路面:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

接着摆放路标:

f43358d02094

在这里插入图片描述

接着摆放障碍物:

f43358d02094

在这里插入图片描述

因为障碍物我们要后期自动生成,现在就可以先隐藏起来。

f43358d02094

在这里插入图片描述

然后设置到达点(到达点的目的是当角色到达这个位置的时候,自动切换路线):

f43358d02094

在这里插入图片描述

隐藏它的Mesh Renderer ,将BoxCollider IsTrigger设置成true:

f43358d02094

在这里插入图片描述

路段就完成了:

f43358d02094

在这里插入图片描述

整个目录如下:

f43358d02094

在这里插入图片描述

不会摆放也没有关系,我已经设置好了,用我的也行。

5、主角模型处理

f43358d02094

在这里插入图片描述

明显是有点大,我们给它同比例缩小一下:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

接着设置一下摄像机的视角:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

6、生成障碍物

新建脚本Control_Scenes.cs

我们首先来生成障碍物:

using UnityEngine;

public class Control_Scenes : MonoBehaviour

{

public GameObject[] m_ObstacleArray;

public Transform[] m_ObstaclePosArray;

void Start()

{

Spawn_Obstacle(1);

}

//生成障碍物

public void Spawn_Obstacle(int index)

{

//销毁原来的对象

GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index);

for (int i = 0; i < obsPast.Length; i++)

{

Destroy(obsPast[i]);

}

//生成障碍物

foreach (Transform item in m_ObstaclePosArray[index])

{

GameObject prefab = m_ObstacleArray[Random.Range(0, m_ObstacleArray.Length)];

Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);

GameObject obj = Instantiate(prefab, item.position, Quaternion.Euler(eulerAngle));

obj.tag = "Obstacle" + index;

}

}

}

将脚本挂在Control_Scenes对象上:

将Prefab文件夹里面的模型拖入到ObstacleArray对象数组卡槽中

将隐藏以后的障碍物拖入到ObstaclePosArray对象数组卡槽中

f43358d02094

在这里插入图片描述

添加Tag:

f43358d02094

在这里插入图片描述

运行看一下:

f43358d02094

在这里插入图片描述

7、路段切换

我们接着打开Control_Scenes.cs

添加函数:

void Start()

{

//Spawn_Obstacle(1);

Change_Road(1);

}

public void Change_Road(int index)

{

if (m_ISFirst && index == 0)

{

m_ISFirst = false;

return;

}

else

{

int lastIndex = index - 1;

if (lastIndex < 0)

lastIndex = 2;

m_RoadArray[lastIndex].transform.position = m_RoadArray[lastIndex].transform.position - new Vector3(150, 0, 0);

Spawn_Obstacle(lastIndex);

}

}

PS:这里解释一下代码,怎么切换的呢

举个例子,角色跑到了第二段,那么第一段要移动到第三段后面隔一个路段长度的距离,接下来画个图:

f43358d02094

在这里插入图片描述

那么为啥x轴减去150。这是因为我发现这三条路段的距离都差了50,坐标轴是负轴,所以就减去了150。

f43358d02094

在这里插入图片描述

我们可以测试一下效果:

f43358d02094

在这里插入图片描述

但是仅仅这样是不够的,我们还需要在角色到达抵达点的时候,切换路线,当然第一段路不用切换,因为再切就没了。。

这个在我们写完角色移动以后再补充。

8、角色移动

新建脚本:Control_Player.cs

说明一下:因为我们设定的三条道,所以角色只能在三条道里面切换。那么只需要改变角色的z值就可以了。如果角色在最左边,那么只能往右移动,同理在最右边,只能往左移动,在中间两边都可以移动。

接着我们就可以看一下z轴的值:

中间:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

左边:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

右边:

f43358d02094

在这里插入图片描述

f43358d02094

在这里插入图片描述

代码:

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");

// Use this for initialization

void Start()

{

m_Anim = GetComponent();

}

// Update is called once per frame

void Update()

{

transform.position += Vector3.left * 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)

{

if (transform.position.z == -14.7f)

return;

else if (transform.position.z == -9.69f)

{

transform.position = new Vector3(transform.position.x, transform.position.y, -14.7f);

}

else

{

transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);

}

}

else

{

if (transform.position.z == -6.2f)

return;

else if (transform.position.z == -9.69f)

{

transform.position = new Vector3(transform.position.x, transform.position.y, -6.2f);

}

else

{

transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f);

}

}

}

}

键盘WSAD控制上跳,下滑,左右移动等操作。现在就可以去试试啦。

f43358d02094

在这里插入图片描述

但是,有一点哈,角色怎么越跑越远离开了我们呢,因为,还没有写摄像机跟随脚本,接下来继续吧。

9、摄像机跟随

新建脚本Control_Camera.cs

using UnityEngine;

public class Control_Camera : MonoBehaviour

{

//间隔距离

public float m_DistanceAway = 5f;

//间隔高度

public float m_DistanceHeight = 10f;

//平滑值

public float smooth = 2f;

//目标点

private Vector3 m_TargetPosition;

//参照点

Transform m_Follow;

void Start()

{

m_Follow = GameObject.Find("Player").transform;

}

void LateUpdate()

{

m_TargetPosition = m_Follow.position + Vector3.up * m_DistanceHeight - m_Follow.forward * m_DistanceAway;

transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth);

}

}

OK 摄像机跟着Player跑起来了

10、碰撞检测

我们需要不停的躲避障碍物,一旦碰撞到障碍物就dead了

我们首先修改障碍物的碰撞器属性:

f43358d02094

在这里插入图片描述

Mesh Collider : Is Trigger=true

f43358d02094

在这里插入图片描述

我们给Player加上刚体和碰撞体:

f43358d02094

在这里插入图片描述

注意要勾上Is Trigger

打开Control_Player.cs脚本:

//游戏结束

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), "你输了~", 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);

}

}

11、切换道路

在第七章的时候就已经写好了道路切换,但是一直没有讲到碰撞检测,那么现在我们就结合碰撞检测,检测到抵达点然后切换道路吧

我们首先找到三个抵达点:MonitorPos

然后改名叫做MonitorPos0 MonitorPos1 MonitorPos2

f43358d02094

在这里插入图片描述

修改一下BoxCollider的Is Trigger属性:

f43358d02094

在这里插入图片描述

修改Control_Player.cs的代码:

//场景控制对象

Control_Scenes m_ControlScenes;

void Start()

{

m_Anim = GetComponent();

m_ControlScenes = GameObject.Find("Control_Scenes").GetComponent();

}

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);

}

if (other.gameObject.name == "MonitorPos0")

{

m_ControlScenes.Change_Road(0);

}

else if (other.gameObject.name == "MonitorPos1")

{

m_ControlScenes.Change_Road(1);

}

else if (other.gameObject.name == "MonitorPos2")

{

m_ControlScenes.Change_Road(2);

}

}

这篇关于linux下跑酷游戏编程,【Unity3D开发小游戏】《跑酷小游戏》Unity开发教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/240404

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

16.Spring前世今生与Spring编程思想

1.1.课程目标 1、通过对本章内容的学习,可以掌握Spring的基本架构及各子模块之间的依赖关系。 2、 了解Spring的发展历史,启发思维。 3、 对 Spring形成一个整体的认识,为之后的深入学习做铺垫。 4、 通过对本章内容的学习,可以了解Spring版本升级的规律,从而应用到自己的系统升级版本命名。 5、Spring编程思想总结。 1.2.内容定位 Spring使用经验

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了