play.1122 发表于 2019-12-28 14:32

使用unity3D制作逃脱类小游戏的完整思路游戏过程

本帖最后由 play.1122 于 2019-12-29 11:42 编辑

使用unity3D制作逃脱类小游戏的完整思路游戏过程
读贴温馨提醒:(预计读贴需20分钟)
1.本人刚刚接触这个方面,小白一枚,大神不喜勿喷。
2.本帖使用语言全部使用C#。
3.此游戏非完全原创,非商用。
废话篇:最近快放假了,结果学校还要实训,我就选了unity3D,结果发现挺有意思,这个上手快,大家都知道unity支持java和C#两种语言,但在其更高版更趋向于C#,还有一个原因
,就是我的Java学的(此处省略好多字),这个unity3D项目是比较综合的,比较适合和我一样的小白入门。这里面用到的unity的功能比较多,而且游戏音效,特效,动画,特殊脚本
都提供好了,你可以做拆分再重组。反正目的就是让自己明白unity的属性,功能。还有就是其实我不是新成员,早就有号了,之前我经常分享破解软件,然后说我打广告,
就关小黑屋了,所以我洗心革面。(注:有人可能有错误认识,认为做游戏的所有素材都需要自己准备,当然身为个体是这样,
但在公司里游戏音效,特效,动画都是由其他专人提供给你的。)
这里我给大家提供了完整所有的资源包,并非打包好的exe,但可以直接使用。在unity打开自取,兄弟们读贴十分钟,写贴一小时,希望不要吝啬。管理员明鉴只发了素材。
正式开始
(一)创建主场景1)新建场景并保持,场景名MyStealth。
2)导入资源,拖拽Stealth.unitypackage包到Project面板。
3)过滤资源,删除没有用的目录。Prefabs(预制体),Done(官方实例),Scenes(场景目录)。
4)创建主场景游戏对象:env_stealth_static组件,为此对象添加MeshCollider碰撞器组件,过滤网格env_stealth_collision。
5)拖拽模型(汽车),摆放到对应位置,为其添加BoxCollider组件。
(二)创建警报灯光1)添加平行光源,命名为“AlarmLight”。
2)设置AlarmLight光源颜色为红色,同时设置其光照强度(Intensity)为0.
3)向光源添加脚本组件,“AlarmLight”,其原理为在0-2的光照强度来回切换,其核心代码为:
//如果当前光强强度到达了目标括光强,需要切换目标括         
if (Mathf.Abs (targetIntensity - alarmLight.intensity)< 0.05f) {            


//如果当獭前目标括是高光强            
if(targetIntensity == highIntensity) {                  
//切换目标括为低台光强?               
targetIntensity = lowIntensity;            }
else{                  //否则切换目标括为高光强            
   targetIntensity =highIntensity;            
}         
}
(三)创建警报声音
1)选中场景中的一个喇叭游戏对象(共6个),从层级视图选中全部。
2)为6个喇叭添加AuidoSource组件,Audioclip选择alarm_Triggered.
3)将AudioSource组件设置为循环播放(Loop=true),初始音量为0,并一直播放。
4)调整声音类型,为3D声音,最大范围为10.
5)将6个喇叭的Tag值,设置为Siren
(四)创建游戏对象控制器1)创建空游戏对象,命名为GameManager,设置其tag为GameClintroller
2)在GameManager身上,添加AuidoSource组件,其音频片段选择,循环播放,初始值为1.
3)为游戏控制器,LastPlayerSighting添加脚本和hashids脚本
4)在GameManager对象下,创建名为PaniMusic的游戏对象,播放警报音乐,音频片段选择PanicMusic,循环播放,初始音量为,2D声音。
5)LastPlayerSighting的核心思想是:警报位置一旦不等于(1000,1000,1000)时,警报触发,反之警报解除。
代码如下:
//解除警报馈      
if(alarmPosition == normalPosition) {         
//关闭警报馈灯         
alarmLight.alarmOn = false;         
//渐渐关闭警ˉ报馈背景音乐?         
panicAudio.volume = Mathf.Lerp (panicAudio.volume,      
      0, Time.deltaTime* turnSpeed);         
//逐个渐渐关闭警报喇叭声音         
for (int i = 0; i < alarmAudios.Length; i++) {         
   alarmAudios .volume = Mathf.Lerp (alarmAudios .volume,      
         0, Time.deltaTime* turnSpeed);         }      
   //渐渐开启主背景音乐         
mainAudio.volume = Mathf.Lerp (mainAudio.volume,         
    1, Time.deltaTime* turnSpeed);       }      
