马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册帐号
x
前言 大渣好。正如标题所示,咱们这篇文章做一个跑酷游戏。这个类型确实已经过了它最辉煌的时代。 但我要说的是,跑酷游戏是最适合初学者做完整个项目的游戏类型之一。你在这类项目中,需要涉及地图自动生成、角色操控与动画等一系列通用性极强的技术要点——而这一切,都是建立在“跑酷”这样一个不那么复杂的游戏架构上的。对初学者来说,没有比获取及时的正反馈和成就感更重要的了。 多说无益,直接开搞。 准备工具 DoTween插件。 插件下载
工程创建 打开Unity,新建一个工程,工程中新建一个文件夹并命名为Plugins,将DoTween插件解压后的文件放入这个文件夹当中。不明白文件夹有什么用的参考这篇文章: 需求分析 完成以上步骤才算准备完成。那么现在分析我们这款跑酷游戏的需求,或者说实现功能。 先听听我的小伙伴的看法。 伙伴A:肯定要有无限的道路了,不然怎么玩?(看我不跑死你们) 伙伴B:原版在地上跑太low了,我们自己做当然要厉害点了。那就要用魔法让道路自己到脚下来。 总结一下: 1.要有无限的道路 2.要让道路动起来,能够自己到脚下铺路。 恩!那就像这样? 地图模板 在探讨游戏规则之前,我们先制作整个游戏道路的模板。 首先我们在场景视图中创建一个Cube,并将他的TransForm.position改成0,0,0.同时更改这个Cube的名字为CubeCenter,去掉这个Cube上面的BoxCollider。创建第二个Cube,并将他的TransForm.position改成1,0,0.同时更改这个Cube的名字为CubeRightr,去掉这个Cube上面的BoxCollider。创建第三个Cube,并将他的TransForm.position改成-1,0,0.同时更改这个Cube的名字为CubeLeft,去掉这个Cube上面的BoxCollider。在CubeCenter下面创建一个空物体,并命名为RoadTemplate。
将这个空物体设为3个cube的父节点,同时添加一个BoxCollider,并将这个逐渐的Size改成3,1,1.用来刚好覆盖3个Cube。 然后将在这个道路模板保存为预制体。 地图规则 在游戏中你每一次生成下一个道路的时候你都会有3个方向选择 1.直线方向——foward 2.相对于自己的左方向——left 3.相对于自己的右方向——right 那么要生成能够使用的,无限的地图,那么我们必须制定游戏道路的生成规则才能达到这个目标。 规则1:在你生成一次转向道路后,10回合之内不能再进行转向。(如果还能继续转向会出现无法使用的道路) 规则2:只有在你完全经过一个道路进入下一个道路后,才能进行下一个道路的生成。(防止无限生成,占用不必要的资源。同时也防止道路生成过长,出现道路重叠,影响游戏体验) 依照上面的规则,我们创建一个GameMode.cs文件,贴上我的代码: [AppleScript] 纯文本查看 复制代码 public void BuidRoad()
{
int turnSeed = Random.Range(1,10); //用于确定是否转向
if (turnSeed == 1 && buidfound<=0)
{
buidfound = 10; //回合数更新
int dictSeed = Random.Range(1,3);
for (int i = 0; i < 3; i++) //先生成3个格子的道路,作为转向区
{
var tmpRoad = Instantiate(roadTemplate, guideTrs.position, guideTrs.rotation);
PlayRoadAnimator(tmpRoad);
roads.Add(tmpRoad);
guideTrs.position += guideTrs.forward;
}
if (dictSeed == 1)
{
guideTrs.position -= guideTrs.forward * 2; //转向区域生成完成后,引导物体回退2格
guideTrs.Rotate(Vector3.up, 90); //转向
guideTrs.position += guideTrs.forward * 2; //转向后引导物体的forward轴改变,改变pos值,到达下一个道路的生成地点
}
else
{
guideTrs.position -= guideTrs.forward * 2;
guideTrs.Rotate(Vector3.up, -90);
guideTrs.position += guideTrs.forward * 2;
}
}
else
{
var tmpRoad = Instantiate(roadTemplate, guideTrs.position, guideTrs.rotation);
PlayRoadAnimator(tmpRoad);
roads.Add(tmpRoad);
guideTrs.position += guideTrs.forward; //每生成一个道路,引导物体的位置改变
}
buidfound--;
}
PS:代码中的道路模板需要在编辑器中手动拖入。 人物动画与移动 游戏的人物模型我们使用官方免费提供的模型,在unity中Window菜单中点击Asste Store ,打开资源商店进行下载就行了。 新建一个动画控制文件,PlayerAnimatorController.controller。并应用在人物上,然后在animator视图中配置动画控制器。如图: 新建一个BlendTree,点击进入编辑 在人物模型上添加Character Controller组件。然后新建一个PlayerController.cs文件。然后再代码中获取模型身上的组件,进行动画与移动的设置。如下: [AppleScript] 纯文本查看 复制代码 void Update ()[/align]
[align=left]{[/align]
[align=left] moveSpeed += Time.deltaTime*0.3f;[/align]
[align=left] float moveDir = Input.GetAxis("Horizontal");[/align]
[align=left] MoveIncrements = transform.forward * moveSpeed * Time.deltaTime;[/align]
[align=left] MoveIncrements += transform.right * transverseSpeed * Time.deltaTime*moveDir;[/align]
[align=left] MoveIncrements.y += playController.isGrounded ? 0f : Physics.gravity.y * Time.deltaTime * 1f; //更新重力[/align]
[align=left] playController.Move(MoveIncrements);[/align]
[align=left] playAnimtor.SetFloat("MoveSpeed",playController.velocity.magnitude); //动画状态更新[/align]
[align=left]}
地图效果 在预览图中地图中的方块在空中进行旋转,为了达成这样的效果,我们先创建2个文件,分别是RoadControl.cs,RoadChildrenChange.cs。RoadControl挂载在父物体上,用于控制下面的子物体。如下: [AppleScript] 纯文本查看 复制代码 public void ChangeChildrens() //改变全部子物体的位置信息
{
for (int i=0;i< childrens.Length;i++)
{
childrens.PosChange();
childrens.ChangeRotate();
childrens.isTurn = true;
}
}
public void InitChildrens() //初始化全部子物体的信息
{
for (int i = 0; i < childrens.Length; i++)
{
childrens.Init();
childrens.isTurn = false;
}
}
RoadChildrenChange挂载在子节点上用于记录自己信息,并恢复。如下: [AppleScript] 纯文本查看 复制代码 public void PosChange() //改变这个物体的相对位置
{
int changeValueUp = 0;
int chageValueRight = 0;
while (Mathf.Abs(changeValueUp)<=4.0f)
{
changeValueUp = Random.Range(-10,10);
}
while (Mathf.Abs(chageValueRight) <= 4.0f)
{
chageValueRight = Random.Range(-10, 10);
}
transform.localPosition += transform.up * changeValueUp;
transform.localPosition += transform.right * chageValueRight;
}
public void ChangeRotate() //改变这个物体的相对旋转
{
transform.Rotate(transform.right, Random.Range(0, 180));
transform.Rotate(transform.forward, Random.Range(0, 180));
transform.Rotate(transform.up, Random.Range(0, 180));
}
public void Init() //使用DOTween插件初始化
{
transform.DOLocalMove(firstLocalPos, time);
transform.DOLocalRotateQuaternion(firstLocalRotation, time);
}
然后再将我们的道路模板挂载上我们的控制脚本,如图:
实现原理:通过代码记录组成道路模板小方块的Local坐标,在生成这个道路时候,改变自己的相对坐标,并按照设置好的轴进行旋转操作,在需要道路重现的时候,同时使用插件进行插值计算,在一定时间恢复道路,达到这个效果。 游戏运行 完成上面的步骤,我们将这写脚本挂载到游戏的对象当中,进行游戏运行。
后记 如有下期,我会增加道路生成的复杂性,添加游戏道具的生成等。(希望不会摸鱼给搞忘了) 附上这篇文章制作的简单工程:
知乎:繁华如梦
|