作者:软件猫
日期:2016年12月8日
转载请注明出处:
上一篇文章中存在一个很严重的问题,首先我们先让 Main Camera 跟随 Player 移动
Main Camera 跟随 与 阻挡物
用 Redux 模式,我们可以很轻易的实现这个功能。
1、创建 MainCameraViewProvider.cs
using UnityEngine;public class MainCameraViewProvider : ViewProvider{ protected override void OnFixedStateChanged (State state) { // 使用 Player 的 x,y 坐标,并保持 z 坐标 transform.position = new Vector3 (state.Player.Position.x, state.Player.Position.y, transform.position.z); }}
2、将 MainCameraViewProvider.cs 拖放至 Main Camera。
3、使用下面的图片创建一个新的精灵,并拖入场景,命名为 Rock。
4、给 Rock 添加 Box Collider 2D
执行游戏后,我们发现当 Player 被 Rock 挡住的时候,MainCamera 仍然在向前移动。这是因为 Rigidbody 发现 Player 被 Rock 阻挡了,阻止了 Player 的移动,但是 AxisReducer 仍然在改变 PlayerState 中的 Position。
下面要针对这个问题进行改造。
改造 Rigidbody2D
改造思路是这样的:InitAction 时,传入 Player 的 Rigidbody2D 组件,用 Rigidbody2D 来决定 Position 和 Rotation。
下面的代码中,加粗部分是新增以及修改后的代码,划线部分是删除的代码。
1、改造 PlayerState.cs
using UnityEngine;namespace Player{ public class PlayerState { // 用于控制位置的刚体 public Rigidbody2D Rigidbody { get; set; } // 玩家坐标 public Vector2 Position { get { return Rigidbody.position; } set { Rigidbody.MovePosition (value); } } // 玩家面向的方向 public float Rotation { get { return Rigidbody.rotation; } set { Rigidbody.MoveRotation (value); } } // 移动速度 public float Speed { get; set; } }}
2、改造 PlayerActions.cs
using UnityEngine;namespace Player{ // Player 初始化,设置坐标、旋转角度与移动速度 public class InitAction : IAction { public Vector2 position { get; set; } public float rotation { get; set; } public float speed { get; set; } public Rigidbody2D rigidbody { get; set; } } // 移动轴 public class AxisAction : IAction { public float x { get; set; } public float y { get; set; } }}
3、改造 PlayerViewProvider.cs
using UnityEngine;namespace Player{ public class PlayerViewProvider: ViewProvider { [SerializeField] float speed = 3f; Rigidbody2D rigid = null; void Start () { rigid = GetComponent(); // 执行初始化 Store.Dispatch (new InitAction () { position = transform.position, rotation = transform.rotation.eulerAngles.z, speed = this.speed, rigidbody = GetComponent (), }); } void FixedUpdate () { // 获取轴数据,并传递 Action float ax = Input.GetAxis ("Horizontal"); float ay = Input.GetAxis ("Vertical"); if (ax != 0 || ay != 0) { Store.Dispatch (new AxisAction () { x = ax, y = ay }); } } protected override void OnFixedStateChanged (State state) { if (rigid != null) { // 刚体旋转和移动 rigid.MoveRotation (state.Player.Rotation); rigid.MovePosition (state.Player.Position); } } }}
执行游戏,刚体问题解决了。
这里有一点违反 Redux 模式,但是并不会影响整个架构。就这样。