//开启警报馈       else {      
    //开启警报馈灯         
alarmLight.alarmOn = true;         
//渐渐关闭主背景音乐      
    mainAudio.volume = Mathf.Lerp (mainAudio.volume,       
       0, Time.deltaTime* turnSpeed);         
//渐渐开启警报背景音乐         
panicAudio.volume = Mathf.Lerp (panicAudio.volume,         
      1,Time.deltaTime * turnSpeed);         
//渐渐开启警报喇叭声音?         
for (int i = 0; i < alarmAudios.Length; i++) {         
    alarmAudios .volume = Mathf.Lerp (alarmAudios .volume,         
         1, Time.deltaTime* turnSpeed);         
}      
}   
}
(五)创建激光栅栏
1)在层级视图中,创建空游戏对象”Lasers”,作为激光栅栏的父对象
2)从Models目录下,选择fx_lasersFence_lasers模型,拖拽到场景中,依次将6个激光栅栏放到相应位置
3)选中6个激光栅栏,添加Light组件,营造红光氛围,Light组件设为点光源,Range=5,Intensity=1.5,Color=red。
4)选中6个激光栅栏,添加AudioSource组件,发出激光轰鸣声。AudioSource组件音频判断为“laser_hum”,初始播放,循环播放,初始音量为1,范围为1-5.
5)选中6个激光栅栏,添加BoxCollider组件,并且设置为触发器(Trigger)。
6)选中6个激光栅栏,添加脚本组件LaserController,将其中两个激光的闪烁标记打开。脚本逻辑为:检测玩家进入触发区域,修改PlayerLastSighting
核心脚本如下:void OnTriggerEnter (Collider other)
{       //如果是玩家   
    if (other.tag == Tags.Player) {         
//将玩家位置同步到警报位置      
   lastPlayerSighting.alarmPosition         
   =other.transform.position;      
}   
}效果如图:

注意设置参数

(六)创建激光开关(小电脑)
1)在层级视图中,创建空游戏对象作为激光开关的父物体。
2)在Models目录下,选择模型,拖拽到场景中,放到合适位置
3)为父物体添加一个碰撞器BoxCollider,防止人物穿模,不用设置大小。
4)在父物体上,添加AudioSource组件,播放激光解锁的声音,音频片段选择“Switch_deativation,初始不播放,不循环,音量为1,2d音效。
5)在子物体身上,添加一个BoxCollider,设置为触发器,作为检测玩家靠近的触发器区域,调整其大小,如图(waibu边框是触发器)

6)在子物体身上添加LaserSwitchDeativation脚本,该脚本检测玩家是否按下了Z键,如果在触发区域按下了Z,则会解锁对应的激光,并且修改屏幕材质,
其原理是将对应的激光失去激活,
代码如下:void OnTriggerStay (Collider other)
{      //当玩家按下Z键   
if (Input.GetKeyDown (KeyCode.Z) &&      
   other.tag == Tags.Player &&         
controlledLaser.activeSelf) {      
//关闭激光         
controlledLaser.SetActive(false);      
//切换屏幕材质      
GetComponent<MeshRenderer>().material = unlockMat;      
    //播放声音      
GetComponent<AudioSource>().Play ();      
}    }
(七)创建自动门1)在层级视图中创建空游戏对象“Doors”,作为三扇门的父物体。从Models目录下,查找“door_generic_slide”模型,拖拽到Doors下。
摆放好三扇门的位置。
2)选择三扇门,添加球形碰撞器组件(SphereCollider),将碰撞器改为触发器,高度设置为1,半径设置为1.5.
3)选中三扇门,添加AuidoSources组件,播放开门声音。音频片段设置为“Door-open‘,初始不播放,不循环。3D声音,范围1-5.
4)选中三扇门,添加脚本组件“Door Animation“,不勾选Needkey。
5)选中三扇门,动画控制器选择“DoorAnimationContoller“。

6)为了不允许玩家从门上穿过,在门的自物体上添加BoxCollider,无需设置大小和位置。效果如图

