当前位置: 首页 > 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.hskmm.com/?act=detail&tid=23645

相关文章:

  • 《咳咳,未来编程大师,顶尖程序员的第一条博客》
  • CSP-JF36
  • 超越炒作:使用Agentic AI构建系统架构
  • K个节点的组内逆序调整
  • 【任务】自然语言处理——情感分析 <上>
  • 文件目录
  • 【Azure App Service】Root CA on App Service
  • QOJ #8147. Math Exam 题解
  • 10.03模拟赛t3
  • 国庆梦熊集训做题记录
  • 文件的逻辑结构
  • python 肘部法则,判点聚类分为几类,K-means聚类分析
  • AT_abc315_f [ABC315F] Shortcuts
  • 紫外UV固化太阳光模拟器的原理 - 教程
  • 每日一题
  • P5709 【深基2.习6】Apples Prologue / 苹果和虫子
  • 问题表 - microsoft
  • Leetcode 736. Lisp 语法解析
  • Day10.1
  • SolarWinds Web Help Desk远程代码执行漏洞分析
  • Aria2安装
  • 正则表达式学习
  • 深入解析:[特殊字符]函数指针:C语言的动态灵魂,嵌入式的超能力(202589)
  • 《电路基础》第八章学习笔记
  • 《电路基础》第七章学习笔记
  • LLM大模型:deepseek sparse attention是个啥?
  • Day10
  • 软著申请全流程材料模板,2025年最新模板汇总! - 实践
  • 手把手教你使用 Docker 部署 Nginx 教程
  • CF2129 CF1951 VP 记录