// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using Unity.Mathematics; using UnityEngine; namespace MagicaCloth { /// /// 物理チーム /// 特定のパーティクルと機能を1つのチームとして管理します。 /// 当たり判定はチーム内部のパーティクルに対してのみ有効です。 /// これによりチームごとに独立した環境を構築することが可能です。 /// 例:キャラクタAとBは当たり判定が干渉しないようにする /// public abstract class PhysicsTeam : CoreComponent { [SerializeField] protected PhysicsTeamData teamData = new PhysicsTeamData(); /// /// ユーザー設定ブレンド率 /// [SerializeField] private float userBlendWeight = 1.0f; /// /// 更新モード /// public enum TeamUpdateMode { Normal = 0, UnityPhysics = 1, } [SerializeField] private TeamUpdateMode updateMode = TeamUpdateMode.Normal; /// /// カリングモード(数値が高いほど優先) /// public enum TeamCullingMode { Reset = 0, Pause = 10, Off = 100, } [SerializeField] private TeamCullingMode cullingMode = TeamCullingMode.Reset; /// /// スキニングモード /// さらにNone以外の設定では計算時にアニメーション化された姿勢を利用するようになる(旧UseAnimatedDistanceフラグ) /// public enum TeamSkinningMode { None = 0, UserAnimation = 1, //GenerateFromBones = 2, } [SerializeField] private TeamSkinningMode skinningMode = TeamSkinningMode.UserAnimation; //[SerializeField] //private bool skinningUpdateFixed = false; //========================================================================================= /// /// この物理チームのID /// protected int teamId = -1; /// /// この物理チームで管理するパーティクル /// protected ChunkData particleChunk = new ChunkData(); /// /// 速度影響/ワープ判定トランスフォーム /// protected Transform influenceTarget; //========================================================================================= /// /// データハッシュを求める /// /// public override int GetDataHash() { int hash = teamData.GetDataHash(); return hash; } //========================================================================================= public int TeamId { get { return teamId; } } public PhysicsTeamData TeamData { get { return teamData; } } public ChunkData ParticleChunk { get { return particleChunk; } } public Transform InfluenceTarget { set { influenceTarget = value; } get { return influenceTarget; } } public float UserBlendWeight { get { return userBlendWeight; } set { userBlendWeight = Mathf.Clamp01(value); } } public TeamUpdateMode UpdateMode { get { return updateMode; } protected set { updateMode = value; } } public TeamCullingMode CullingMode { get { return cullingMode; } set { cullingMode = value; } } public TeamSkinningMode SkinningMode { get => skinningMode; set => skinningMode = value; } //public bool SkinningUpdateFixed //{ // get => skinningUpdateFixed; // set => skinningUpdateFixed = value; //} /// /// 計算に使用する距離/回転を常にアニメーション後の姿勢から取得するかどうか /// internal bool UseAnimatedPose { get { //return skinningMode == TeamSkinningMode.UserAnimation || skinningMode == TeamSkinningMode.GenerateFromBones; return skinningMode == TeamSkinningMode.UserAnimation; } } //========================================================================================= protected override void OnInit() { // チーム作成 teamId = MagicaPhysicsManager.Instance.Team.CreateTeam(this, 0); TeamData.Init(TeamId); } /// /// 破棄 /// 通常はOnDestroy()で呼ぶ /// protected override void OnDispose() { // 破棄 if (TeamId >= 0) { TeamData.Dispose(TeamId); // チーム削除 if (MagicaPhysicsManager.IsInstance()) MagicaPhysicsManager.Instance.Team.RemoveTeam(teamId); } } /// /// 更新 /// protected override void OnUpdate() { } /// /// 実行状態に入った場合に呼ばれます /// protected override void OnActive() { // チーム有効化 MagicaPhysicsManager.Instance.Team.SetEnable(teamId, true); } /// /// 実行状態から抜けた場合に呼ばれます /// protected override void OnInactive() { if (MagicaPhysicsManager.IsInstance()) { // チーム無効化 MagicaPhysicsManager.Instance.Team.SetEnable(teamId, false); } } //========================================================================================= /// /// 実行状態を取得 /// /// public bool IsActive() { if (MagicaPhysicsManager.IsInstance()) return MagicaPhysicsManager.Instance.Team.IsActive(teamId); else return false; } /// /// チームデータが存在するか判定 /// /// public bool IsValid() { if (MagicaPhysicsManager.IsInstance()) return MagicaPhysicsManager.Instance.Team.IsValid(teamId); else return false; } //========================================================================================= /// /// パーティクルを1つ追加 /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// //public ChunkData CreateParticle( // uint flag, // int team, // float3 wpos, quaternion wrot, // float3 lpos, quaternion lrot, // float depth, // float radius, // Transform target, float3 targetLocalPos // ) //{ // var c = MagicaPhysicsManager.Instance.Particle.CreateParticle( // flag, // team, // wpos, wrot, // lpos, lrot, // depth, // radius, // target, targetLocalPos // ); // // チームパーティクルとして管理する // particleChunk = c; // return c; //} /// /// パーティクルをグループで追加 /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public ChunkData CreateParticle( int team, int count, System.Func funcFlag, System.Func funcWpos, System.Func funcWrot, System.Func funcDepth, System.Func funcRadius, System.Func funcTargetLocalPos ) { var c = MagicaPhysicsManager.Instance.Particle.CreateParticle( team, count, funcFlag, funcWpos, funcWrot, funcDepth, funcRadius, funcTargetLocalPos ); // チームパーティクルとして管理する particleChunk = c; return c; } /// /// パーティクル削除(全体のみ) /// public void RemoveAllParticle() { MagicaPhysicsManager.Instance.Particle.RemoveParticle(particleChunk); particleChunk.Clear(); } /// /// 管理するパーティクルを有効化する /// public void EnableParticle( System.Func funcTarget, System.Func funcLpos, System.Func funcLrot ) { MagicaPhysicsManager.Instance.Particle.SetEnable(particleChunk, true, funcTarget, funcLpos, funcLrot); } /// /// 管理するパーティクルを無効化する /// public void DisableParticle( System.Func funcTarget, System.Func funcLpos, System.Func funcLrot ) { if (MagicaPhysicsManager.IsInstance()) { MagicaPhysicsManager.Instance.Particle.SetEnable(particleChunk, false, funcTarget, funcLpos, funcLrot); } } //========================================================================================= /// /// 現在のデータが正常(実行できる状態)か返す /// /// public override Define.Error VerifyData() { return base.VerifyData(); } } }