抱歉抱歉,这两天都没时间做,今天就要修改《无眼地牢》玩家反馈的BUG了。
真的很感谢这两天反馈的玩家,都超级认真啊!如果真能上steam的话,一定给大家key作为感谢!!!!

然后昨天睡觉前我做完了《Wall》控制玩家移动的功能。
想的是按下方向键,就可以走一步这样。

首先,我做了一个单例化的类,用来监测玩家的按键。
所有玩家要按的键的监测,都在这个类中进行管理和处理。
在Unity中实现单例化真的太方便了,所以基本上会经常重复使用的、但又只需要1个实例的类,我都会做成单例模式。
代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Com.XiMiGua.Wall
{
    //
    //
    public class StaticInput : MonoBehaviour
    {  
        #region 
        public static StaticInput Instance;
        void Awake()
        {
            Instance = this;
        }
        #endregion
        #region 
        [HideInInspector]
        public bool InputUpArrow; // –
        [HideInInspector]
        public bool InputDownArrow; // –
        [HideInInspector]
        public bool InputLeftArrow; // –
        [HideInInspector]
        public bool InputRightArrow; // –
        #endregion
        #region Unity
        void Start()
        {
            InputUpArrow = false;
            InputDownArrow = false;
            InputLeftArrow = false;
            InputRightArrow = false;
        }
        void Update()
        {
            InputUpArrow = Input.GetKeyDown(KeyCode.UpArrow);
            InputDownArrow = Input.GetKeyDown(KeyCode.DownArrow);
            InputLeftArrow = Input.GetKeyDown(KeyCode.LeftArrow);
            InputRightArrow = Input.GetKeyDown(KeyCode.RightArrow);
        }
        #endregion
    }
}

我们有了监测用户按下按键的脚本了之后,就可以开始处理移动啦!
移动的话,因为Unity 中移动的方式太多了。
我开始用的是角色控制器,但是效果并不好,它会频繁穿墙,而且没有重力。
然后 我又试了下刚体,刚体移动有重力,但是因为我们是按一下移动一格,移动速度太快了!所以也会穿墙。
最后就用Transform进行移动,这样简单粗暴,而且后面还能用DoTween进行插值动画。
但是Transform没有重力,所以再添加一个刚体组件,为角色增加重力(不用刚体组件,也可以自己写射线检测,但是为了快速做出来,就直接使用刚体组件啦~)。
然后Transform是不管速度快不快,都会穿墙的!因为利用Transform进行移动会无视碰撞器。
所以我准备在角色移动到一个新的地方的时候,向四个方向发送射线,这样进行射线检测,看看能不能走动。
所以我们需要一个脚本来保存射线检测的结果。
代码如下(这个类我也做成单例模式了):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Com.XiMiGua.Wall
{
    /// <summary>
    ///  
    /// 
    /// </summary>
    public class StaticMoveJudge : MonoBehaviour
    {
        #region 
        public static StaticMoveJudge Instance;
        void Awake()
        {
            Instance = this;
        }
        #endregion
        #region 
        [HideInInspector]
        public bool IsUp;//
        [HideInInspector]
        public bool IsDown;//退
        [HideInInspector]
        public bool IsLeft;//
        [HideInInspector]
        public bool IsRight;//
        #endregion
        #region Unity
        void Start()
        {
            IsUp = true;
            IsDown = true;
            IsLeft = true;
            IsRight = true;
        }
        #endregion
    }
}

然后我把这两个脚本,挂到一个空物体上,把空物体命名为StaticClass,专门拿来挂单例化的脚本用的。