脚本逻辑是,玩家是否进入区域,区域人数不为0,则门打开,否则门关闭。
代码如下: void OnTriggerEnter (Collider other)    {   
//如果进来的是玩家或机器人      
if (other.tag == Tags.Player ||         
(other.tag == Tags.Enemy &&         
other.GetType () == typeof(CapsuleCollider))) {         
//人数递增         count++;         
//如果是玩家         
if (other.tag == Tags.Player) {         
   //设置玩家进入的标志位            
playerIn= true;            
//如果玩家没有钥匙            
if (!playerInventory.hasKey &&needKey) {         
         //播放拒绝声音            
      AudioSource.PlayClipAtPoint(refuseAud, transform.position);      
       }         
}       }
   }
(八)创建逃离大红门
1)从Models目录下,选择“Door-exit-outer“,拖拽到Doors对象下,摆放好位置。
2)选中红门,添加球形碰撞器,将其设置为触发器,位置为1,半径为2.
3)选中红门,添加Audio组件,音频片段选择,初始不播放,不循环,音量为1,3D声音,范围1-5.
4)选中红门,添加DoorAnimation脚本,勾选Needkey,并设置RefuseAud为“door_accessDenied”。
5)选中红门,为Animator组件设置动画状态机为“BigredAnimatorController”。
6)选中红门,的两个子物体,添加BoxCollider组件,防止玩家穿过。

(九)创建CCTV摄像头
1)创建空物体,,命名为“CCTV”,用来监视摄像头物体。
2)从Models目录下,寻找模型“prop_cctvCam”,拖拽至正确位置
3)向摄像头最底层的对象(body)添加一个空物体“trigger”。body和Trigger各自围绕x轴旋转30度。
4)在Trigger对象添加Light组件,灯光类型使用(spot)。Range=40-60,color=red,intensity=5-10,shezhiCookie的图片为“fx_cameraView_alp”。
5)在Trigger对象添加MeshCollider组件,mesh网格选择“prop_cctvCam_collision”,并勾选触发器。选择第二层游戏对象“prop_cctvCam_collision”,并勾选触发器
6)选择第二层游戏对象“prop_cctvCam_joint”,为其添加组件“Animation”,动画片段选择“CCTVCamAnimation”,使其左右旋转起来。
7)向Tirgger游戏对象,添加CCTVPlayerDetection脚本,逻辑是玩家进入触发范围,打开警报。
代码如下:void OnTriggerEnter (Collider other)    {   
    //如果是玩家,同步警报位置   
if (other.tag == Tags.Player) {      
   lastPlayerSighting.alarmPosition         
   =other.transform.position;   
}   
}

(十)创建自动升降电梯
1)从Models目录下,寻找电梯模型“”Prop_lift_exit拖拽到场景中
2)分析层级关系,为第二层“Door_exit_inner”层,添加脚本,使电梯的栅栏门与大红门同步打开,脚本逻辑是让栅栏门与大红门的本地坐标相等,
代码如下:void Update ()    {   
    //左右里门同步左右外门      
innerleft.localPosition=       
   new Vector3 (innerleft.localPosition.x,       
   innerleft.localPosition.y,         
outterleft.localPosition.z);   
    innerright.localPosition=          
new Vector3 (innerright.localPosition.x,      
   innerright.localPosition.y,         
outterright.localPosition.z);   
}
3)在电梯对象的第三层“Prop_lift_exit_carriage”,添加AudioSource组件,播放电梯上升声音,音频片段选择,2D声音,初始不播放,不循环。
4)在prop_lift_exit_carriage对象下,继续添加boxCollider组件,将其设置为触发器,大小与电梯机箱一般大,用作检测玩家是否进入了电梯。
5)继续在prop_lift_exit_carriage电梯井添加BoxCollider碰撞器,共4个,调整其位置和大小分别是电梯的三面墙壁和地板

