当前位置: 首页 > news >正文

unity面向组合开发二:EC的代码实践

一、ECCore

需要在Unity项目中使用插件:UniRx,通过UniRx代替Mono的Update,Mono下做轮询性能消耗会有点大。

EntityMono代码:

using System;
using System.Collections.Generic;
using EC;
using UniRx;
using UnityEngine;namespace ECCore
{public abstract class EntityMono : MonoBehaviour{private readonly List<CapBase> caps = new();private IDisposable updateSubscription;public CapBase AddCap<T>() where T : CapBase, new(){// 检查是否已经添加了相同类型的 CapBase 实例if (caps.Exists(cap => cap is T)){Debug.LogWarning($"{typeof(T).Name} 已经添加了!");return null;}// 创建新的实例并添加到 caps 列表中var c = (T)System.Activator.CreateInstance(typeof(T));caps.Add(c);LogErrorByCap(c);return c;}public T GetCap<T>() where T : CapBase{return (T)caps.Find(cap => cap is T);}public void RemoveCap(CapBase cap){caps.Remove(cap);}private void Awake(){OnInit();updateSubscription?.Dispose();updateSubscription = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(0.01f)).Subscribe(_ => OnUpdate());}private void OnDestroy(){updateSubscription?.Dispose();OnClear();}// entity生命周期protected abstract void OnInit();protected abstract void OnUpdate();protected abstract void OnClear();void OnCollisionEnter(Collision collision){GetCap<OnColliderCapBase>()?.OnCollisionEnter(collision);}void OnCollisionStay(Collision collision){GetCap<OnColliderCapBase>()?.OnCollisionStay(collision);}void OnCollisionExit(Collision collision){GetCap<OnColliderCapBase>()?.OnCollisionExit(collision);}void OnTriggerEnter(Collider otherCollision){GetCap<OnTriggerCapBase>()?.OnTriggerEnter(otherCollision);}void OnTriggerStay(Collider otherCollision){GetCap<OnTriggerCapBase>()?.OnTriggerStay(otherCollision);}void OnTriggerExit(Collider otherCollision){GetCap<OnTriggerCapBase>()?.OnTriggerExit(otherCollision);}private void LogErrorByCap(CapBase cap){switch (cap){case OnColliderCapBase onColliderCapBase:if (GetComponent<Collider>() == null){Debug.LogError("碰撞能力实体没有添加Collider:"+ name);}break;case OnTriggerCapBase onTriggerCapBase:var colliderComponent = GetComponent<Collider>();if (colliderComponent == null)Debug.LogError("触发能力实体没有添加Collider:"+ name);else{if(!colliderComponent.isTrigger)Debug.LogError("触发能力实体没有勾选isTrigger:"+ name);}break;}}}
}

CapBase代码:

namespace ECCore
{public abstract class CapBase{public abstract void InitData(EntityMono initEntity);public abstract void OnClear();}
}

二、OnColliderCapBase和OnTriggerCapBase 碰撞能力基类和触发能力基类

碰撞和触发需要依赖Mono下内部方法,所以给碰撞能力和触发能力抽象出基类方法。

OnColliderCapBase代码:

using ECCore;
using UnityEngine;namespace EC
{public abstract class OnColliderCapBase : CapBase{public abstract void OnCollisionEnter(Collision collision);public abstract void OnCollisionStay(Collision collision);public abstract void OnCollisionExit(Collision collision);}
}

OnTriggerCapBase代码:

using ECCore;
using UnityEngine;namespace EC
{public abstract class OnTriggerCapBase : CapBase{public abstract void OnTriggerEnter(Collider otherCollision);public abstract void OnTriggerStay(Collider otherCollision);public abstract void OnTriggerExit(Collider otherCollision);}
}

 三、GameEC

PlayerEntity代码:

using ECCore;
using UnityEngine;namespace EC
{public class PlayerEntity : EntityMono{public float mouseSensitivity = 10.0f;protected override void OnInit(){// AddCap<InputCap>().InitData(this);AddCap<MoveCap>().InitData(this);AddCap<GravityCap>().InitData(this);GetCap<GravityCap>()?.SetGravity(10);AddCap<LookCap>().InitData(this);AddCap<PlayerOnColliderCap>().InitData(this);}protected override void OnUpdate(){// 输入先这么做 不知道要不要加Cap 思考中.....Vector3 movement = Vector3.zero;Vector2 look = Vector2.zero;movement.x = Input.GetAxis("Horizontal");movement.z = Input.GetAxis("Vertical");look.x = Input.GetAxis("Mouse X");look.y = Input.GetAxis("Mouse Y");GetCap<LookCap>()?.Look(look, mouseSensitivity);GetCap<MoveCap>()?.Move(movement);}protected override void OnClear(){}}}

MoveCap代码:

using UnityEngine;
using ECCore;namespace EC
{public class MoveCap : CapBase{private EntityMono entity;public override void InitData(EntityMono initEntity){entity = initEntity;}public void Move(Vector3 pos){pos = entity.transform.TransformDirection(pos);entity.transform.position += pos;}public override void OnClear(){entity = null;}}
}
http://www.jsqmd.com/news/7678/

相关文章:

  • 《咳咳,未来编程大师,顶尖程序员的第一条博客》
  • CSP-JF36
  • 超越炒作:使用Agentic AI构建系统架构
  • 【进入便捷的系统不解决问题】ubuntu开机出现‘系统出错且无法恢复。请联系系统管理员’
  • K个节点的组内逆序调整
  • 【任务】自然语言处理——情感分析 <上>
  • 2025华为 OD 机试2025C卷 机考真题库清单(全真题库)含考点说明(OD上机考试2025年C卷) - 教程
  • QOJ #8147. Math Exam 题解
  • 10.03模拟赛t3
  • 国庆梦熊集训做题记录
  • 完整教程:缓存总线是什么?
  • 兰博平台: 星云抽卡豪华版. 作者acc177
  • 打工人日报#20250927 - 教程
  • GPT-5 撼动量子计算:AI 在科研领域的颠覆性应用 - 实践
  • python 肘部法则,判点聚类分为几类,K-means聚类分析
  • AT_abc315_f [ABC315F] Shortcuts
  • 紫外UV固化太阳光模拟器的原理 - 教程
  • 《系统与软件工程功能规模测量IFPUG手段》(GB/T42449-2023)标准解读
  • 实用指南:无人机图传及组网功能如何实现?适用频段与传输模块选择全攻略
  • 每日一题
  • P5709 【深基2.习6】Apples Prologue / 苹果和虫子
  • 问题表 - microsoft
  • KD论文阅读 - 实践
  • Leetcode 736. Lisp 语法解析
  • Day10.1
  • 随想八
  • 【600】
  • SolarWinds Web Help Desk远程代码执行漏洞分析
  • Aria2安装
  • 正则表达式学习