现在,就该做射线检测了。
但是我又突然觉得射线检测太麻烦,干脆用触发器来代替射线检测!
我真的是特别喜欢使用触发器来代替射线检测的。
那么我现在在角色的前后左右4个方向(角色只能朝4个方向进行移动),各放置一个Collider。
这个Collider的范围要比一个格子小,不然可能会碰撞到下下个格子上的碰撞器。
然后勾选Collider组件上的Trigger选项,把碰撞器变成一个触发器。
在Unity里,Collider(碰撞器)和Trigger(触发器)真的是太太太太常用了。
他们之间唯一的区别就是,碰撞器就像墙一样,会挡住玩家。触发器则不会。
比如,我们现在搭建个场景给大家演示一下:
如果地面是碰撞器,当正方体因为重力自由下落的时候,当碰到了地面,小球就会像真的碰撞到了地面一样,停下来

但如果地面是触发器,那么则不会产生碰撞,方块会穿过地面,继续下落

我们现在是希望这个Collider能穿过物体,然后如果它穿过了物体,就代表它的前面有障碍物,就不能朝那个方向移动。
所以,我们用触发器正合适。
现在的状态就像这样,玩家身上有一个大的碰撞器,用于和地面发生碰撞,不穿模的。
然后前后左右各有一个小的触发器,用于判断这个方向是否能移动。

我们现在给向前的触发器身上添加一个脚本叫做MoveIsUp.cs,用来管理是否能向前进行移动。
代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Com.XiMiGua.Wall
{
    /// <summary>
    /// 
    /// </summary>
    public class MoveIsUp : MonoBehaviour
    {
        void OnTriggerEnter(Collider other)//
        {
            StaticMoveJudge.Instance.IsUp = false;//
        }
        void OnTriggerExit(Collider other)
        {
            StaticMoveJudge.Instance.IsUp = true;
        }
    }
}

大概是这样的:当有物体进入碰撞器的时候,就代表前面有障碍物,不能前进。
当有物体离开碰撞器的是,代表前面没有障碍物了,可以前进了。
凑是这么简单哈哈哈哈!

然后剩下的3个方向也用同样的方式来做。
但是现在还有一个问题!就是,我们的玩家身上也有碰撞器,虽然我们可以写if语句来做区分。但是我最爱用的还是给不同的物体添加不同的层,然后指定哪些层跟那些层可以发生碰撞,这样大大提高了性能!
现在是这样的,我们把触发器设置为Move层,把地板和墙壁等障碍物设置为Plane层,让Move层只和Plane层发生碰撞。

最最最后就是移动的代码了!
为了让大家看的清除,下面的移动代码只实现向前移动。

using UnityEngine;
using System.Collections;
using JacobGames.SuperInvoke;
namespace Com.XiMiGua.Wall
{
    //
    public class PlayerMove : MonoBehaviour
    {
        #region 
        public float moveDistance = 0.9f;//0.9
        #endregion
        #region Unity
        void Update()
        {
            SetMoveDirection();//
        }
        #endregion
        #region 
        /// <summary>
        /// 
        /// </summary>
        private void SetMoveDirection()
        {
            //Up()
            if (StaticInput.Instance.InputRightArrow)
            {
                Move(Direction.Up);//
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name=”direction”></param>
        private void Move(Direction direction)
        {
            Vector3 newPosition = transform.position;
            //
            if (direction == Direction.Up && StaticMoveJudge.Instance.IsUp)
            {
                newPosition.x -= moveDistance;
            }
            //
            transform.position = newPosition;
        }
        #endregion
    }
}
把脚本挂到角色的身上。
现在角色身上是这样的:
有一个碰撞体(BoxCollider),一个刚体(Rigidbody),以及一个我们刚刚写的PlayerMove脚本。

然后我们来看看最终的效果吧!
现在碰到了墙就过不去了呢!完美!哈哈哈哈或!!!

感觉这一篇会让很多人感觉Unity很难,但是如果不使用游戏引擎的话,开发这些功能需要更加更加久的时间。
游戏引擎可以让我们节省80%的开发时间和精力。
感觉看不懂是因为,完全没有Unity的基础知识,如果我们下定决心,带上热爱慢慢学,大概1周就能开始做自己的游戏!

好啦!我要去改无眼地牢的BUG啦!我们明天见~