6)在电梯身上添加脚本组件“LiftDoorsTracking.cs”,,控制电梯的上升和重新开始游戏,
代码如下:
void OnTriggerStay (Collider other){      
if (other.tag == Tags.Player) {         
timer += Time.deltaTime;         
//到达上升时间         
if (timer > waitTime) {               
//播放电梯声音               
if (!liftRaise.isPlaying) {                   
liftRaise.Play ();                }      
      //播放结束游戏声音            
    if (!endGame.isPlaying) {                  
endGame.Play ();                }         
      //电梯上升            
transform.root.position += Vector3.up * Time.deltaTime * moveSpeed;      
         //人物上升               
player.position += Vector3.up * Time.deltaTime * moveSpeed;         
      if (timer > waitTime + moveTime) {                  
///TODO:重启游戏            
       SceneManager.LoadScene ("Stealth");         
       }         
}      }
(十一)创建卡片
1)从Models目录下,选择“Prop-keycard”模型,拖拽到游戏场景,摆放到合适位置
2)在卡片上添加light组件,color=blue,光照强度intensity=1,range=5。
3)在卡片游戏对象上添加SphereCollider,设置成触发器,y=1,半径=1.
4)在卡片游戏对象身上,添加脚本组件“卡片旋转。Cs,控制卡片旋转,代码如下:
private void Update()
{      
transform.Rotate(Vector3.up* Time.deltaTime * 180);   
}
5)在卡片对象身上,添加脚本组件“KeyPickUp.cs”,拾起卡片的音频片段选择“keycard_pickUp”。该脚本设置玩家拿到钥匙,并且播放拾起声音、
控制卡片消失。代码为:
void OnTriggerEnter (Collider other)   
{   
if (other.tag == Tags.Player) {      
   //更换标志位,玩家获取到了钥匙         
playerInventory.hasKey= true;         
//播放声音         
AudioSource.PlayClipAtPoint(pickAud, transform.position);         
//销毁自己         Destroy(gameObject);   
}    }

(十二)创建玩家人物
1) 从Models目录下,寻找玩家模型“char_ethan”拖拽到场景中。删除场景中原来的白模cube。
2) 在人物的Aniamtor组件中,设置为,动画状态机内衣3个动画片段,分别是Idle,Run,Sneak(潜行),
如图:
3) 在player身上添加刚体组件,打开重力,冻结由于重力产生在x轴三个方向的旋转,冻结在y轴的偏移。

4) 微任务添加一个胶囊体碰撞器,调整至合适位置
5) 为人物添加AudioSource组件,用于播放脚步声,音频片段选择“Play_footsteps”,初始不播放,但循环,2D音效,音量为1.。
6) 为人物添加“Playerinventory.cs脚本组件,该组件使用bool类型变量表示是否拿到钥匙,代码如下://玩家是否拥有钥匙public bool hasKey = false;
7) 为人物添加耳朵组件,Audiolistener。
8) 为人物添加脚本组件PlayMovement.cs脚本,为脚本控制人物移动,逻辑规则是w向北s向南,a向西,d向东。
代码如下:
void Update ()    {   
if (playerHealth.health > 0) {         
//获取用户的按键情况         
hor= Input.GetAxis ("Horizontal");      
    ver= Input.GetAxis ("Vertical");   
   }else {         hor= 0;         
ver= 0;       }   
if (Input.GetKey (KeyCode.LeftShift)) {      
   sneak= true;      
}else {      
   sneak= false;      
}      
//设置潜行参数      
ani.SetBool(HashIDs.Sneak, sneak);   
    //如果用户按下了方向键      
if (hor != 0 || ver != 0) {         //动画参数Speed渐变到5.5(奔跑动画)      
    ani.SetFloat(HashIDs.Speed, 5.5f, 0.1f, Time.deltaTime);         //玩家转向   
      TurnDir(hor, ver);       }
else {         //立刻停下来      
   ani.SetFloat(HashIDs.Speed, 0);       }       //执行脚步声控制
   FootSteps();
}
9) 为玩家添加脚本组件“pleyerHealth.cs”,用来控制玩家的血量和死亡,其逻辑是玩家受到攻击,血量减少,当血量小于等于0时,
人物死亡,播放结束音乐“endgame”,游戏重新开始。其核心代码如下:
void Update ()    {       //如果血量小于等于0,死亡   
if (health <= 0 && !isdead) {         
ani.SetTrigger(HashIDs.Dead);         
isdead= true;      
}else if (isdead && !endGame) {      
   //开启结束游戏协程         
StartCoroutine(EndGame ());         
endGame= true;       }   
}     IEnumeratorEndGame ()    {       //播放结束音效   
    AudioSource.PlayClipAtPoint(endGameAud, transform.position);       //等待4.4秒
      yield return new WaitForSeconds (4.4f);      
//重新加载场景      
SceneManager.LoadScene("Stealth");   
}
8)人物完成效果如下:

