这节课我们讲
EntityComponentSystem 架构Entitas 交互功能实现(三)
最后的效果就是这样
接下来就开始我们的教程
- 新建文件夹 2.IniterationExample 然后接着 Components 和Const 文件夹
- Components 文件夹下创建Input文件夹创建 MouseComponent (在类上添加Input标签),MouseButtonComponent (在类上添加Input标签),
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 方向组件
/// </summary>
[Game]
public class DirectionComponent : IComponent
{
/// <summary>
/// 方向
/// </summary>
public float direction;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 位置组件
/// </summary>
[Game]
public class PositionComponent : IComponent
{
/// <summary>
/// 位置
/// </summary>
public Vector2 position;
}
}
- 在Components文件夹下创建Game文件夹 创建PositionComponent(在类上添加Game标签),DirectionComponent(在类上添加Game标签)类
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标事件组件
/// </summary>
[Input]
public class MouseButtonComponent : IComponent
{
/// <summary>
/// 鼠标事件
/// </summary>
public MouseButtonEvent mouseEvent;
}
}
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标点击组件
/// </summary>
[Input]
public class MouseComponent : IComponent
{
/// <summary>
/// 点击的鼠标类型
/// </summary>
public MouseButton mouse;
}
}
- 全部在IniterationExample命名空间下
- Const文件夹下创建Enum 的枚举类型
namespace IniterationExample
{
/// <summary>
/// 鼠标按键事件
/// </summary>
public enum MouseButton
{
LEFT,RIGHT
}
/// <summary>
/// 鼠标事件
/// </summary>
public enum MouseButtonEvent
{
DOWN,PRESS,UP
}
}
- 添加View 视图 负责跟Unity的视图交互 新建Systems文件夹 新建一个AddViewSystem 类
using System.Collections.Generic;
using Entitas;
namespace IniterationExample {
/// <summary>
/// 添加视图层的系统
/// </summary>
public class AddViewSystem : ReactiveSystem<GameEntity> {
public AddViewSystem(Contexts contexts ) :base (contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
throw new System.NotImplementedException();
}
protected override bool Filter(GameEntity entity)
{
throw new System.NotImplementedException();
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
throw new System.NotImplementedException();
}
}
}
- 添加 在Game文件夹下添加ViewComponent 脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 视图层组件
/// </summary>
[Game]
public class ViewComponent : IComponent
{
/// <summary>
/// 视图层对象
/// </summary>
public Transform viewTrans;
}
}
- 生成一下代码 然编写 AddViewSystem脚本
using System.Collections.Generic;
using Entitas;
using Entitas.Unity;
using UnityEngine;
namespace IniterationExample {
/// <summary>
/// 添加视图层的系统
/// </summary>
public class AddViewSystem : ReactiveSystem<GameEntity> {
private Transform _parent;
private Contexts _contexts;
public AddViewSystem(Contexts contexts ) :base (contexts.game)
{
_parent = new GameObject("ViewParent").transform;
}
/// <summary>
/// 触发器
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleView);
}
protected override bool Filter(GameEntity entity)
{
//条件是没有view组件的时候 添加组件 如果没有添加View视图
return ! entity.hasIniterationExampleView;
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entity in entities)
{
GameObject go = new GameObject("View");
go.transform.SetParent(_parent);
//关联Unity 和 View视图
go.Link(entity) ;
//添加View视图
entity.AddIniterationExampleView(go.transform);
}
}
}
}
- 添加完了GameObject go 这时候是在视图中看不到的。需要添加一下组件才能看到
- 在Systems 文件夹下新建RenderSpriteSystem脚本 添加命名空间IniterationExample
- 在Components/Game文件夹下创建 SpriteComponent脚本 添加命名空间IniterationExample
- 接着在生成一下代码 才能找到我们想要的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 添加图片
/// </summary>
public class RenderSpriteSystem : ReactiveSystem<GameEntity>
{
public RenderSpriteSystem( Contexts contexts): base (contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entitie in entities)
{
Transform trans= entitie.initerationExampleView.viewTrans;
SpriteRenderer sr = trans.GetComponent<SpriteRenderer>();
///如果当前transform没有spriterender组件就添加一个
if (sr==null)
{
sr= trans.gameObject.AddComponent<SpriteRenderer>();
}
sr.sprite = Resources.Load<Sprite>(entitie.initerationExampleSprite.spriteName);
}
}
/// <summary>
/// 过滤器
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
protected override bool Filter(GameEntity entity)
{
return entity.hasIniterationExampleSprite && entity.hasIniterationExampleView;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleSprite);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 图片组件
/// </summary>
public class SpriteComponent : IComponent
{
/// <summary>
/// 图片名字
/// </summary>
public string spriteName;
}
}
- 新建文件夹Feature 里面新建脚本GameFeature
namespace IniterationExample
{
public class GameFeature : Feature
{
public GameFeature(Contexts contexts)
{
Add(new AddViewSystem(contexts));
Add(new RenderSpriteSystem(contexts));
}
}
}
- 新建文件夹Controller新建GameController脚本
using Entitas;
using UnityEngine;
namespace IniterationExample
{
public class GameController : MonoBehaviour
{
private Systems _system;
private Contexts _context;
private void Start()
{
_context = Contexts.sharedInstance;
_system = CreateStetems();
}
private Systems CreateStetems()
{
return new Feature("System").Add(new GameFeature(_context));
}
private void Update()
{
_system.Execute();
_system.Cleanup();
}
}
}
- 打开System文件夹 新建MouseSystem脚本
- 打开MouseComponent脚本添加Unique ?? 代码里面有注释 然后点击生成
using Entitas;
using Entitas.CodeGeneration.Attributes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标点击组件 Unique 是指全局唯一的意思 需要引入using Entitas.CodeGeneration.Attributes; 命名空间
/// </summary>
[Input,Unique]
public class MouseComponent : IComponent
{
/// <summary>
/// 点击的鼠标类型
/// </summary>
public MouseButton mouse;
}
}
全局唯一的 生成代码就 会在这创建一个单利类??? 不懂 只需要调用 interationExampleMouse
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标事件相应系统
/// </summary>
public class MouseSystem : IExecuteSystem ,IInitializeSystem
{
/// <summary>
/// 前面说 一共创建了两个实体对象 Game 和Input 因为Mouse跟输入有关就用Input
/// </summary>
private InputEntity _inputEntity;
private InputContext _contexts;
public MouseSystem(Contexts contexts)
{
_contexts = contexts.input;
}
/// <summary>
/// 初始化实体对象
/// </summary>
public void Initialize()
{
_inputEntity = _contexts.initerationExampleMouseEntity;
}
public void Execute()
{
if (Input.GetMouseButtonDown(0))
{
}
}
}
}
- 把MouseComponent整理一下 把 MouseButtonComponent 里面的东西整理到MouseComponent脚本 删掉MouseButtonComponent脚本 。修改 注释 一下报错 然后生成代码 注释完成生成代码是没问题的哦。
using Entitas;
using Entitas.CodeGeneration.Attributes;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标点击组件 Unique 是指全局唯一的意思 需要引入using Entitas.CodeGeneration.Attributes; 命名空间
/// </summary>
[Input,Unique]
public class MouseComponent : IComponent
{
/// <summary>
/// 点击的鼠标类型
/// </summary>
public MouseButton mouse;
/// <summary>
/// 鼠标事件
/// </summary>
public MouseButtonEvent mouseEvent;
}
}
- MouseSystem类
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标事件相应系统
/// </summary>
public class MouseSystem : IExecuteSystem ,IInitializeSystem
{
/// <summary>
/// 前面说 一共创建了两个实体对象 Game 和Input 因为Mouse跟输入有关就用Input
/// </summary>
private InputEntity _inputEntity;
private InputContext _contexts;
public MouseSystem(Contexts contexts)
{
_contexts = contexts.input;
}
/// <summary>
/// 初始化实体对象
/// </summary>
public void Initialize()
{
_inputEntity = _contexts.initerationExampleMouseEntity;
}
public void Execute()
{
if (Input.GetMouseButtonDown(0))
{
//更新这个数据
_inputEntity.ReplaceIniterationExampleMouse(MouseButton.LEFT, MouseButtonEvent.DOWN);
//这种情况是不行的 因为框架不知道你更改了 更不会去相应你的事件
//_inputEntity.initerationExampleMouse.mouse= MouseButton.LEFT
}
if (Input.GetMouseButtonDown(1))
{
//更新这个数据
_inputEntity.ReplaceIniterationExampleMouse(MouseButton.RIGHT, MouseButtonEvent.DOWN);
}
}
}
}
- 鼠标事件相应系统的实现 CreateSystem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 创建实体系统 监听鼠标点击 继承ReactiveSystem<InputEntity>
/// </summary>
public class CreateSystem : ReactiveSystem<InputEntity>
{
/// <summary>
/// 获取Game的上下文 通过GameContext对象创建
/// </summary>
private GameContext _gameCOntext;
public CreateSystem( Contexts contexts ):base(contexts.input)
{
_gameCOntext = contexts.game;
}
protected override bool Filter(InputEntity entity)
{
//判断是否含有mouse组件 是否是左键按下
return (entity.hasIniterationExampleMouse)
&& (entity.initerationExampleMouse.mouse==MouseButton.LEFT)
&& (entity.initerationExampleMouse.mouseEvent == MouseButtonEvent.DOWN);
}
protected override ICollector<InputEntity> GetTrigger(IContext<InputEntity> context)
{
return context.CreateCollector(InputMatcher.IniterationExampleMouse);
}
protected override void Execute(List<InputEntity> entities)
{
foreach (InputEntity entitie in entities)
{
//在这里创建的是一个Game对象 所以需要获取上下文
_gameCOntext.CreateEntity();
}
}
}
}
- 新建 feacture 文件夹下新建InputFeature类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
public class InputFeature : Feature
{
public InputFeature( Contexts contexts )
{
Add(new CreateSystem(contexts));
Add(new MouseSystem(contexts));
}
}
}
- 然后修改GameController类中 吧InputFeacture添加进去
using Entitas;
using UnityEngine;
namespace IniterationExample
{
public class GameController : MonoBehaviour
{
private Systems _system;
private Contexts _context;
private void Start()
{
_context = Contexts.sharedInstance;
_system = CreateStetems();
}
private Systems CreateStetems()
{
return new Feature("System").Add(new GameFeature(_context)) .Add(new InputFeature(_context));
}
private void Update()
{
_system.Execute();
_system.Cleanup();
}
}
}
- 运行发现报错 修改 MouseSystem类 修改的内容 已经加上注释了 大概就是 用上下文更新方法 而不是通过单利
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 鼠标事件相应系统
/// </summary>
public class MouseSystem : IExecuteSystem ,IInitializeSystem
{
/// <summary>
/// 前面说 一共创建了两个实体对象 Game 和Input 因为Mouse跟输入有关就用Input
/// </summary>
private InputEntity _inputEntity;
private InputContext _contexts;
public MouseSystem(Contexts contexts)
{
_contexts = contexts.input;
}
/// <summary>
/// 初始化实体对象
/// </summary>
public void Initialize()
{
//我们创建了一个MouseEntity对象 附属于InputContext
_inputEntity = _contexts.initerationExampleMouseEntity;
}
public void Execute()
{
if (Input.GetMouseButtonDown(0))
{
//更新这个数据 _inputEntity.ReplaceIniterationExampleMouse 这样写是错的 他是属于 InputEntity类下的 所以要用 _contexts.ReplaceIniterationExampleMouse
// _contexts.ReplaceIniterationExampleMouse 是上下文的方法 _inputEntity.ReplaceIniterationExampleMouse 是实体方法
_contexts.ReplaceIniterationExampleMouse(MouseButton.LEFT, MouseButtonEvent.DOWN);
//这种情况是不行的 因为框架不知道你更改了 更不会去相应你的事件
//_inputEntity.initerationExampleMouse.mouse= MouseButton.LEFT
}
if (Input.GetMouseButtonDown(1))
{
//更新这个数据
_contexts.ReplaceIniterationExampleMouse(MouseButton.RIGHT, MouseButtonEvent.DOWN);
}
}
}
}
- 运行测试 没问题
- 这节课我们添加Sprite 在CreateEntity 实体的时候 添加一个Sprite组件 Resources文件夹下的名字
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 创建实体系统 监听鼠标点击 继承ReactiveSystem<InputEntity>
/// </summary>
public class CreateSystem : ReactiveSystem<InputEntity>
{
/// <summary>
/// 获取Game的上下文 通过GameContext对象创建
/// </summary>
private GameContext _gameCOntext;
public CreateSystem( Contexts contexts ):base(contexts.input)
{
_gameCOntext = contexts.game;
}
protected override bool Filter(InputEntity entity)
{
//判断是否含有mouse组件 是否是左键按下
return (entity.hasIniterationExampleMouse)
&& (entity.initerationExampleMouse.mouse==MouseButton.LEFT)
&& (entity.initerationExampleMouse.mouseEvent == MouseButtonEvent.DOWN);
}
protected override ICollector<InputEntity> GetTrigger(IContext<InputEntity> context)
{
return context.CreateCollector(InputMatcher.IniterationExampleMouse);
}
protected override void Execute(List<InputEntity> entities)
{
foreach (InputEntity entitie in entities)
{
//在这里创建的是一个Game对象 所以需要获取上下文
var gameEntity= _gameCOntext.CreateEntity();
//添加Sprite 添加的Sprite的名字
gameEntity.AddIniterationExampleSprite("006tCxXily1fz4ran8lweg308c09xx6v");
}
}
}
}
- 然后会发现这时候有报错。。 问题出在AddViewSystem的Trigger(筛选器) 应该获取的是Sprite 而不是View 修改以后再在Filter增加一个条件
using System.Collections.Generic;
using Entitas;
using Entitas.Unity;
using UnityEngine;
namespace IniterationExample {
/// <summary>
/// 添加视图层的系统
/// </summary>
public class AddViewSystem : ReactiveSystem<GameEntity> {
private Transform _parent;
private Contexts _contexts;
public AddViewSystem(Contexts contexts ) :base (contexts.game)
{
_parent = new GameObject("ViewParent").transform;
_contexts = contexts;
}
/// <summary>
/// 触发器
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
//这里是添加图片的相应 要吧View 改为Sprite
return context.CreateCollector(GameMatcher.IniterationExampleSprite);
}
protected override bool Filter(GameEntity entity)
{
// 检查sprite 条件是没有view组件的时候 添加组件 如果没有添加View视图
return entity.hasIniterationExampleSprite && ! entity.hasIniterationExampleView;
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entity in entities)
{
GameObject go = new GameObject("View");
go.transform.SetParent(_parent);
//关联Unity 和 View视图
go.Link(entity) ;
//go.Link(entity,_contexts) ;
//添加View视图
entity.AddIniterationExampleView(go.transform);
}
}
}
}
- 还有情况问题的话就是GameFeature构造函数的顺序可能会出现其他问题 如果出现 自行调换顺序
- 这时候我们在system文件夹下添加PositionSystem 添加命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 位置变换系统
/// </summary>
public class PositionSystem : ReactiveSystem<GameEntity>
{
public PositionSystem(Contexts contexts):base(contexts.game)
{
}
protected override bool Filter(GameEntity entity)
{
return entity.hasIniterationExamplePosition;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExamplePosition);
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entitie in entities)
{
entitie.initerationExampleView.viewTrans.position = entitie.initerationExamplePosition.position;
}
}
}
}
- 修改 CreateSystem类 把position添加到positionComponent的位置
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 创建实体系统 监听鼠标点击 继承ReactiveSystem<InputEntity>
/// </summary>
public class CreateSystem : ReactiveSystem<InputEntity>
{
/// <summary>
/// 获取Game的上下文 通过GameContext对象创建
/// </summary>
private GameContext _gameCOntext;
public CreateSystem( Contexts contexts ):base(contexts.input)
{
_gameCOntext = contexts.game;
}
protected override bool Filter(InputEntity entity)
{
//判断是否含有mouse组件 是否是左键按下
return (entity.hasIniterationExampleMouse)
&& (entity.initerationExampleMouse.mouse==MouseButton.LEFT)
&& (entity.initerationExampleMouse.mouseEvent == MouseButtonEvent.DOWN);
}
protected override ICollector<InputEntity> GetTrigger(IContext<InputEntity> context)
{
return context.CreateCollector(InputMatcher.IniterationExampleMouse);
}
protected override void Execute(List<InputEntity> entities)
{
foreach (InputEntity entitie in entities)
{
//在这里创建的是一个Game对象 所以需要获取上下文
var gameEntity= _gameCOntext.CreateEntity();
//添加Sprite 添加的Sprite的名字
gameEntity.AddIniterationExampleSprite("006tCxXily1fz4ran8lweg308c09xx6v");
//屏幕坐标转换为世界坐标
Vector2 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
gameEntity.AddIniterationExamplePosition(worldPos);
gameEntity.isIniterationExampleMoveComplete = true;
}
}
}
}
- 再把GameFeature类添加PositionSystem
namespace IniterationExample
{
public class GameFeature : Feature
{
public GameFeature(Contexts contexts)
{
Add(new AddViewSystem(contexts));
Add(new RenderSpriteSystem(contexts));
Add(new PositionSystem(contexts));
}
}
}
- 然后改为正交相机
- 这时候就能正常运行了
接下来我们学习 图片移动
- 我们在Component文件夹内 MoveCompleteComponent 类 和MoveComponent类 命名空间和 变量都添加
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 用于标记物体运动结束的组件
/// </summary>
public class MoveCompleteComponent :IComponent
{
}
}
using Entitas;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace IniterationExample
{
/// <summary>
/// 移动组件
/// </summary>
public class MoveComponent : IComponent
{
/// <summary>
/// 目标位置
/// </summary>
public Vector3 targetPos;
}
}
- 然后生成代码
然后修改MoveSystem类 修改完成后添加在GameFeature类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
using DG.Tweening;
namespace IniterationExample
{
/// <summary>
/// 移动系统
/// </summary>
public class MoveSystem : ReactiveSystem<GameEntity>
{
public MoveSystem(Contexts contexts): base(contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
foreach (var entitie in entities)
{
entitie.initerationExampleView.viewTrans.DOMove(entitie.initerationExampleMove.targetPos,3);
}
}
protected override bool Filter(GameEntity entity)
{
return entity.hasIniterationExampleMove
&& entity.isIniterationExampleMoveComplete == true
&& entity.hasIniterationExampleView;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleMove);
}
}
}
- 接着我们新建鼠标右键的时候 图片会移动到target目标位置
- 正在system类下添加StartMove 右键单击会移动到点击的位置 写完以后记得加载Feature脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 相应鼠标右键, 移动物体
/// </summary>
public class StartMoveSystem : ReactiveSystem<InputEntity>
{
public GameContext _gameCOnext;
private IGroup<GameEntity> _moveGroup;
public StartMoveSystem(Contexts contexts):base(contexts.input)
{
_gameCOnext = contexts.game;
_moveGroup = contexts.game.GetGroup(GameMatcher.IniterationExampleView);
}
protected override void Execute(List<InputEntity> entities)
{
foreach (InputEntity entitie in entities)
{
Vector2 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
foreach (GameEntity gameEntity in _moveGroup)
{
///使用ReplaceIniterationExampleMove AddIniterationExampleMove 好 是因为rep内部有检测是否重复的功能
gameEntity.ReplaceIniterationExampleMove(worldPos);
}
}
}
protected override bool Filter(InputEntity entity)
{
//判断是否含有mouse组件 是否是右键按下
return (entity.hasIniterationExampleMouse)
&& (entity.initerationExampleMouse.mouse == MouseButton.RIGHT)
&& (entity.initerationExampleMouse.mouseEvent == MouseButtonEvent.DOWN);
}
protected override ICollector<InputEntity> GetTrigger(IContext<InputEntity> context)
{
return context.CreateCollector(InputMatcher.IniterationExampleMouse);
}
}
}
- 接下来我们创建转向后移动到右键点击的位置
- 在System文件夹下创建脚本DirectionSystem类 写上命名空间 添加到GameFeature类中
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 方向系统
/// </summary>
public class DirectionSystem : ReactiveSystem<GameEntity>
{
public DirectionSystem(Contexts contexts):base(contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entitie in entities)
{
Transform view = entitie.initerationExampleView.viewTrans;
Vector3 targetPos= entitie.initerationExampleMove.targetPos;
Vector3 direction = (targetPos - view.position).normalized;
Quaternion angleOffset = Quaternion.FromToRotation(view.up, direction);
view.rotation *= angleOffset;
}
}
protected override bool Filter(GameEntity entity)
{
return entity.isIniterationExampleMoveComplete
&& entity.hasIniterationExampleMove
&& entity.hasIniterationExampleView
&& entity.hasIniterationExampleMove;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleMove);
}
}
}
namespace IniterationExample
{
public class GameFeature : Feature
{
public GameFeature(Contexts contexts)
{
Add(new AddViewSystem(contexts));
Add(new RenderSpriteSystem(contexts));
Add(new PositionSystem(contexts));
Add(new MoveSystem(contexts));
Add(new StartMoveSystem(contexts));
Add(new DirectionSystem(contexts));
}
}
}
本节完。。
接下来我们用第二种方法 一样能实现小火箭的转向
这回是以方向组件的形式改变的
- 添加ChangeRotationSystem类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 改变方向系统
/// </summary>
public class ChangeRotationSystem : ReactiveSystem<GameEntity>
{
public ChangeRotationSystem(Contexts contexts):base(contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entitie in entities)
{
Transform view = entitie.initerationExampleView.viewTrans;
var angle = entitie.initerationExampleDirection.direction;
view.rotation = Quaternion.AngleAxis(angle-90 ,Vector3.forward);
}
}
protected override bool Filter(GameEntity entity)
{
return entity.hasIniterationExampleDirection
&& entity.hasIniterationExampleView;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleDirection);
}
}
}
修改DirectionSystem类中的Execute方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Entitas;
namespace IniterationExample
{
/// <summary>
/// 方向系统
/// </summary>
public class DirectionSystem : ReactiveSystem<GameEntity>
{
public DirectionSystem(Contexts contexts):base(contexts.game)
{
}
protected override void Execute(List<GameEntity> entities)
{
foreach (GameEntity entitie in entities)
{
Transform view = entitie.initerationExampleView.viewTrans;
Vector3 targetPos= entitie.initerationExampleMove.targetPos;
Vector3 direction = (targetPos - view.position).normalized;
//四元数版本
// Quaternion angleOffset = Quaternion.FromToRotation(view.up, direction);
// view.rotation *= angleOffset;
//普通版本 角度乘以弧度??
float angle = Mathf.Atan2(direction.y, direction.x) *Mathf.Rad2Deg;
entitie.ReplaceIniterationExampleDirection(angle);
}
}
protected override bool Filter(GameEntity entity)
{
return entity.isIniterationExampleMoveComplete
&& entity.hasIniterationExampleMove
&& entity.hasIniterationExampleView
&& entity.hasIniterationExampleMove;
}
protected override ICollector<GameEntity> GetTrigger(IContext<GameEntity> context)
{
return context.CreateCollector(GameMatcher.IniterationExampleMove);
}
}
}
在GameFacade类中添加改变方向的system类
namespace IniterationExample
{
public class GameFeature : Feature
{
public GameFeature(Contexts contexts)
{
Add(new AddViewSystem(contexts));
Add(new RenderSpriteSystem(contexts));
Add(new PositionSystem(contexts));
Add(new MoveSystem(contexts));
Add(new StartMoveSystem(contexts));
//四元数版本在DirectionStstem 是在这个里面直接改变方向
Add(new DirectionSystem(contexts));
//普通版本 通过组件的形式改变方向
Add(new ChangeRotationSystem(contexts));
}
}
}