视频链接:https://www.bilibili.com/video/av70393139/
项目地址:https://github.com/liangwj45/Unity-3D/tree/master/HW4
程序要求
将游戏中对象的动作分离出来,实现动作和物体属性的分离
添加裁判类,在游戏状态发生改变时通知场景控制器
游戏截图
编写程序
动作基类(SSAction)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class SSAction :ScriptableObject { public bool enable = true ; public bool destroy = false ; public GameObject gameObject { get ; set ; } public Transform transform { get ; set ; } public ISSActionCallback callback { get ; set ; } protected SSAction ( ) { } public virtual void Start ( ) { throw new System.NotImplementedException(); } public virtual void Update ( ) { throw new System.NotImplementedException(); } }
简单动作实现(CCMoveToAction)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class CCMoveToAction :SSAction { public Vector3 target; public float speed; public static CCMoveToAction GetAction (Vector3 target, float speed ) { CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>(); action.target = target; action.speed = speed; return action; } public override void Update ( ) { this .transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime); if (transform.position == target) { destroy = true ; callback.ISSActionCallback(this ); } } public override void Start ( ) { } }
顺序动作组合类实现(CCSequenceAction)
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 public class CCSequenceAction :SSAction , ISSActionCallback { public List<SSAction> sequence; public int repeat = 1 ; public int start = 0 ; public static CCSequenceAction GetAction (int repeat, int start, List<SSAction> sequence ) { CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction>(); action.sequence = sequence; action.repeat = repeat; action.start = start; return action; } public override void Update ( ) { if (sequence.Count == 0 ) return ; if (start < sequence.Count) { sequence[start].Update(); } } public void ISSActionCallback (SSAction source ) { source.destroy = false ; this .start++; if (this .start >= sequence.Count) { this .start = 0 ; if (repeat > 0 ) repeat--; if (repeat == 0 ) { this .destroy = true ; this .callback.ISSActionCallback(this ); } } } public override void Start ( ) { foreach (SSAction action in sequence) { action.gameObject = this .gameObject; action.transform = this .transform; action.callback = this ; action.Start(); } } void OnDestroy ( ) { } }
动作事件接口定义(ISSActionCallback)
1 2 3 4 public enum SSActionEventType :int { Started, Completed }public interface ISSActionCallback { void ISSActionCallback (SSAction source ) ; }
动作管理基类(SSActionManager)
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 public class SSActionManager :MonoBehaviour { private Dictionary<int , SSAction> actions = new Dictionary<int , SSAction>(); private List<SSAction> add_list = new List<SSAction>(); private List<int > delete_list = new List<int >(); protected void Update ( ) { foreach (SSAction ac in add_list) { actions[ac.GetInstanceID()] = ac; } add_list.Clear(); foreach (KeyValuePair<int , SSAction> kv in actions) { SSAction ac = kv.Value; if (ac.destroy) { delete_list.Add(ac.GetInstanceID()); } else if (ac.enable) { ac.Update(); } } foreach (int key in delete_list) { SSAction ac = actions[key]; actions.Remove(key); } delete_list.Clear(); } public void AddAction (GameObject gameObject, SSAction action, ISSActionCallback ICallBack ) { action.gameObject = gameObject; action.transform = gameObject.transform; action.callback = ICallBack; add_list.Add(action); action.Start(); } }
动作管理实现类(ActionManager)
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 public class ActionManager :SSActionManager , ISSActionCallback { public SSActionEventType complete = SSActionEventType.Completed; public void BoatMove (Boat boat ) { complete = SSActionEventType.Started; Vector3 destination = boat.gameObject.transform.position; destination.x = -destination.x; CCMoveToAction action = CCMoveToAction.GetAction(destination, boat.speed); AddAction(boat.gameObject, action, this ); boat.state = boat.state == BoatState.Left ? BoatState.Right : BoatState.Left; } public void UpDownBoat (Character character, Vector3 destination ) { complete = SSActionEventType.Started; Vector3 position = character.gameObject.transform.position; Vector3 middle = position; if (destination.y > position.y) { middle.y = destination.y; } else { middle.x = destination.x; } SSAction action1 = CCMoveToAction.GetAction(middle, character.speed); SSAction action2 = CCMoveToAction.GetAction(destination, character.speed); SSAction sequence = CCSequenceAction.GetAction(1 , 0 , new List<SSAction> { action1, action2 }); this .AddAction(character.gameObject, sequence, this ); } public void ISSActionCallback (SSAction source ) { complete = SSActionEventType.Completed; } }
裁判类(Judger)
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 public class Judger :MonoBehaviour { public Character[] preists; public Character[] devils; public Boat boat; public GameState gameState; public ISceneController sceneController; public void Start ( ) { gameState = GameState.Continue; } public void Update ( ) { GameState state = Check(); if (gameState != state) { sceneController.UpdateGameState(state); gameState = state; } } public GameState Check ( ) { int preist_left = 0 , preist_right = 0 , devil_left = 0 , devil_right = 0 , win = 0 ; for (int i = 0 ; i < 3 ; ++i) { if (preists[i].state == CharacterState.OnCoastL) { preist_left++; win++; } else if (preists[i].state == CharacterState.OnBoat && boat.state == BoatState.Left) { preist_left++; } else { preist_right++; } if (devils[i].state == CharacterState.OnCoastL) { devil_left++; win++; } else if (devils[i].state == CharacterState.OnBoat && boat.state == BoatState.Left) { devil_left++; } else { devil_right++; } } if (win == 6 ) return GameState.Win; if ((preist_left < devil_left && preist_left != 0 ) || (preist_right < devil_right && preist_right != 0 )) return GameState.Gameover; return GameState.Continue; } }
其他修改
修改原有的 Character 类和 Boat 类,去除原来的 Move 对象,并修改场景控制类,修改对象移动以及处理游戏状态改变的部分代码。