(十三)添加相机1)调整相机视角45度,上帝视角。
2)在相机上添加脚本组件“CameraNovement.cs”,其原理是由相机每一帧向玩家发射射线,如果射线检测到玩家以外的物体,说明玩家和相机之间有障碍物,
相机便会向头顶方向移动,直到相机坚持到玩家,相机停下来,拍玩家,
原理如图:
代码如下:void LateUpdate ()    {       //第一个点   
    Vector3startPoint = player.position - direction;       //最后一个点
   Vector3endPoint = player.position + Vector3.up * distance;   
    //第二个点   
currentPoints = Vector3.Lerp (startPoint, endPoint, 0.25f);       //第三个点
      currentPoints = Vector3.Lerp (startPoint, endPoint, 0.5f);       //第四个点   
    currentPoints = Vector3.Lerp (startPoint, endPoint, 0.75f);       //放到数组里   
    currentPoints = startPoint;       currentPoints = endPoint;       //创建一个点,用来存储选择好可以看到玩家的点
   Vector3viewPosition = currentPoints ;       //遍历五点
   for (int i = 0; i < 5; i++) {         
if (CheckView (currentPoints )) {            
//更新合适的点            
viewPosition= currentPoints ;            
break;         }       }   
   //摄像机移动到指定点      
transform.position= Vector3.Lerp (transform.position,          
viewPosition,Time.deltaTime * moveSpeed);       //执行平滑旋转   
    SmoothRotate();
}
(十四)添加机器人AI(这是这里面最难理解的,你应该明白unity里导航的概念,不懂先查查看)
1)在Models目录下,选择机器人守卫模型“char_robotGuard”,拖拽至场景中,白放到合适位置。
2)为机器人守卫设置巡逻点,使用空物体表示,设置其在场景的显示标签为“wayPoint(小旗子)
3)机器人守卫的动画状态机选择“EnemyAnimatorController”。。该动画状态机中分为移动层和射击层,使用动画遮罩进行区分,
移动层使用了融合数值术,融合了21个动画。
4)为机器人守卫添加胶囊体碰撞器,调整大小。
5)为机器人守卫廷加球形碰撞器,设置为触发器,半径大小为10,当作机器人的感知范围,玩家进入到这个触发器范围,才能被看到或者听到脚步声。
6)为机器人守卫添加导航代{过}{滤}理组件,并设置导航。
(1地形勾选静态(static))(2)dakaiNavgation选项卡,点击bake按钮。(3)机器人守卫添加NavMeshAgent组件
7)为机器人守卫添加“EnemySight.cs”脚本。该脚本实现了机器人的“视觉”,和“听觉”功能。
(1)视觉:当玩家进入了机器人的触发器,如果玩家在机器人的视野范围呢110°之内,视为“发现”玩家,之后拉响警报,并且通知其它守卫。
②听觉:当玩家进入机器人触发器,发出脚步声音后,奔跑到发出声音的位置去“看一看”,跑的过程如果“看到”玩家,就拉响警报。
示例代码如下:void OnTriggerStay (Collider other)
{       //如果是玩家   
if (other.tag == Tags.Player) {         //重置   
      playerInSight= false;         //玩家与机器人的距离   
      float distance = Vector3.Distance(other.transform.position,      
                         transform.position);      
   //玩家与机器人之间的方向向量         
Vector3dir = other.transform.position - transform.position;   
       //计算机器人自身前方与方向向量之间的夹角         
float angular = Vector3.Angle (dir,transform.forward);   
      //满足视野范围内和距离范围内         
if (distance < distanceOfView &&angular < fieldOfView /
2) {            
if (Physics.Raycast (transform.position +Vector3.up * 1.7f,         
            dir, out hit)) {            
    if (hit.collider.tag == Tags.Player) {            
         //可以看到玩家                  
   playerInSight= true;               
    //报警                  
lastPlayerSighting.alarmPosition=         
                other.transform.position;   
            }            
}         }         
//听觉:如果机器人与玩家的导航路程在听觉路程范围内         
if (EnemyListening(other.transform.position)) {            //如果玩家发出了声音         
    if (other.GetComponent<AudioSource>().isPlaying) {               
//赋值私人警报位置               
personalAlarmPosition= other.transform.position;            
}      
   }       }   
}     /// <summary>    /// 机器人与玩家的导航距离在听觉范围内
   /// </summary>    bool EnemyListening (Vector3 playerPos)    {   
   UnityEngine.AI.NavMeshPathpath = new UnityEngine.AI.NavMeshPath ();       //如果导航可以到达玩家位置      
