【Unity之竖屏游戏制作】如何做一个竖屏的手机游戏

2024-03-12 08:20

本文主要是介绍【Unity之竖屏游戏制作】如何做一个竖屏的手机游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 效果演示
    • 🎶(==1==) 添加分辨率
    • 🎶(==2==)生成地图
    • 🎶(==3==) 未添加缓存池之前
    • 🎶(==4==) 添加缓存池后
    • 🎶(==5==)缓存池 脚本
    • 🎶(==6==)简单的prime算法——十字检测
    • c#版本的十字Prim
    • c++版本的十字Prim
    • Unity版本的十字Prim
    • 🎶(==7==)prime算法生成的效果
    • 🅰️


效果演示

在这里插入图片描述


🎶(1 添加分辨率


在这里插入图片描述

在这里插入图片描述


🎶(2生成地图


普通矩形地图生成


在这里插入图片描述

菱形矩形地图生成

  • 单排生成

在这里插入图片描述

  • 双排铺满

在这里插入图片描述

  • 添加缓存池的本质其实就是资源的循环利用,减少多次CG。也就是说,当我们需要销毁一个物体的时候我们需要用到的story,但是多次的destroy,它会触发我们的CG回收,那此时我们如果说用一个列表或者是字典。形成了一个缓存池,让他临时存放,我们需要多次销毁的一个物体的话,那么它就避免了多次产生C机的回收机制。此时我们可以选择让存进去的物体失活,需要的时候再激活,把它存取出来,让就可以进行一个循环的利用。

🎶(3 未添加缓存池之前


在这里插入图片描述


🎶(4 添加缓存池后


在这里插入图片描述


🎶(5缓存池 脚本


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;/// <summary>
/// 抽屉数据 
/// </summary>
public class PoolData
{//抽屉中 对象挂载的父节点public GameObject fatherObj;//对象的容器public List<GameObject> poolList;public PoolData(GameObject obj, GameObject poolObj){//给我们的抽屉 创建一个父对象 并且把他作为我们pool(衣柜)对象的子物体fatherObj = new GameObject(obj.name);fatherObj.transform.parent = poolObj.transform;poolList = new List<GameObject>() {};PushObj(obj);}/// <summary>/// 往抽屉里面 压都东西/// </summary>/// <param name="obj"></param>public void PushObj(GameObject obj){//失活 让其隐藏//obj.SetActive(false);  //可放在外部去激活//存起来poolList.Add(obj);//设置父对象obj.transform.parent = fatherObj.transform;}/// <summary>/// 从抽屉里面 取东西/// </summary>/// <returns></returns>public GameObject GetObj(Transform parent)  //参数为需要设置的父对象{GameObject obj = null;//取出第一个obj = poolList[0];//对物体的Y轴进行约束obj.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePositionY;poolList.RemoveAt(0);//激活 让其显示obj.SetActive(true);//断开了父子关系obj.transform.SetParent(parent);return obj;}
}/// <summary>
/// 缓存池模块 
/// </summary>
public class PoolManager : SingleManager <PoolManager>
{//缓存池容器 (衣柜)public Dictionary<string, PoolData> poolDic = new Dictionary<string, PoolData>();private GameObject poolObj;/// <summary>/// 从缓存池中拿东西/// </summary>/// <param name="名字"></param>/// <param parent="挂载的父对象"></param>/// <param position="实例化的位置"></param>/// <param rotation="实例化的角度"></param>/// <param callBack="委托"></param>public void GetObj(string name, Transform parent, UnityAction<GameObject> callBack) //第三个参数为挂载的父对象{if(poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0){callBack(poolDic[name ].GetObj(parent));}else{//同步加载GameObject obj = GameObject.Instantiate(ResManager.GetInstance().Load<GameObject>("prefabs/" + name));obj.name = name;  callBack(obj);  //返回实例化的物品给委托通过异步加载资源 创建对象给外部用//ResManager .GetInstance().LoadAsync<GameObject>("prefabs/"+name, (o) =>//{//    o.name = name;//    callBack(o);//});//obj = GameObject.Instantiate(Resources.Load<GameObject>(name));//把对象名字改的和池子名字一样//obj.name = name;}}/// <summary>/// 换暂时不用的东西给池子/// </summary>public void PushObj(string name, GameObject obj){if (poolObj == null)poolObj = new GameObject("Pool");//里面有抽屉if (poolDic.ContainsKey(name)){poolDic[name].PushObj(obj);}//里面没有抽屉else{          poolDic.Add(name, new PoolData(obj, poolObj));}}/// <summary>/// 清空缓存池的方法 /// 主要用在 场景切换时/// </summary>public void Clear(){poolDic.Clear();poolObj = null;}
}

🎶(6简单的prime算法——十字检测


在这里插入图片描述

在这里插入图片描述

  • 1.首先全部判定为墙,最外的为路包裹墙(类似于防止数组越界
    在这里插入图片描述
  • 2.红色为它的检测范围(假设检测点在如图所示的位置)———(可先忽略此步骤)

——————在这里插入图片描述

  • 3.该检测点(紫色)需要在起点的旁边或者外墙旁边,已保证它可以生成主路线而不是死迷宫
    在这里插入图片描述
    在这里插入图片描述
  • 4.生成后是这样的,没有出口,它不会自动打破墙
    在这里插入图片描述
  • 5,所以需要我们自己检测一波打出一个出口

在这里插入图片描述

  • 运行结果
    在这里插入图片描述

c#版本的十字Prim


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace algorithm
{/// <summary>/// 该Prom算法,初始化时全部是墙/// </summary>class PrimOfAlgorithm{public const int max = 40;int[,] Maze = new int[max  , max ];  //默认全为0 ,全为墙Random random = new Random();//X和Y方向的队列List<int> X = new List<int>();List<int> Y = new List<int>();/// <summary>/// 生成迷宫/// </summary>public  void CreatMap(){//设置迷宫进口Maze[2, 1] = 1;//将最外围设置为路,包裹最外层的的墙,防止出界for (int i = 0; i < max; i++){Maze[i ,0]= 1;Maze[i, max - 1] = 1;Maze[0, i] = 1;Maze[max - 1, i] = 1;  }//设置一个坐标.该检测点需要在起点的旁边,或者旁边是外围路X.Add (2);Y.Add (2);while( Y.Count > 0){int index = random.Next(0, X.Count - 1); //随机性则有错综复杂的效果int xPosition=  X[index];int yPosition = Y[index];//判断上下左右是否有路int count = 0;for (int i = xPosition - 1; i <= xPosition + 1; i++) //左右位置{for (int j = yPosition - 1; j <= yPosition + 1; j++) //上下位置{//判断它是不是十字检测中的点,和判断它是否为路if (Math.Abs(xPosition - i) + Math.Abs(yPosition - j) == 1 && Maze[i,j] > 0) {++count; //路++  }}}//如果十字检测的路标记少于或等于1条?(为甚不直接小于1呢,因为它要保证生成一条主路)if (count <= 1){//将此刻的位置变成路Maze[xPosition, yPosition] = 1;for (int i = xPosition - 1; i <= xPosition + 1; i++){for (int j = yPosition - 1; j <= yPosition + 1; j++){//判断它是不是十字检测中的点并且是墙if (Math.Abs(xPosition - i) + Math.Abs(yPosition - j) == 1 && Maze[i, j] == 0){//把十字检测到的墙放入XY墙列表X.Add(i);Y.Add(j);}}}}//删除列表中已经变成路的点X.RemoveAt(0 + index );Y.RemoveAt(0 + index ); //记住不能是Remove}//设置迷宫出口(出口不可能是四个底脚)for (int i = max - 3; i >= 0; i--){if (Maze[i, max - 3] == 1){Maze[i, max - 2] = 1;break;}}//画迷宫for (int i = 0; i < max; i++){for (int j = 0; j < max; j++){if (Maze[i, j] == 1)Console.Write("  ");elseConsole.Write("囚");}Console.WriteLine();}}static void Main(string[] args){PrimOfAlgorithm aa = new PrimOfAlgorithm();aa.CreatMap();}}}

c++版本的十字Prim



#include <iostream>
#include<vector>
#include <windows.h>
using namespace std;
static const int L = 44;
void CreateMaze();
int main()
{CreateMaze();
}void CreateMaze() {int Maze[L][L] = { 0 };vector<int> X;vector<int> Y;//最外围设置为路,可以有效的保护里面一层墙体,并防止挖出界for (int i = 0; i < L; i++) {Maze[i][0] = 1;Maze[0][i] = 1;Maze[L - 1][i] = 1;Maze[i][L - 1] = 1;}//设置迷宫进口Maze[2][1] = 1;//任取初始值X.push_back(2);Y.push_back(2);//当墙队列为空时结束循环while (X.size()) {//在墙队列中随机取一点int r = rand() % X.size();int x = X[r];int y = Y[r];//判读上下左右四个方向是否为路int count = 0;for (int i = x - 1; i < x + 2; i++) {	for (int j = y - 1; j < y + 2; j++) {if (abs(x - i) + abs(y - j) == 1 && Maze[i][j] > 0) {++count;}}}if (count <= 1) {Maze[x][y] = 1;//在墙队列中插入新的墙for (int i = x - 1; i < x + 2; i++) {for (int j = y - 1; j < y + 2; j++) {if (abs(x - i) + abs(y - j) == 1 && Maze[i][j] == 0) {X.push_back(i);Y.push_back(j);}}}}//删除当前墙X.erase(X.begin() + r);Y.erase(Y.begin() + r);}//设置出口 (从最下往上面判断)for (int i = L - 3; i >= 0; i--) {if (Maze[i][L - 3] == 1) {Maze[i][L - 2] = 1;break;}}//画迷宫for (int i = 0; i < L; i++){for (int j = 0; j < L; j++) {if (Maze[i][j] == 1) printf("  ");else printf("囚");}printf("\n");}}

Unity版本的十字Prim


在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:  生成迷宫
//___________创建者:_____秩沅_____
//_____________________________________
//-------------------------------------
public class Muze : MonoBehaviour
{const int max = 40;//建立迷宫数组private int[,] mauz = new int [max ,max ];//墙列表private List<int > X = new List<int>();private List<int>  Y = new List<int>();//待加载资源private GameObject m_prefab_tile;private GameObject m_prefab_wall;private void Awake(){//资源加载m_prefab_tile = Resources.Load<GameObject>("prefabs/tile_white");m_prefab_wall = Resources.Load<GameObject>("prefabs/cube_bread");}void Start(){//初始坐标CreatMazu(new Vector2(2,1));}/// <summary>/// 生成迷宫/// </summary>public void CreatMazu( Vector2  position){//step1.设置外墙for (int i = 0; i < max ; i++){mauz[0, i] = 1;mauz[i, 0] = 1;mauz[i, max - 1] = 1;mauz[max - 1, i] = 1;}//step2.将初始位置放入队列当中X.Add((int )position.x);Y.Add((int )position.y);mauz[(int )position.x, (int )position.y] = 1; //它为起点while(X.Count > 0) //当列表里面有值的时候,也代表有墙的时候{//step3:从列表中取判定点int index = Random.Range(0, X.Count - 1); //从墙队列里面随机取一个下标int xPosition = X[index];int yPosition = Y[index];int count = 0;  //路的数量//step4:道路判定for (int i = xPosition - 1; i <= xPosition + 1; i++){for (int j = yPosition - 1; j <= yPosition + 1; j++){if (Mathf.Abs(xPosition - i) + Mathf.Abs(yPosition - j) == 1 && mauz[i, j] > 0){count++;}}}//step5:变成路,添加墙if (count <= 1){mauz[xPosition, yPosition] = 1; //变成路for (int i = xPosition - 1; i <= xPosition + 1; i++){for (int j = yPosition - 1; j <= yPosition + 1; j++){if (Mathf.Abs(xPosition - i) + Mathf.Abs(yPosition - j) == 1 && mauz[i, j] == 0){X.Add(i);Y.Add(j);}}}}//step6:移除列表里面的墙X.RemoveAt(0 + index);Y.RemoveAt(0 + index);}//step7:检测一下设置出口for (int i = max - 3 ; i  > 0 ; i-- ){if(mauz[i,max - 3 ] == 1 ){mauz[i, max - 2] = 1;break;}}//step8:加载迷宫for (int i = 0; i < max ; i++){for (int j = 0; j < max ; j++){if(mauz[i,j] == 0 ){GameObject ob =  Instantiate(m_prefab_wall,new Vector3(i * 0.254f, 0 , j * 0.254f),Quaternion.identity );ob.transform.SetParent(transform);}                }}}
}

🎶(7prime算法生成的效果


迷宫相对比较自然,但迷宫的分岔路会比较多,适合生成错综复杂的地图效果,主路不是特别明显

  • 初始化大地图,0代表墙,1代表道路,墙为地图边缘包裹

  • 靠近地图边缘随机选取状态为1的道路点,作为出生点a

  • 然后将 a 点周围所有的墙体点标记为待检测点,加入到待检测集合

  • 从待检测集合随机取一个点 b ,判断顺着它方向的下一个点 c,是否是道路

  • 如果是,则将这个待检测点墙体打通,将其移出待检测集合;将下一个点 c作为新的起点,重新执行第3步

  • 如果不是就把这个待检测点移出待检测集合,重新作为墙体点
    不断重复,直到待检测集合全部检查过,重新为空
    在这里插入图片描述
    🅰️


🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


这篇关于【Unity之竖屏游戏制作】如何做一个竖屏的手机游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系

OpenStack镜像制作系列2—Windows7镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系列

OpenStack镜像制作系列1—环境准备

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作