using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using BITKit; using System.IO; using System.Linq; using BITFALL.Items; using UnityEditor; using UnityEngine.UIElements; namespace BITFALL.Items { public class WorldItem : MonoBehaviour,IBasicItem,IDescription,IDisposable { #region 本地字段 [Header(nameof(IAddressable))] [SerializeField] private ulong addressableId = (ulong)Guid.NewGuid().GetHashCode(); [Header(Constant.Header.Components)] [SerializeField] private new Rigidbody rigidbody; [Header(Constant.Header.Settings)] [SerializeField]private ScriptableItem asset; [Header(Constant.Header.Optional)] [SerializeReference, SubclassSelector] private IProperty[] initialProperties; #endregion #region 接口实现 public int Value => asset.Value; public ulong AddressableId { get=>addressableId; set { addressableId = value; #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif } } public int Id { get { if (_id is 0)_id = GetInstanceID(); return _id; } set => _id = value; } private int _id; public string Name => asset.Name; public string Description => asset.Description; public ItemQuality Quality => asset.Quality; public string AddressablePath => asset.AddressablePath; internal Property property { get { if (BITAppForUnity.IsPlaying is false |!asset || asset.RuntimeProperties is null) { return (initialProperties is null)? new Property() : new Property(initialProperties); } if(_property is not null) return _property; var list = new List(); if (asset && asset.RuntimeProperties is not null) { list.AddRange(asset.RuntimeProperties.Select(x=>x is ICloneable cloneable ? cloneable.Clone().As() : x)); } if(initialProperties is not null) { list.AddRange(initialProperties); } return _property= new Property(list.ToArray()); } set=>_property=value; } private Property _property; private object _rigidbody; public bool Contains() => property.Contains(); public T GetOrAddProperty(Func addFactory) => property.GetOrAddProperty(addFactory); public T GetOrCreateProperty() => property.GetOrCreateProperty(); public object[] GetProperties() => property.GetProperties(); public bool TryGetProperty(out T value) => property.TryGetProperty(out value); public bool TryRemoveProperty() => property.TryRemoveProperty(); public bool TrySetProperty(T value) => property.TrySetProperty(value); public void Read(BinaryReader r) { throw new NotImplementedException(); } public void Write(BinaryWriter w) { throw new NotImplementedException(); } public bool CopyItemsFrom(IBasicItem item) { Id=item.Id; CopyPropertiesFrom(item); return true; } public bool ClearProperties()=>property.ClearProperties(); public bool CopyPropertiesFrom(IPropertable propertable)=>property.CopyPropertiesFrom(propertable); #endregion #region 本地方法 public ScriptableItem Scriptable => asset; public Rigidbody Rigidbody => rigidbody; public ManagedItem Pick() { var managedItem = new ManagedItem(); managedItem.CopyItemsFrom(this); return managedItem; } public void Picked() { Destroy(gameObject); } #endregion public object Clone() { return Pick(); } private void Start() { if (isInitialized is false) { WorldItemService.Register(this); isInitialized = true; } destroyCancellationToken.Register(() => { if (isDisposed is false) WorldItemService.Unregister(this); }); } private bool isInitialized; private bool isDisposed; public void WaitForInitializationComplete() { if (isInitialized) return; Start(); isInitialized = true; } public void Dispose() { isDisposed = true; if (this) { property = null; initialProperties = null; Destroy(gameObject); } } } #if UNITY_EDITOR [UnityEditor.CustomEditor(typeof(WorldItem))] public class WorldItemInspector:BITInspector { public override VisualElement CreateInspectorGUI() { FillDefaultInspector(); CreateSubTitle(Constant.Header.Debug); var label = root.Create