if (nav.CalculatePath (playerPos, path)) {         //用数组获取所有的路径点      
   Vector3[]points = new Vector3;         //起点      
   points = transform.position;         //终点         
points = playerPos;         //赋值中间的拐点      
    for (int i = 1; i < points.Length - 1; i++) {            
points = path.corners ;         }         //导航距离      
    float navDistance = 0;         //遍历计算距离         
for (int i = 0; i < points.Length - 1; i++) {            
navDistance+= Vector3.Distance (points , points );         
}         //导航距离在听觉距离范围内      
   if (navDistance < distanceOfView) {            
return true;         
}       }   
    return false;    }
8)向机器人守卫添加“EnemyAnimation。cs”脚本,该脚本实现机器人动画之间的切换,并且优化动作细节。
9)想机器人守卫添加“EnemyAI.cs”脚本组件,该组件控制机器人的具体行为,决定了机器人守卫什么时候攻击,什么时候追击,何时开枪射击等行为,
其判断依据是取决于与玩家之间的位置对象。10)向机器人守卫添加“EnemyShooting.cs”脚本组件,该脚本控制开枪时的效果,如打开闪光灯、打开激光,
并且对玩家造成伤害。
11)找到机器人的右手,在其下面拖拽一把手枪模型“prop_sciFiGun_low”。在手枪下创建一个空游戏对象,取名“Effects”。
12)在Effects对象上,添加Light组件,用于模拟开枪时的闪光灯。光源类型为point点光源,光强为2.5,Range=10。
13)在Effects对象上,添加LineRenderer组件,该组件模拟开枪时的激光,材质球选择“alpha_laserShot_fx”,起始和终止宽度(Width)设为0.1。
14)重复以上过程,创建另外两个机器人守卫。

Bug调试   
(1)机器人的手枪即使在搭配是多次调试,但在运行时,当机器人守卫攻击入侵者时,手枪还是位置偏离严重。影响游戏观感。
解决方法:在游戏调试运行过程中,在机器人守卫攻击入侵者那一帧时暂停,将手枪位置调好,将它的transform值copy component,
退出运行,将手枪的transform值Paste componentValues,之后运行即可。
(2)发现在运行时当逃离至电梯里,上升时,可以跳出,跳进电梯。
解决方法:这是由于创建电梯时第七步没有做好,首先,应该让外面的大红门不可见,然后添加BoxCollider碰撞器,
原理,人物是刚体,由于重力必须向下落,所以必须有碰撞器拖着它,墙壁也需要加碰撞器,需要注意的是,在安装电梯栅栏门的碰撞器是,
需要展开,给两个门分别安装一个。
这里我给大家提供了完整所有的资源包,并非打包好的exe,但可以直接使用。在unity打开自取,兄弟们读贴十分钟,写贴两小时,希望不要吝啬。
或者百度网盘,谢谢支持,资源附上

play.1122 发表于 2020-2-10 20:22

shen920928 发表于 2020-2-9 11:39
我是刚学unity3D的萌新,楼主有教学视频吗我想学习 看见你 很高大上的样子

没有很厉害,我也是再慢慢学习,可以一起分享

苏紫方璇 发表于 2019-12-28 22:49

play.1122 发表于 2019-12-28 22:14
重新发一个帖子吗?

不用,你的帖子左下角有编辑按钮,用这个就可以重新编辑了

play.1122 发表于 2019-12-28 15:03

排好版,一发就这样了,怎么办

苏紫方璇 发表于 2019-12-28 18:46

play.1122 发表于 2019-12-28 15:03
排好版,一发就这样了,怎么办

建议您重新编辑一下

RyanEdward 发表于 2019-12-28 20:02

感谢分享

play.1122 发表于 2019-12-28 22:14

苏紫方璇 发表于 2019-12-28 18:46
建议您重新编辑一下

重新发一个帖子吗?

play.1122 发表于 2019-12-29 11:44

苏紫方璇 发表于 2019-12-28 22:49
不用,你的帖子左下角有编辑按钮,用这个就可以重新编辑了

谢谢,重新编辑了

阳光下的少年 发表于 2019-12-30 19:03

好厉害鸭, 我也正在学习Unity3D

play.1122 发表于 2019-12-30 22:07

阳光下的少年 发表于 2019-12-30 19:03
好厉害鸭, 我也正在学习Unity3D

没有了,一起学习学习

cj13888 发表于 2019-12-31 10:30

学习借鉴一下,谢谢分享
页: [1] 2
查看完整版本: 使用unity3D制作逃脱类小游戏的完整思路游戏过程