在Resources——Picture中新建Map文件夹,并将每个关卡的Map图片放在里面。每个Map图片都是上下无缝连接的。
在Game场景中新建SceneRoot空物体,并拿Main Camera和两张Map作为它的子物体,两张Map分别命名为map_0和map_1,并将两张Map上下无缝贴好,摄像机照向下面的Map。
我们想要Camera一直向Y轴正方向移动,而Camera的Postion和上面的Map重合时,下面的Map转到上面Map的上面,不断重复。
各种配置
将SceneRoot拉取到Resources——Prefab——Game文件夹内。
在Consts
中添加Map图片的名称前缀
1
| public const string MAP_PREFIX = "map_level_";
|
修改GameStateModel
中的Level
,修改为PlaneLevel
在GameModel
中添加SelectedLevel
属性,代表当前选择的关卡。
1
| public int SelectedLevel { get; set; }
|
修改LevelItemController
,设置每次选中的关卡
1 2 3 4 5 6
| transform.ButtonAction("Enter", () => { GameModel.Instance.SelectedLevel = _id; GameStateModel.Instance.TargetScene = SceneName.Game; UIMgr.Instance.Show(Pathes.LOADING_VIEW); });
|
在StreamingAssets——Config文件夹内,新建GameConfig.json
在Pathes
中配置它的路径以及Map图片文件夹的路径和GameConfig.json的路径
1 2 3 4 5 6 7
| private const string PREFAB_GAME_FOLDER = "Prefab/Game/"; public const string PREFAB_SCENEROOT = PREFAB_GAME_FOLDER + "SceneRoot";
public const string MAP_PICTURE_FOLDER = "Picture/Map/"
public static readonly string GAME_CONFIG = CONFIG_FOLDER + "/GameConfig.json";
|
MapMgr
在Scripts——Logic文件夹下创建MapMgr
脚本,这是需要动态挂载到SceneRoot的脚本,用来初始化地图的逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| using UnityEngine;
public class MapMgr : MonoBehaviour { public void Init() { Transform camera = transform.Find("Main Camera"); Transform map1 = transform.Find("map_1"); Transform map0 = transform.Find("map_0"); float offset = Mathf.Abs(map1.position.y - map0.position.y); var item0 = map0.AddCo<MapItem>(); item0.Init(offset, camera); var item1 = map1.AddCo<MapItem>(); item1.Init(offset, camera); camera.AddCo<CameraMove>(); } }
|
SceneConfig
在SceneConfig
中添加新的Game场景初始化逻辑。
1 2 3 4 5 6 7 8 9 10 11
| private void AddLoaded() { SceneMgr.Instance.AddSceneLoaded(SceneName.Game, callback => PoolMgr.Instance.Init(callback)); SceneMgr.Instance.AddSceneLoaded(SceneName.Game, callback => { var go = LoadMgr.Instance.LoadPrefabAndInstantiate(Pathes.PREFAB_SCENEROOT); var mapMgr = go.AddComponent<MapMgr>(); mapMgr.Init(); callback?.Invoke(); }); }
|
MapItem
这是每个Map的GameObject需要挂载的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| using UnityEngine;
public class MapItem : MonoBehaviour, IUpdate { private float _offset; private Transform _cameraTrans; private SpriteRenderer _spriteRenderer; public void Init(float offset, Transform camTrans) { _offset = offset; _cameraTrans = camTrans; _spriteRenderer = GetComponent<SpriteRenderer>(); LifeCycleMgr.Instance.Add(LifeName.UPDATE, this); SetSprite(); } private void SetSprite() { int level = GameModel.Instance.SelectedLevel; string name = Consts.MAP_PREFIX + level; Sprite sprite = LoadMgr.Instance.Load<Sprite>(Pathes.MAP_PICTURE_FOLDER + name); if(sprite == null) { sprite = LoadMgr.Instance.Load<Sprite>(Pathes.MAP_PICTURE_FOLDER + Consts.MAP_PREFIX + 0); } _spriteRenderer.sprite = sprite; }
public void UpdateFun() { if (JudgeMove(_offset, _cameraTrans)) { Move(_offset); } }
private bool JudgeMove(float offset, Transform camTrans) { return camTrans.position.y - transform.position.y >= offset; } private void Move(float offset) { var pos = transform.position; pos.y += offset * 2; transform.position = pos; } private void OnDestroy() { LifeCycleMgr.Instance.Remove(LifeName.UPDATE, this); } }
|
SerSprite方法:根据当前关卡Level加载不同的背景Sprite
CameraMove
动态挂载在Camera上,让它开始移动的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| using UnityEngine;
public class CameraMove : MonoBehaviour, IUpdate { private float _speed;
private void Start() { _speed = 0; var reader = ReaderMgr.Instance.GetReader(Pathes.GAME_CONFIG); reader["cameraSpeed"].Get<float>(value => { _speed = value; }); LifeCycleMgr.Instance.Add(LifeName.UPDATE, this); } public void UpdateFun() { transform.Translate(0, _speed * Time.deltaTime, 0); } private void OnDestroy() { LifeCycleMgr.Instance.Remove(LifeName.UPDATE, this); } }
|