├── LICENSE ├── README.md └── Scripts ├── Const.cs ├── Data ├── Audio │ ├── AudioClipData.cs │ ├── AudioResource.cs │ ├── AudioType.cs │ └── ButtonSePreset.cs ├── Monster │ ├── MonsterGenerateSet.cs │ ├── MonsterMasterData.cs │ ├── MonsterMasterDataRepository.cs │ ├── MonsterMasterDataStoreSource.cs │ └── MonsterParameter.cs ├── Skill │ ├── Abnormality │ │ ├── AbnormalityEffectMasterData.cs │ │ └── AbnormalityType.cs │ ├── NknockbackData.cs │ ├── SkillMasterData.cs │ ├── SkillRangeTargetType.cs │ ├── SkillTargetType.cs │ └── SkillType.cs ├── Stage │ ├── StageInfo.cs │ ├── StageMasterData.cs │ ├── StageMasterDataRepository.cs │ ├── StageMasterDataStoreSource.cs │ └── StageMonsterData.cs └── StageScene │ ├── SceneObject.cs │ ├── StageSceneData.cs │ ├── StageSceneDataStoreSource.cs │ └── StageSceneRepository.cs ├── Domain ├── Abnomality │ ├── AbnormalityEffectCalculator.cs │ ├── AbnormalityEffectCollection.cs │ ├── AbnormalityTypeCollection.cs │ └── IAbnormalityEffectState.cs ├── ActiveSkill │ ├── ActiveSkill.cs │ ├── KnockbackEffect.cs │ ├── SkillTarget.cs │ ├── StanEffect.cs │ └── StanEffectState.cs ├── Audio │ ├── AudioPlayer.cs │ ├── AudioResourceLoader.cs │ ├── AudioSettingsService.cs │ └── CreateAudioSettingViewModelUseCase.cs ├── Battle │ ├── AllyPlacedMonsterUseCase.cs │ ├── BattleReset.cs │ ├── BattleShutdownUseCase.cs │ ├── BattleTerminationCalculator.cs │ ├── CreateAllyBattleMonsterUseCase.cs │ ├── CreateEnemyBattleMonsterUseCase.cs │ ├── CreateMonsterSelectViewModelUseCase.cs │ ├── History │ │ ├── BattleMonsterPlaceHistory.cs │ │ ├── BattleMonsterPlaceRecord.cs │ │ ├── HistoryRecordData.cs │ │ ├── PlaceRecordFactory.cs │ │ └── PlaceRecordUseCase.cs │ ├── Knockback.cs │ ├── KnockbackService.cs │ ├── Monster │ │ ├── BattleMonster.cs │ │ ├── BattleMonsterAttackUseCase.cs │ │ ├── BattleMonsterContainer.cs │ │ ├── BattleMonsterContainerService.cs │ │ ├── BattleMonsterFactory.cs │ │ ├── BattleMonsterId.cs │ │ ├── BattleMonsterPresenterContainer.cs │ │ └── BattleMonsterPresenterFactory.cs │ ├── Place │ │ ├── FindPlacedMonsterUseCase.cs │ │ └── JudgeMonsterPlaceableUseCase.cs │ ├── Result │ │ ├── BattleDefeatCondition.cs │ │ ├── BattleResult.cs │ │ ├── BattleResultCalculator.cs │ │ ├── BattleResultNextAction.cs │ │ └── BattleVictoryCondition.cs │ └── Time │ │ └── TimeControlUseCase.cs ├── Capture │ ├── BattleCaptureSet.cs │ ├── CaptureTextureContainer.cs │ └── CaptureUseCase.cs ├── Costs │ ├── CostStatus.cs │ └── PlayerConsumeCostUseCase.cs ├── Debugger │ └── BattleDebug.cs ├── HelpAutoDisplayUseCase.cs ├── Monster │ └── MonsterMasterDataService.cs ├── MyMath.cs ├── PlayerStatus.cs ├── Scenes │ └── SceneLoader.cs ├── SkillCalculator │ ├── BattleMonsterAttackCalculator.cs │ ├── BattleMonsterHealCalculator.cs │ └── SkillTargetCalculator.cs └── Stage │ ├── GetStageCostUseCase.cs │ ├── GetStageInfoUseCase.cs │ ├── LoadStageSceneUseCase.cs │ ├── NextStageUseCase.cs │ ├── StageSceneService.cs │ └── StageSituation.cs ├── Editor ├── ButtonSePlayerEditor.cs ├── ButtonSePresetEditor.cs ├── MasterDataAssetProcessor.cs ├── MonsterMasterDataAnalyseEditor.cs ├── MonsterMasterDataAssetProcess.cs ├── MonsterMasterDataEditor.cs ├── SceneObjectEditor.cs ├── StageMasterDataAssetProcess.cs └── StageMasterDataEditor.cs ├── Extensions ├── DisposableExtensions.cs ├── EnumerableExtensions.cs └── Presenter.cs ├── Installer ├── AudioLifetimeScope.cs ├── EndingLifetimeScope.cs ├── InGameLifetimeScope.cs ├── LifetimeScopeBuilder.cs ├── RootLifetimeScope.cs └── TitleLifetimeScope.cs ├── Presentation ├── Abnormality │ └── AbnormalityView.cs ├── Audio │ ├── AudioSettingPresenter.cs │ ├── AudioSettingView.cs │ ├── BgmPlayer.cs │ ├── BgmSettingView.cs │ ├── SePlayer.cs │ ├── SePlayerForButton.cs │ └── SeSettingView.cs ├── Battle │ ├── BattleInitializer.cs │ ├── BattlePerformPresenter.cs │ ├── CameraController.cs │ ├── EnemyGeneratePresenter.cs │ ├── Help │ │ ├── HelpPresenter.cs │ │ └── HelpView.cs │ ├── Hp │ │ └── HpGaugeView.cs │ ├── InBattleTimeControlView.cs │ ├── InBattleUIView.cs │ ├── InGameLoop.cs │ ├── MonsterDetail │ │ ├── CreateMonsterDetailViewModelUseCase.cs │ │ ├── MonsterDetailPresenter.cs │ │ └── MonsterDetailView.cs │ ├── PlayerGeneratePresenter.cs │ ├── Ready │ │ ├── BattleReadyPerformPresenter.cs │ │ └── BattleReadyPerformView.cs │ ├── Result │ │ ├── BattleResultFailedPerformView.cs │ │ ├── BattleResultPresenter.cs │ │ ├── BattleResultVictoryPerformView.cs │ │ ├── ResultBackgroundPerformView.cs │ │ └── ResultVirtualCamera.cs │ ├── Start │ │ ├── BattleStartPerformPresenter.cs │ │ └── BattleStartPerformView.cs │ └── TimeControlPresenter.cs ├── BattleMonster │ ├── BattleMonsterPrefabView.cs │ ├── BattleMonsterPresenter.cs │ ├── BattleMonsterView.cs │ ├── MonsterDamagePerformView.cs │ └── MonsterHealPerformView.cs ├── Costs │ ├── CurrentCostPresenter.cs │ └── CurrentCostView.cs ├── Ending │ ├── CreateEndingCardViewModel.cs │ ├── EndingCardElementView.cs │ ├── EndingCardView.cs │ ├── EndingPresenter.cs │ └── EndingView.cs ├── Gizmo │ ├── GizmoDrawer.cs │ └── IOnDrawGizmosHandler.cs ├── License │ ├── GetLicenseTextUseCase.cs │ ├── LicensePresenter.cs │ └── LicenseView.cs ├── MonsterSelect │ ├── MonsterSelectElementView.cs │ ├── MonsterSelectPresenter.cs │ └── MonsterSelectView.cs ├── PlacePoint │ ├── PlacePointPresenter.cs │ └── PlacePointView.cs ├── Shaders │ └── UnscaledShaderTime.cs ├── Title │ ├── TitleMenuView.cs │ └── TitlePresenter.cs ├── Transition │ ├── TransitionPresenter.cs │ └── TransitionView.cs └── UI │ ├── ButtonAnimation.cs │ ├── ButtonSePlayer.cs │ └── Toggle.cs └── Structure ├── AudioVolume.cs ├── Cost.cs ├── Heal.cs ├── Hp.cs ├── MonsterId.cs └── StageId.cs /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 kameffee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | Unity 1週間ゲームジャム お題「かわる」 4 | 5 | [ペーパー百鬼](https://unityroom.com/games/paperhyakki)のソースコードのみを抽出したリポジトリです。 6 | 7 | 8 | ## External Assets 9 | 10 | - [VContainer](https://github.com/hadashiA/VContainer) 11 | - [R3](https://github.com/Cysharp/R3) 12 | - [UniTask](https://github.com/Cysharp/UniTask) 13 | - [DOTween Pro](http://dotween.demigiant.com) -------------------------------------------------------------------------------- /Scripts/Const.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403 4 | { 5 | public static class Const 6 | { 7 | public const int LayerIdMonsterCollider = 6; 8 | public static LayerMask LayerMaskMonsterCollider = 1 << LayerIdMonsterCollider; 9 | 10 | public static class Scene 11 | { 12 | public const string Title = "Title"; 13 | public const string InGame = "InGame"; 14 | public const string Ending = "Ending"; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Data/Audio/AudioClipData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [Serializable] 7 | public class AudioClipData 8 | { 9 | [SerializeField] 10 | private string _id; 11 | 12 | [SerializeField] 13 | private AudioClip _clip; 14 | 15 | public string Id => _id; 16 | public AudioClip Clip => _clip; 17 | } 18 | } -------------------------------------------------------------------------------- /Scripts/Data/Audio/AudioResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace Unity1week202403.Data 7 | { 8 | [CreateAssetMenu(fileName = "AudioResource", menuName = "Audio/AudioResource")] 9 | public class AudioResource : ScriptableObject 10 | { 11 | [SerializeField] 12 | private AudioClipData[] _bgmAudioDatas; 13 | 14 | [SerializeField] 15 | private AudioClipData[] _seAudioDatas; 16 | 17 | public AudioClipData Get(AudioType audioType, string id) 18 | { 19 | return audioType switch 20 | { 21 | AudioType.Bgm => GetBgm(id), 22 | AudioType.Se => GetSe(id), 23 | _ => throw new ArgumentOutOfRangeException(nameof(audioType), audioType, null) 24 | }; 25 | } 26 | 27 | private AudioClipData GetSe(string id) 28 | { 29 | var data = _seAudioDatas.FirstOrDefault(data => data.Id.Equals(id)); 30 | if (data == null) 31 | { 32 | throw new FileNotFoundException($"AudioClip is not found. id: {id}"); 33 | } 34 | 35 | return data; 36 | } 37 | 38 | private AudioClipData GetBgm(string id) 39 | { 40 | var data = _bgmAudioDatas.FirstOrDefault(data => data.Id.Equals(id)); 41 | if (data == null) 42 | { 43 | throw new FileNotFoundException($"AudioClip is not found. id: {id}"); 44 | } 45 | 46 | return data; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Scripts/Data/Audio/AudioType.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Data 2 | { 3 | public enum AudioType 4 | { 5 | Bgm, 6 | Se, 7 | } 8 | } -------------------------------------------------------------------------------- /Scripts/Data/Audio/ButtonSePreset.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | [CreateAssetMenu(menuName = "UI/ButtonSePreset", fileName = "ButtonSePreset_")] 6 | public class ButtonSePreset : ScriptableObject 7 | { 8 | [SerializeField] 9 | private AudioClip _hoverClip; 10 | 11 | [SerializeField] 12 | private AudioClip _clickClip; 13 | 14 | public AudioClip HoverClip => _hoverClip; 15 | public AudioClip ClickClip => _clickClip; 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Data/Monster/MonsterGenerateSet.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | public readonly struct MonsterGenerateSet 7 | { 8 | public MonsterId MonsterId { get; } 9 | public Vector3 Position { get; } 10 | public GameObject Prefab { get; } 11 | 12 | public MonsterGenerateSet(MonsterId monsterId, Vector3 position, GameObject prefab) 13 | { 14 | MonsterId = monsterId; 15 | Position = position; 16 | Prefab = prefab; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Scripts/Data/Monster/MonsterMasterData.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [CreateAssetMenu(fileName = "MonsterMasterData_", menuName = "Monster/MonsterMasterData", order = 0)] 7 | public class MonsterMasterData : ScriptableObject 8 | { 9 | public MonsterId Id => new(_id); 10 | public string Name => _name; 11 | public string BattleFeature => _battleFeature; 12 | public string Description => _description; 13 | public Cost Cost => new(_cost); 14 | public MonsterParameter Parameter => _parameter; 15 | public SkillMasterData SkillMasterData => _skillMasterData; 16 | public GameObject Prefab => _prefab; 17 | public int ZPosition => _zPosition; 18 | public Sprite Thumbnail => _thumbnail; 19 | public MonsterMasterData BigMonsterMasterData => _bigMonsterMasterData; 20 | 21 | [SerializeField] 22 | private int _id; 23 | 24 | [SerializeField] 25 | private string _name; 26 | 27 | [SerializeField] 28 | [TextArea(1, 2)] 29 | private string _battleFeature; 30 | 31 | [SerializeField] 32 | [TextArea(3, 4)] 33 | private string _description; 34 | 35 | [SerializeField] 36 | private int _cost = 100; 37 | 38 | [SerializeField] 39 | private MonsterParameter _parameter; 40 | 41 | [SerializeField] 42 | private SkillMasterData _skillMasterData; 43 | 44 | [SerializeField] 45 | private GameObject _prefab; 46 | 47 | [Range(0, 1000)] 48 | [SerializeField] 49 | private int _zPosition; 50 | 51 | [SerializeField] 52 | private Sprite _thumbnail; 53 | 54 | [SerializeField] 55 | private MonsterMasterData _bigMonsterMasterData; 56 | } 57 | } -------------------------------------------------------------------------------- /Scripts/Data/Monster/MonsterMasterDataRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | public class MonsterMasterDataRepository 7 | { 8 | private readonly MonsterMasterDataStoreSource _dataStoreSource; 9 | 10 | public MonsterMasterDataRepository(MonsterMasterDataStoreSource dataStoreSource) 11 | { 12 | _dataStoreSource = dataStoreSource; 13 | } 14 | 15 | public MonsterMasterData Get(MonsterId id) => _dataStoreSource.Data.FirstOrDefault(data => data.Id == id); 16 | 17 | public MonsterMasterData[] GetAll() => _dataStoreSource.Data; 18 | } 19 | } -------------------------------------------------------------------------------- /Scripts/Data/Monster/MonsterMasterDataStoreSource.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [CreateAssetMenu(fileName = "MonsterMasterDataStoreSource", menuName = "Monster/DataStoreSource", order = 0)] 7 | public class MonsterMasterDataStoreSource : ScriptableObject 8 | { 9 | public MonsterMasterData[] Data => _data; 10 | 11 | [SerializeField] 12 | private MonsterMasterData[] _data; 13 | 14 | public void Validate() 15 | { 16 | _data = _data.Distinct() 17 | .Where(data => data != null) 18 | .OrderBy(data => data.Id) 19 | .ToArray(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Scripts/Data/Monster/MonsterParameter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [Serializable] 7 | public class MonsterParameter 8 | { 9 | public int Hp => _hp; 10 | public int AttackPower => _attackPower; 11 | public float AttackRange => _attackRange; 12 | public float PreAttackTime => _preAttackFrame/60f; 13 | public float PostAttackTime => (_attackEndFrame - _preAttackFrame)/60f; 14 | public float MoveSpeed => _moveSpeed; 15 | 16 | [SerializeField] 17 | private int _hp = 1; 18 | 19 | [SerializeField] 20 | private int _attackPower = 1; 21 | 22 | [SerializeField] 23 | private float _attackRange = 1; 24 | 25 | [SerializeField] 26 | private int _preAttackFrame = 60; 27 | 28 | [SerializeField] 29 | private int _attackEndFrame = 120; 30 | 31 | [SerializeField] 32 | private float _moveSpeed = 1; 33 | } 34 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/Abnormality/AbnormalityEffectMasterData.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | [CreateAssetMenu(menuName = "Skill/AbnormalityEffect", fileName = "AbnormalityEffect_", order = 0)] 6 | public class AbnormalityEffectMasterData : ScriptableObject 7 | { 8 | public AbnormalityType AbnormalityType => _abnormalityType; 9 | public float StanTime => _stanTime; 10 | 11 | [Header("スタン効果")] 12 | [SerializeField] 13 | private AbnormalityType _abnormalityType; 14 | 15 | [SerializeField] 16 | private float _stanTime = 0; 17 | } 18 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/Abnormality/AbnormalityType.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Data 2 | { 3 | public enum AbnormalityType 4 | { 5 | Stan, 6 | } 7 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/NknockbackData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [Serializable] 7 | public class NknockbackData 8 | { 9 | public bool IsKnockback => _isNknockback; 10 | public float KnockbackPower => _knockbackPower; 11 | 12 | [SerializeField] 13 | private bool _isNknockback; 14 | 15 | [SerializeField] 16 | private float _knockbackPower; 17 | 18 | public NknockbackData(bool isNknockback, float knockbackPower) 19 | { 20 | _isNknockback = isNknockback; 21 | _knockbackPower = knockbackPower; 22 | } 23 | 24 | public static NknockbackData Default => new(false, 0); 25 | } 26 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/SkillMasterData.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | [CreateAssetMenu(menuName = "Skill/MasterData", fileName = "SkillMasterData", order = 0)] 6 | public class SkillMasterData : ScriptableObject 7 | { 8 | public SkillType SkillType => _skillType; 9 | public SkillTargetType SkillTargetType => _skillTargetType; 10 | public int Value => _value; 11 | public SkillRangeTargetType SkillRangeTargetType => _skillRangeTargetType; 12 | public bool IsNknockback => _isNknockback; 13 | public float KnockbackPower => _knockbackPower; 14 | public AbnormalityEffectMasterData AbnormalityEffect => _abnormalityEffect; 15 | 16 | [SerializeField] 17 | private SkillType _skillType = SkillType.AttackDamage; 18 | 19 | [SerializeField] 20 | private SkillTargetType _skillTargetType; 21 | 22 | [SerializeField] 23 | private int _value; 24 | 25 | [SerializeField] 26 | private SkillRangeTargetType _skillRangeTargetType; 27 | 28 | [Header("Knockback")] 29 | [SerializeField] 30 | private bool _isNknockback; 31 | 32 | [SerializeField] 33 | private float _knockbackPower; 34 | 35 | [Header("状態異常効果付与")] 36 | [SerializeField] 37 | private AbnormalityEffectMasterData _abnormalityEffect; 38 | 39 | [TextArea(3, 10)] 40 | [SerializeField] 41 | private string _description; 42 | } 43 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/SkillRangeTargetType.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Data 2 | { 3 | public enum SkillRangeTargetType 4 | { 5 | Single = 0, 6 | All, 7 | } 8 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/SkillTargetType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | [Flags] 6 | public enum SkillTargetType 7 | { 8 | Self = 1 << 0, 9 | Ally = 1 << 1, 10 | Enemy = 1 << 2, 11 | SelfAndAlly = Self | Ally, 12 | All = Self | Ally | Enemy, 13 | } 14 | } -------------------------------------------------------------------------------- /Scripts/Data/Skill/SkillType.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Data 2 | { 3 | public enum SkillType 4 | { 5 | AttackDamage = 100, 6 | Heal = 200, 7 | } 8 | } -------------------------------------------------------------------------------- /Scripts/Data/Stage/StageInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | public readonly struct StageInfo 6 | { 7 | private readonly List _monsterGenerateSetList; 8 | public IEnumerable MonsterGenerateSets => _monsterGenerateSetList; 9 | 10 | public StageInfo(IEnumerable monsterPositionInfoList) 11 | { 12 | _monsterGenerateSetList = new List(); 13 | _monsterGenerateSetList.AddRange(monsterPositionInfoList); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Scripts/Data/Stage/StageMasterData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Data 6 | { 7 | [CreateAssetMenu(fileName = "StageMasterData_", menuName = "Stage/MasterData", order = 0)] 8 | public class StageMasterData : ScriptableObject, IComparer 9 | { 10 | public StageId Id => new(_id); 11 | public string StageName => _stageName; 12 | public SceneObject StageScene => _stageScene; 13 | public IReadOnlyList StageMonsterData => _stageMonsterList; 14 | public IReadOnlyList PlayerPlaceableMonsterList => _playerPlaceableMonsterList; 15 | public int PlayerCost => _playerCost; 16 | 17 | [SerializeField, Multiline(5)] 18 | private string _debugMemo; 19 | 20 | [SerializeField] 21 | private int _id; 22 | 23 | [SerializeField] 24 | private string _stageName; 25 | 26 | [SerializeField] 27 | private SceneObject _stageScene; 28 | 29 | [SerializeField] 30 | private List _stageMonsterList; 31 | 32 | [SerializeField] 33 | private int _playerCost; 34 | 35 | [SerializeField] 36 | private List _playerPlaceableMonsterList; 37 | 38 | public bool HasStageScene() => _stageScene is { IsEmpty: false }; 39 | 40 | private void OnValidate() 41 | { 42 | if (string.IsNullOrEmpty(_stageName)) 43 | { 44 | _stageName = $"Stage {_id}"; 45 | } 46 | } 47 | 48 | public int Compare(StageMasterData x, StageMasterData y) 49 | { 50 | if (ReferenceEquals(x, y)) return 0; 51 | if (ReferenceEquals(null, y)) return 1; 52 | if (ReferenceEquals(null, x)) return -1; 53 | return x.Id.CompareTo(y.Id); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Scripts/Data/Stage/StageMasterDataRepository.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | 3 | namespace Unity1week202403.Data 4 | { 5 | public class StageMasterDataRepository 6 | { 7 | private readonly StageMasterDataStoreSource _source; 8 | 9 | public StageMasterDataRepository(StageMasterDataStoreSource source) 10 | { 11 | _source = source; 12 | } 13 | 14 | public StageMasterData Get(StageId id) => _source.Get(id); 15 | 16 | public StageMasterData[] GetAll() => _source.GetAll(); 17 | 18 | public bool Exists(StageId id) => _source.Exists(id); 19 | } 20 | } -------------------------------------------------------------------------------- /Scripts/Data/Stage/StageMasterDataStoreSource.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Unity1week202403.Structure; 4 | using UnityEngine; 5 | 6 | namespace Unity1week202403.Data 7 | { 8 | [CreateAssetMenu(fileName = "StageMasterDataStoreSource", menuName = "Stage/DataStoreSource", order = 0)] 9 | public class StageMasterDataStoreSource : ScriptableObject 10 | { 11 | public IReadOnlyList Data => _data; 12 | 13 | [SerializeField] 14 | private List _data; 15 | 16 | public StageMasterData Get(StageId id) => _data.Find(data => data.Id == id); 17 | 18 | public StageMasterData[] GetAll() => _data.ToArray(); 19 | 20 | public void Validate() 21 | { 22 | _data = _data.Distinct() 23 | .Where(data => data != null) 24 | .OrderBy(data => data.Id) 25 | .ToList(); 26 | } 27 | 28 | public bool Exists(StageId id) => _data.Exists(data => data.Id == id); 29 | } 30 | } -------------------------------------------------------------------------------- /Scripts/Data/Stage/StageMonsterData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [Serializable] 7 | public class StageMonsterData 8 | { 9 | public MonsterMasterData MonsterMasterData => _monsterMasterData; 10 | public Vector3 Position => _position; 11 | 12 | [SerializeField] 13 | private MonsterMasterData _monsterMasterData; 14 | 15 | [SerializeField] 16 | private Vector3 _position; 17 | } 18 | } -------------------------------------------------------------------------------- /Scripts/Data/StageScene/SceneObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | [Serializable] 7 | public class SceneObject 8 | { 9 | public string SceneName => _sceneName; 10 | public bool IsEmpty => string.IsNullOrEmpty(_sceneName); 11 | 12 | [SerializeField] 13 | private string _sceneName; 14 | 15 | public SceneObject(string sceneName) 16 | { 17 | _sceneName = sceneName; 18 | } 19 | 20 | public static implicit operator string(SceneObject sceneObject) 21 | { 22 | return sceneObject._sceneName; 23 | } 24 | 25 | public static implicit operator SceneObject(string sceneName) 26 | { 27 | return new SceneObject(sceneName); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Scripts/Data/StageScene/StageSceneData.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Data 2 | { 3 | public class StageSceneData 4 | { 5 | public string SceneName { get; } 6 | 7 | public StageSceneData(string sceneName) 8 | { 9 | SceneName = sceneName; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Scripts/Data/StageScene/StageSceneDataStoreSource.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Data 6 | { 7 | [CreateAssetMenu(fileName = "StageSceneDataStoreSource", menuName = "Stage/StageSceneDataStoreSource")] 8 | public class StageSceneDataStoreSource : ScriptableObject 9 | { 10 | public IReadOnlyList Scenes => _data; 11 | 12 | [SerializeField] 13 | private SceneObject[] _data; 14 | 15 | public string GetScene(int index) => _data[index]; 16 | 17 | public void Validate() 18 | { 19 | _data = _data.Distinct() 20 | .Where(data => data != null) 21 | .ToArray(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Scripts/Data/StageScene/StageSceneRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Unity1week202403.Data 5 | { 6 | public class StageSceneRepository 7 | { 8 | public IReadOnlyCollection Scenes { get; } 9 | 10 | public StageSceneRepository(StageSceneDataStoreSource source) 11 | { 12 | Scenes = source.Scenes.Select(scene => new StageSceneData(scene)).ToArray(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Scripts/Domain/Abnomality/AbnormalityEffectCalculator.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class AbnormalityEffectCalculator 4 | { 5 | private readonly BattleMonsterContainer _battleMonsterContainer; 6 | 7 | public AbnormalityEffectCalculator(BattleMonsterContainer battleMonsterContainer) 8 | { 9 | _battleMonsterContainer = battleMonsterContainer; 10 | } 11 | 12 | public void Apply( 13 | BattleMonster invoker, 14 | SkillTarget skillTarget, 15 | IAbnormalityEffectState[] abnormalityEffectStateCollection) 16 | { 17 | foreach (var battleMonsterId in skillTarget.AllTargets) 18 | { 19 | var target = _battleMonsterContainer.Get(battleMonsterId); 20 | target.AddAbnormality(abnormalityEffectStateCollection); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Scripts/Domain/Abnomality/AbnormalityEffectCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using R3; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class AbnormalityEffectCollection 8 | { 9 | public Observable OnUpdateAbnormalityType => _currentAbnormalityTypes; 10 | 11 | private readonly List _collection = new(); 12 | private readonly ReactiveProperty _currentAbnormalityTypes = new(AbnormalityTypeCollection.Empty); 13 | 14 | private float _currentTime; 15 | 16 | public void Add(params IAbnormalityEffectState[] effectState) 17 | { 18 | foreach (var abnormalityEffectState in effectState) 19 | { 20 | abnormalityEffectState.Start(_currentTime); 21 | } 22 | 23 | _collection.AddRange(effectState); 24 | 25 | var types = _collection 26 | .Select(x => x.Type) 27 | .Distinct() 28 | .ToArray(); 29 | _currentAbnormalityTypes.Value = new AbnormalityTypeCollection(types); 30 | } 31 | 32 | public void Update(float currentTime) 33 | { 34 | _currentTime = currentTime; 35 | foreach (var effectState in _collection) 36 | { 37 | effectState.UpdateTime(currentTime); 38 | } 39 | 40 | // 効果が切れたものを削除 41 | var count = _collection.RemoveAll(x => !x.Effectable); 42 | if (count > 0) 43 | { 44 | _currentAbnormalityTypes.Value = new AbnormalityTypeCollection( 45 | _collection.Select(x => x.Type).ToArray() 46 | ); 47 | } 48 | } 49 | 50 | public bool IsMovable() 51 | { 52 | return !_collection.OfType().Any(); 53 | } 54 | 55 | public bool IsAttackable() 56 | { 57 | return !_collection.OfType().Any(); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Scripts/Domain/Abnomality/AbnormalityTypeCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity1week202403.Data; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public readonly struct AbnormalityTypeCollection : IEquatable 7 | { 8 | public AbnormalityType[] Types { get; } 9 | 10 | public AbnormalityTypeCollection(AbnormalityType[] types) 11 | { 12 | Types = types ?? Array.Empty(); 13 | } 14 | 15 | public bool Contains(AbnormalityType type) 16 | { 17 | foreach (var abnormalityType in Types) 18 | { 19 | if (abnormalityType == type) 20 | { 21 | return true; 22 | } 23 | } 24 | 25 | return false; 26 | } 27 | 28 | public bool Equals(AbnormalityTypeCollection other) => Equals(Types, other.Types); 29 | public override bool Equals(object obj) => obj is AbnormalityTypeCollection other && Equals(other); 30 | public override int GetHashCode() => (Types != null ? Types.GetHashCode() : 0); 31 | 32 | public static AbnormalityTypeCollection Empty => new(Array.Empty()); 33 | } 34 | } -------------------------------------------------------------------------------- /Scripts/Domain/Abnomality/IAbnormalityEffectState.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public interface IAbnormalityEffectState 6 | { 7 | AbnormalityType Type { get; } 8 | 9 | bool Effectable { get; } 10 | 11 | void Start(float startTime); 12 | 13 | void UpdateTime(float currentTime); 14 | } 15 | } -------------------------------------------------------------------------------- /Scripts/Domain/ActiveSkill/ActiveSkill.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public class ActiveSkill 6 | { 7 | public SkillType SkillType { get; } 8 | public SkillTargetType SkillTargetType { get; } 9 | public int Value { get; } 10 | public SkillRangeTargetType SkillRangeTargetType { get; } 11 | public KnockbackEffect KnockbackEffect { get; } 12 | public StanEffect StanEffect { get; } 13 | 14 | public ActiveSkill(SkillMasterData skillMasterData) 15 | : this( 16 | skillMasterData.SkillType, 17 | skillMasterData.SkillTargetType, 18 | skillMasterData.Value, 19 | skillMasterData.SkillRangeTargetType, 20 | new KnockbackEffect(skillMasterData.IsNknockback, skillMasterData.KnockbackPower), 21 | skillMasterData.AbnormalityEffect != null 22 | ? new StanEffect(skillMasterData.AbnormalityEffect.StanTime) 23 | : StanEffect.Empty) 24 | { 25 | } 26 | 27 | public ActiveSkill( 28 | SkillType skillType, 29 | SkillTargetType skillTargetType, 30 | int value, 31 | SkillRangeTargetType skillRangeTargetType, 32 | KnockbackEffect knockbackEffect = null, 33 | StanEffect stanEffect = null) 34 | { 35 | SkillType = skillType; 36 | SkillTargetType = skillTargetType; 37 | Value = value; 38 | SkillRangeTargetType = skillRangeTargetType; 39 | KnockbackEffect = knockbackEffect ?? KnockbackEffect.Default; 40 | StanEffect = stanEffect ?? StanEffect.Empty; 41 | } 42 | 43 | public static ActiveSkill DefaultSkill => new( 44 | SkillType.AttackDamage, 45 | SkillTargetType.Enemy, 46 | 1, 47 | SkillRangeTargetType.Single, 48 | KnockbackEffect.Default, 49 | StanEffect.Empty); 50 | } 51 | } -------------------------------------------------------------------------------- /Scripts/Domain/ActiveSkill/KnockbackEffect.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class KnockbackEffect 4 | { 5 | public bool IsKnockback { get; } 6 | public float KnockbackPower { get; } 7 | 8 | public KnockbackEffect(bool isKnockback, float knockbackPower) 9 | { 10 | IsKnockback = isKnockback; 11 | KnockbackPower = knockbackPower; 12 | } 13 | 14 | public static KnockbackEffect Default => new(false, 0); 15 | } 16 | } -------------------------------------------------------------------------------- /Scripts/Domain/ActiveSkill/SkillTarget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class SkillTarget 8 | { 9 | public BattleMonsterId MainTarget { get; } 10 | public IReadOnlyCollection SubTargets { get; } 11 | public IEnumerable AllTargets => SubTargets.Prepend(MainTarget); 12 | 13 | public SkillTarget(BattleMonsterId mainTarget, IEnumerable subTargets = null) 14 | { 15 | MainTarget = mainTarget; 16 | SubTargets = subTargets?.ToArray() ?? Array.Empty(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Scripts/Domain/ActiveSkill/StanEffect.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public class StanEffect 6 | { 7 | public bool Effectable => StanTime > 0; 8 | public float StanTime { get; } 9 | 10 | public StanEffect(float stanTime) 11 | { 12 | StanTime = Mathf.Max(0, stanTime); 13 | } 14 | 15 | public static StanEffect Empty => new(0); 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Domain/ActiveSkill/StanEffectState.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public class StanEffectState : IAbnormalityEffectState 6 | { 7 | public AbnormalityType Type => AbnormalityType.Stan; 8 | 9 | public bool Effectable { get; private set; } = true; 10 | 11 | private readonly StanEffect _stanEffect; 12 | private float _endTime; 13 | 14 | public StanEffectState(StanEffect stanEffect) 15 | { 16 | _stanEffect = stanEffect; 17 | } 18 | 19 | public void Start(float startTime) 20 | { 21 | _endTime = startTime + _stanEffect.StanTime; 22 | } 23 | 24 | public void UpdateTime(float currentTime) 25 | { 26 | if (currentTime >= _endTime) 27 | { 28 | Effectable = false; 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Scripts/Domain/Audio/AudioPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Cysharp.Threading.Tasks; 3 | using R3; 4 | using Unity1week202403.Presentation; 5 | using UnityEngine; 6 | using VContainer.Unity; 7 | using AudioType = Unity1week202403.Data.AudioType; 8 | 9 | namespace Unity1week202403.Domain 10 | { 11 | public class AudioPlayer : IInitializable, IDisposable 12 | { 13 | private readonly BgmPlayer _bgm; 14 | private readonly SePlayer _se; 15 | private readonly AudioResourceLoader _loader; 16 | private readonly AudioSettingsService _audioSettingsService; 17 | private readonly CompositeDisposable _disposable = new(); 18 | 19 | public AudioPlayer( 20 | AudioResourceLoader loader, 21 | AudioSettingsService audioSettingsService, 22 | BgmPlayer bgm, 23 | SePlayer sePlayer) 24 | { 25 | _bgm = bgm; 26 | _se = sePlayer; 27 | _loader = loader; 28 | _audioSettingsService = audioSettingsService; 29 | } 30 | 31 | void IInitializable.Initialize() 32 | { 33 | _audioSettingsService.BgmVolume 34 | .Subscribe(volume => _bgm.SetVolume(volume.Value)) 35 | .AddTo(_disposable); 36 | 37 | _audioSettingsService.SeVolume 38 | .Subscribe(volume => _se.SetVolume(volume.Value)) 39 | .AddTo(_disposable); 40 | } 41 | 42 | public void PlayBgm(string id, bool isLoop = true) 43 | { 44 | PlayBgmAsync(id, isLoop).Forget(); 45 | } 46 | 47 | public async UniTask PlayBgmAsync(string id, bool isLoop = true) 48 | { 49 | var clip = await _loader.LoadAsync(AudioType.Bgm, id); 50 | _bgm.Play(clip, isLoop); 51 | } 52 | 53 | public async UniTask StopBgm(float duration = 1f) 54 | { 55 | await _bgm.StopAsync(duration); 56 | } 57 | 58 | public async void PlaySe(string id) 59 | { 60 | var clip = await _loader.LoadAsync(AudioType.Se, id); 61 | _se.PlayOneShot(clip); 62 | } 63 | 64 | public void PlaySe(AudioClip clip) 65 | { 66 | _se.PlayOneShot(clip); 67 | } 68 | 69 | public void Dispose() => _disposable.Dispose(); 70 | } 71 | } -------------------------------------------------------------------------------- /Scripts/Domain/Audio/AudioResourceLoader.cs: -------------------------------------------------------------------------------- 1 | using Cysharp.Threading.Tasks; 2 | using Unity1week202403.Data; 3 | using UnityEngine; 4 | using AudioType = Unity1week202403.Data.AudioType; 5 | 6 | namespace Unity1week202403.Domain 7 | { 8 | public class AudioResourceLoader 9 | { 10 | private readonly AudioResource _audioResource; 11 | 12 | public AudioResourceLoader(AudioResource audioResource) 13 | { 14 | _audioResource = audioResource; 15 | } 16 | 17 | public async UniTask LoadAsync(AudioType type, string id) 18 | { 19 | var audioClipData = _audioResource.Get(type, id); 20 | if (audioClipData.Clip.loadState != AudioDataLoadState.Loaded) 21 | { 22 | audioClipData.Clip.LoadAudioData(); 23 | } 24 | 25 | await UniTask.WaitUntil(() => audioClipData.Clip.loadState == AudioDataLoadState.Loaded); 26 | return audioClipData.Clip; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Scripts/Domain/Audio/AudioSettingsService.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class AudioSettingsService 7 | { 8 | public ReactiveProperty BgmVolume => _bgmVolume; 9 | public ReactiveProperty SeVolume => _seVolume; 10 | 11 | private readonly ReactiveProperty _bgmVolume = new(new AudioVolume(0.4f)); 12 | private readonly ReactiveProperty _seVolume = new(new AudioVolume(0.4f)); 13 | 14 | public AudioSettingsService() 15 | { 16 | } 17 | 18 | public void SetBgmVolume(AudioVolume volume) => _bgmVolume.Value = volume; 19 | 20 | public void SetSeVolume(AudioVolume volume) => _seVolume.Value = volume; 21 | } 22 | } -------------------------------------------------------------------------------- /Scripts/Domain/Audio/CreateAudioSettingViewModelUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Presentation; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | using ViewModel = AudioSettingView.ViewModel; 6 | 7 | public class CreateAudioSettingViewModelUseCase 8 | { 9 | private readonly AudioSettingsService _audioSettingsService; 10 | 11 | public CreateAudioSettingViewModelUseCase(AudioSettingsService audioSettingsService) 12 | { 13 | _audioSettingsService = audioSettingsService; 14 | } 15 | 16 | public ViewModel Create() 17 | { 18 | return new ViewModel( 19 | _audioSettingsService.BgmVolume.Value, 20 | _audioSettingsService.SeVolume.Value); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/AllyPlacedMonsterUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Data; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class AllyPlacedMonsterUseCase 7 | { 8 | private readonly BattleMonsterContainer _battleMonsterContainer; 9 | private readonly BattleMonsterPresenterContainer _battleMonsterPresenterContainer; 10 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 11 | private readonly PlayerStatus _playerStatus; 12 | 13 | public AllyPlacedMonsterUseCase( 14 | BattleMonsterContainer battleMonsterContainer, 15 | BattleMonsterPresenterContainer battleMonsterPresenterContainer, 16 | MonsterMasterDataRepository monsterMasterDataRepository, 17 | PlayerStatus playerStatus) 18 | { 19 | _battleMonsterContainer = battleMonsterContainer; 20 | _battleMonsterPresenterContainer = battleMonsterPresenterContainer; 21 | _monsterMasterDataRepository = monsterMasterDataRepository; 22 | _playerStatus = playerStatus; 23 | } 24 | 25 | public void ResetAll() 26 | { 27 | foreach (var battleMonsterId in _battleMonsterContainer.GetAllyIds().ToArray()) 28 | { 29 | Remove(battleMonsterId); 30 | } 31 | } 32 | 33 | public void Remove(BattleMonsterId battleMonsterId) 34 | { 35 | var battleMonster = _battleMonsterContainer.Get(battleMonsterId); 36 | var masterData = _monsterMasterDataRepository.Get(battleMonster.MonsterId); 37 | 38 | _battleMonsterPresenterContainer.RemoveAndDestroy(battleMonsterId); 39 | _battleMonsterContainer.Remove(battleMonsterId); 40 | 41 | // コストを返却 42 | _playerStatus.CostStatus.Add(masterData.Cost); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/BattleReset.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public readonly struct BattleReset 4 | { 5 | public bool Value { get; } 6 | 7 | public BattleReset(bool value) 8 | { 9 | Value = value; 10 | } 11 | 12 | public static BattleReset None => new(false); 13 | } 14 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/BattleShutdownUseCase.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class BattleShutdownUseCase 4 | { 5 | private readonly TimeControlUseCase _timeControlUseCase; 6 | 7 | public BattleShutdownUseCase(TimeControlUseCase timeControlUseCase) 8 | { 9 | _timeControlUseCase = timeControlUseCase; 10 | } 11 | 12 | public void Shutdown() 13 | { 14 | _timeControlUseCase.SetDefaultTimeScale(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/BattleTerminationCalculator.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class BattleTerminationCalculator 4 | { 5 | private readonly BattleMonsterContainer _battleMonsterContainer; 6 | 7 | public BattleTerminationCalculator(BattleMonsterContainer battleMonsterContainer) 8 | { 9 | _battleMonsterContainer = battleMonsterContainer; 10 | } 11 | 12 | public bool IsBattleTerminated() 13 | { 14 | return IsVictory() || IsDefeat(); 15 | } 16 | 17 | private bool IsVictory() 18 | { 19 | return BattleVictoryCondition.IsFulfilled(_battleMonsterContainer); 20 | } 21 | 22 | private bool IsDefeat() 23 | { 24 | return BattleDefeatCondition.IsFulfilled(_battleMonsterContainer); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/CreateAllyBattleMonsterUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Structure; 3 | using UnityEngine.Assertions; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class CreateAllyBattleMonsterUseCase 8 | { 9 | private readonly BattleMonsterFactory _battleMonsterFactory; 10 | private readonly BattleMonsterContainer _battleMonsterContainer; 11 | 12 | public CreateAllyBattleMonsterUseCase( 13 | BattleMonsterFactory battleMonsterFactory, 14 | BattleMonsterContainer battleMonsterContainer) 15 | { 16 | _battleMonsterFactory = battleMonsterFactory; 17 | _battleMonsterContainer = battleMonsterContainer; 18 | } 19 | 20 | public BattleMonster Create(MonsterId monsterId) 21 | { 22 | var uniqueBattleMonsterId = CreateUniqueBattleMonsterId(); 23 | var monster = _battleMonsterFactory.Create(uniqueBattleMonsterId, monsterId, isAlly: true); 24 | return monster; 25 | } 26 | 27 | private BattleMonsterId CreateUniqueBattleMonsterId() 28 | { 29 | var ids = _battleMonsterContainer.GetAllyIds().ToArray(); 30 | BattleMonsterId? id = null; 31 | 32 | // 重複しないIDを生成する 33 | for (int i = 0; i < 999; i++) 34 | { 35 | // 候補 36 | var candidate = BattleMonsterId.CreateAlly(i); 37 | if (!ids.Contains(candidate)) 38 | { 39 | id = candidate; 40 | break; 41 | } 42 | } 43 | 44 | Assert.IsTrue(id.HasValue, "IDが生成できませんでした"); 45 | 46 | return id.Value; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/CreateEnemyBattleMonsterUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Structure; 3 | using UnityEngine.Assertions; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class CreateEnemyBattleMonsterUseCase 8 | { 9 | private readonly BattleMonsterContainer _battleMonsterContainer; 10 | private readonly BattleMonsterFactory _battleMonsterFactory; 11 | 12 | public CreateEnemyBattleMonsterUseCase( 13 | BattleMonsterContainer battleMonsterContainer, 14 | BattleMonsterFactory battleMonsterFactory) 15 | { 16 | _battleMonsterContainer = battleMonsterContainer; 17 | _battleMonsterFactory = battleMonsterFactory; 18 | } 19 | 20 | public BattleMonster CreateAndRegister(MonsterId monsterId) 21 | { 22 | var uniqueBattleMonsterId = CreateUniqueBattleMonsterId(); 23 | var monster = _battleMonsterFactory.Create(uniqueBattleMonsterId, monsterId, false); 24 | _battleMonsterContainer.Add(monster); 25 | return monster; 26 | } 27 | 28 | private BattleMonsterId CreateUniqueBattleMonsterId() 29 | { 30 | var ids = _battleMonsterContainer.GetEnemyIds().ToArray(); 31 | BattleMonsterId? id = null; 32 | 33 | // 重複しないIDを生成する 34 | for (int i = 0; i < 999; i++) 35 | { 36 | // 候補 37 | var candidate = BattleMonsterId.CreateEnemy(i); 38 | if (!ids.Contains(candidate)) 39 | { 40 | id = candidate; 41 | break; 42 | } 43 | } 44 | 45 | Assert.IsTrue(id.HasValue, "IDが生成できませんでした"); 46 | 47 | return id.Value; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/CreateMonsterSelectViewModelUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Data; 3 | using Unity1week202403.Presentation; 4 | using Unity1week202403.Structure; 5 | 6 | namespace Unity1week202403.Domain 7 | { 8 | using ViewModel = MonsterSelectView.ViewModel; 9 | using ElementViewModel = MonsterSelectElementView.ViewModel; 10 | 11 | public class CreateMonsterSelectViewModelUseCase 12 | { 13 | private readonly StageMasterDataStoreSource _stageMasterDataStoreSource; 14 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 15 | 16 | public CreateMonsterSelectViewModelUseCase(StageMasterDataStoreSource stageMasterDataStoreSource, MonsterMasterDataRepository monsterMasterDataRepository) 17 | { 18 | _stageMasterDataStoreSource = stageMasterDataStoreSource; 19 | _monsterMasterDataRepository = monsterMasterDataRepository; 20 | } 21 | 22 | public ViewModel Create(StageId stageId) 23 | { 24 | var elementViewModels = _stageMasterDataStoreSource.Get(stageId) 25 | .PlayerPlaceableMonsterList.Select(x => _monsterMasterDataRepository.Get(new MonsterId(x))) 26 | .Select(CreateElementViewModel) 27 | .ToArray(); 28 | 29 | return new ViewModel(elementViewModels); 30 | } 31 | 32 | private ElementViewModel CreateElementViewModel(MonsterMasterData data) 33 | { 34 | return new ElementViewModel( 35 | data.Id, 36 | data.Thumbnail, 37 | data.Cost, 38 | data.BigMonsterMasterData != null 39 | ? new ElementViewModel( 40 | data.BigMonsterMasterData.Id, 41 | data.BigMonsterMasterData.Thumbnail, 42 | data.BigMonsterMasterData.Cost) 43 | : null); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/History/BattleMonsterPlaceHistory.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class BattleMonsterPlaceHistory 4 | { 5 | private BattleMonsterPlaceRecord _lastRecord; 6 | 7 | public bool HasRecord() => _lastRecord != null; 8 | 9 | public void Set(BattleMonsterPlaceRecord historyRecordData) 10 | { 11 | _lastRecord = historyRecordData; 12 | } 13 | 14 | public BattleMonsterPlaceRecord GetLast() => _lastRecord; 15 | 16 | public void Reset() => _lastRecord = null; 17 | } 18 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/History/BattleMonsterPlaceRecord.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class BattleMonsterPlaceRecord 7 | { 8 | private readonly List _records = new(); 9 | 10 | public void AddRecord(HistoryRecordData historyRecordData) 11 | { 12 | _records.Add(historyRecordData); 13 | } 14 | 15 | public IEnumerable GetRecords() => _records; 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/History/HistoryRecordData.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class HistoryRecordData 7 | { 8 | public BattleMonsterId BattleMonsterId { get; } 9 | public MonsterId MonsterId { get; } 10 | public Vector3 Position { get; } 11 | 12 | public HistoryRecordData(BattleMonsterId battleMonsterId, MonsterId monsterId, Vector3 position) 13 | { 14 | BattleMonsterId = battleMonsterId; 15 | MonsterId = monsterId; 16 | Position = position; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/History/PlaceRecordFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class PlaceRecordFactory 7 | { 8 | private readonly BattleMonsterPresenterContainer _battleMonsterPresenterContainer; 9 | 10 | public PlaceRecordFactory(BattleMonsterPresenterContainer battleMonsterPresenterContainer) 11 | { 12 | _battleMonsterPresenterContainer = battleMonsterPresenterContainer; 13 | } 14 | 15 | public BattleMonsterPlaceRecord Create(IEnumerable allyBattleMonsters) 16 | { 17 | var record = new BattleMonsterPlaceRecord(); 18 | foreach (var battleMonster in allyBattleMonsters) 19 | { 20 | var recordData = new HistoryRecordData( 21 | battleMonster.BattleMonsterId, 22 | battleMonster.MonsterId, 23 | GetPosition(battleMonster.BattleMonsterId)); 24 | record.AddRecord(recordData); 25 | } 26 | 27 | return record; 28 | } 29 | 30 | private Vector3 GetPosition(BattleMonsterId battleMonsterId) 31 | { 32 | var monsterPresenter = _battleMonsterPresenterContainer.Get(battleMonsterId); 33 | return monsterPresenter.WorldPosition; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/History/PlaceRecordUseCase.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class PlaceRecordUseCase 4 | { 5 | private readonly BattleMonsterPlaceHistory _battleMonsterPlaceHistory; 6 | private readonly BattleMonsterContainer _battleMonsterContainer; 7 | private readonly BattleMonsterPresenterContainer _battleMonsterPresenterContainer; 8 | private readonly BattleMonsterFactory _battleMonsterFactory; 9 | private readonly BattleMonsterPresenterFactory _battleMonsterPresenterFactory; 10 | private readonly PlaceRecordFactory _placeRecordFactory; 11 | private readonly PlayerStatus _playerStatus; 12 | 13 | public PlaceRecordUseCase( 14 | BattleMonsterPlaceHistory battleMonsterPlaceHistory, 15 | BattleMonsterContainer battleMonsterContainer, 16 | BattleMonsterPresenterContainer battleMonsterPresenterContainer, 17 | BattleMonsterFactory battleMonsterFactory, 18 | BattleMonsterPresenterFactory battleMonsterPresenterFactory, 19 | PlaceRecordFactory placeRecordFactory, 20 | PlayerStatus playerStatus) 21 | { 22 | _battleMonsterPlaceHistory = battleMonsterPlaceHistory; 23 | _battleMonsterContainer = battleMonsterContainer; 24 | _battleMonsterPresenterContainer = battleMonsterPresenterContainer; 25 | _battleMonsterFactory = battleMonsterFactory; 26 | _battleMonsterPresenterFactory = battleMonsterPresenterFactory; 27 | _placeRecordFactory = placeRecordFactory; 28 | _playerStatus = playerStatus; 29 | } 30 | 31 | public bool HasRecord() 32 | { 33 | return _battleMonsterPlaceHistory.HasRecord(); 34 | } 35 | 36 | public void Record() 37 | { 38 | var allyBattleMonsters = _battleMonsterContainer.GetAllyBattleMonsters(); 39 | var record = _placeRecordFactory.Create(allyBattleMonsters); 40 | _battleMonsterPlaceHistory.Set(record); 41 | } 42 | 43 | public void Restore() 44 | { 45 | if (!HasRecord()) 46 | { 47 | return; 48 | } 49 | 50 | var record = _battleMonsterPlaceHistory.GetLast(); 51 | foreach (var historyRecordData in record.GetRecords()) 52 | { 53 | CreateBattleMonster(historyRecordData); 54 | } 55 | } 56 | 57 | private void CreateBattleMonster(HistoryRecordData historyRecordData) 58 | { 59 | var monster = _battleMonsterFactory.Create( 60 | historyRecordData.BattleMonsterId, 61 | historyRecordData.MonsterId, 62 | isAlly: true); 63 | 64 | var monsterPresenter = _battleMonsterPresenterFactory.Create(monster, historyRecordData.Position); 65 | 66 | _battleMonsterContainer.Add(monster); 67 | _battleMonsterPresenterContainer.Add(monsterPresenter); 68 | 69 | // コスト消費 70 | _playerStatus.CostStatus.Consume(monster.Cost); 71 | } 72 | 73 | public void Reset() 74 | { 75 | _battleMonsterPlaceHistory.Reset(); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Knockback.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public readonly struct Knockback 6 | { 7 | public Vector3 Direction { get; } 8 | public float Power { get; } 9 | 10 | public Knockback(Vector3 direction, float power) 11 | { 12 | Direction = direction; 13 | Power = power; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/KnockbackService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class KnockbackService 7 | { 8 | private readonly BattleMonsterPresenterContainer _battleMonsterPresenterContainer; 9 | private readonly BattleMonsterContainer _battleMonsterContainer; 10 | 11 | public KnockbackService(BattleMonsterPresenterContainer battleMonsterPresenterContainer, 12 | BattleMonsterContainer battleMonsterContainer) 13 | { 14 | _battleMonsterPresenterContainer = battleMonsterPresenterContainer; 15 | _battleMonsterContainer = battleMonsterContainer; 16 | } 17 | 18 | public void Apply( 19 | BattleMonsterId invoker, 20 | IEnumerable targets, 21 | KnockbackEffect knockbackEffect) 22 | { 23 | var invokerMonster = _battleMonsterContainer.Get(invoker); 24 | Apply( 25 | invokerMonster, 26 | targets.Select(monsterId => _battleMonsterContainer.Get(monsterId)), 27 | knockbackEffect 28 | ); 29 | } 30 | 31 | private void Apply(BattleMonster invoker, IEnumerable targets, KnockbackEffect knockbackEffect) 32 | { 33 | foreach (var target in targets) 34 | { 35 | Apply(invoker, target, knockbackEffect); 36 | } 37 | } 38 | 39 | private void Apply(BattleMonster invoker, BattleMonster target, KnockbackEffect knockbackEffect) 40 | { 41 | if (knockbackEffect.IsKnockback) 42 | { 43 | var invokerPresenter = _battleMonsterPresenterContainer.Get(invoker.BattleMonsterId); 44 | var targetPresenter = _battleMonsterPresenterContainer.Get(target.BattleMonsterId); 45 | var direction = invokerPresenter.Direction(targetPresenter).normalized; 46 | var knockback = new Knockback(direction, knockbackEffect.KnockbackPower); 47 | target.Knockback(knockback); 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterAttackUseCase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity1week202403.Data; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class BattleMonsterAttackUseCase 7 | { 8 | private readonly BattleMonsterContainer _battleMonsterContainer; 9 | private readonly KnockbackService _knockbackService; 10 | private readonly AbnormalityEffectCalculator _abnormalityEffectCalculator; 11 | 12 | public BattleMonsterAttackUseCase( 13 | BattleMonsterContainer battleMonsterContainer, 14 | KnockbackService knockbackService, 15 | AbnormalityEffectCalculator abnormalityEffectCalculator) 16 | { 17 | _battleMonsterContainer = battleMonsterContainer; 18 | _knockbackService = knockbackService; 19 | _abnormalityEffectCalculator = abnormalityEffectCalculator; 20 | } 21 | 22 | public void Calculate(BattleMonsterId attackerBattleMonsterId, SkillTarget skillTarget, ActiveSkill activeSkill) 23 | { 24 | var attackerMonster = _battleMonsterContainer.Get(attackerBattleMonsterId); 25 | switch (activeSkill.SkillType) 26 | { 27 | case SkillType.AttackDamage: 28 | Attack(attackerMonster, skillTarget); 29 | break; 30 | case SkillType.Heal: 31 | Heal(attackerMonster, skillTarget, attackerMonster.ActiveSkill); 32 | break; 33 | default: 34 | throw new ArgumentOutOfRangeException(); 35 | } 36 | 37 | // スタン状態付与 38 | _abnormalityEffectCalculator.Apply( 39 | invoker: attackerMonster, 40 | skillTarget: skillTarget, 41 | CreateAbnormalityEffectState(attackerMonster, skillTarget) 42 | ); 43 | } 44 | 45 | private IAbnormalityEffectState[] CreateAbnormalityEffectState(BattleMonster invoker, SkillTarget target) 46 | { 47 | return new IAbnormalityEffectState[] 48 | { 49 | new StanEffectState(invoker.ActiveSkill.StanEffect), 50 | }; 51 | } 52 | 53 | private void Attack(BattleMonster attacker, SkillTarget skillTarget) 54 | { 55 | foreach (var monsterId in skillTarget.AllTargets) 56 | { 57 | var monster = _battleMonsterContainer.Get(monsterId); 58 | BattleMonsterAttackCalculator.Calculate(attacker, monster); 59 | } 60 | 61 | if (attacker.ActiveSkill.KnockbackEffect.IsKnockback) 62 | { 63 | _knockbackService.Apply( 64 | attacker.BattleMonsterId, 65 | skillTarget.AllTargets, 66 | attacker.ActiveSkill.KnockbackEffect); 67 | } 68 | } 69 | 70 | private void Heal(BattleMonster invoker, SkillTarget skillTarget, ActiveSkill activeSkill) 71 | { 72 | foreach (var monsterId in skillTarget.AllTargets) 73 | { 74 | var monster = _battleMonsterContainer.Get(monsterId); 75 | BattleMonsterHealCalculator.Calculate(invoker, monster, activeSkill); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using R3; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class BattleMonsterContainer 8 | { 9 | public Observable OnDead => _onDead; 10 | 11 | private readonly List _monsters = new(); 12 | private readonly Subject _onDead = new(); 13 | 14 | public void Add(BattleMonster monster) 15 | { 16 | _monsters.Add(monster); 17 | monster.OnDead.Subscribe(_ => _onDead.OnNext(monster)); 18 | } 19 | 20 | public BattleMonster Get(BattleMonsterId battleMonsterId) 21 | { 22 | return _monsters.Find(x => x.BattleMonsterId == battleMonsterId); 23 | } 24 | 25 | public void Clear() => _monsters.Clear(); 26 | 27 | public IEnumerable GetAllyIds() 28 | { 29 | return _monsters 30 | .Where(monster => monster.IsAlly) 31 | .Select(monster => monster.BattleMonsterId); 32 | } 33 | 34 | public IEnumerable GetEnemyIds() 35 | { 36 | return _monsters 37 | .Where(monster => monster.IsEnemy) 38 | .Select(monster => monster.BattleMonsterId); 39 | } 40 | 41 | public bool AnyAlly() => _monsters.Any(monster => monster.IsAlly); 42 | 43 | public IEnumerable GetAllyBattleMonsters() 44 | { 45 | return _monsters.Where(monster => monster.IsAlly); 46 | } 47 | 48 | /// 49 | /// 指定した妖怪が敵である妖怪を取得する 50 | /// 51 | public IEnumerable GetEnemyBattleMonstersBy(BattleMonsterId battleMonsterId) 52 | { 53 | var target = _monsters.Find(x => x.BattleMonsterId == battleMonsterId); 54 | return _monsters.Where(monster => target.IsEnemyTo(monster)); 55 | } 56 | 57 | /// 58 | /// 指定した妖怪が味方である妖怪を取得する 59 | /// 60 | public IEnumerable GetAllyBattleMonstersBy(BattleMonsterId battleMonsterId) 61 | { 62 | var target = _monsters.Find(x => x.BattleMonsterId == battleMonsterId); 63 | return _monsters.Where(monster => target.IsAllyTo(monster)); 64 | } 65 | 66 | public IEnumerable GetEnemyBattleMonsters() 67 | { 68 | return _monsters.Where(monster => monster.IsEnemy); 69 | } 70 | 71 | public void Remove(params BattleMonsterId[] battleMonsterIds) 72 | { 73 | foreach (var battleMonsterId in battleMonsterIds) 74 | { 75 | var monster = _monsters.First(monster => monster.BattleMonsterId == battleMonsterId); 76 | _monsters.Remove(monster); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterContainerService.cs: -------------------------------------------------------------------------------- 1 | 2 | using R3; 3 | using Unity1week202403.Presentation; 4 | using UnityEngine; 5 | using VContainer.Unity; 6 | 7 | namespace Unity1week202403.Domain 8 | { 9 | public class BattleMonsterContainerService : IInitializable 10 | { 11 | private readonly BattleMonsterContainer _battleMonsterContainer; 12 | private readonly BattleMonsterPresenterContainer _battleMonsterPresenterContainer; 13 | private BattleMonster _lastDeadMonster; 14 | 15 | public BattleMonsterContainerService( 16 | BattleMonsterContainer battleMonsterContainer, 17 | BattleMonsterPresenterContainer battleMonsterPresenterContainer) 18 | { 19 | _battleMonsterContainer = battleMonsterContainer; 20 | _battleMonsterPresenterContainer = battleMonsterPresenterContainer; 21 | } 22 | 23 | public void Initialize() 24 | { 25 | _battleMonsterContainer.OnDead.Subscribe(monster => 26 | { 27 | Debug.Log("Dead: " + monster.BattleMonsterId.Value); 28 | _lastDeadMonster = monster; 29 | }); 30 | } 31 | 32 | public BattleMonsterPresenter GetLastDeadMonster() 33 | { 34 | return _battleMonsterPresenterContainer.Get(_lastDeadMonster.BattleMonsterId); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterFactory.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class BattleMonsterFactory 7 | { 8 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 9 | 10 | public BattleMonsterFactory(MonsterMasterDataRepository monsterMasterDataRepository) 11 | { 12 | _monsterMasterDataRepository = monsterMasterDataRepository; 13 | } 14 | 15 | public BattleMonster Create(BattleMonsterId battleMonsterId, MonsterId monsterId, bool isAlly) 16 | { 17 | var monsterMasterData = _monsterMasterDataRepository.Get(monsterId); 18 | 19 | var activeSkill = monsterMasterData.SkillMasterData != null 20 | ? new ActiveSkill(monsterMasterData.SkillMasterData) 21 | : ActiveSkill.DefaultSkill; 22 | 23 | return new BattleMonster( 24 | battleMonsterId, 25 | monsterId, 26 | isAlly, 27 | monsterMasterData.Cost, 28 | monsterMasterData.Parameter, 29 | activeSkill, 30 | monsterMasterData.ZPosition); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public readonly struct BattleMonsterId : IEquatable 6 | { 7 | public int Value { get; } 8 | public int TeamId => Value / 1_000; 9 | public int NumberId => Value % 1_000; 10 | 11 | public BattleMonsterId(int value, bool isAlly) 12 | { 13 | // 0-999: Ally, 1000-1999: Enemy 14 | var isAllyValue = (isAlly ? 0 : 1) * 1_000; 15 | Value = value + isAllyValue; 16 | } 17 | 18 | public bool Equals(BattleMonsterId other) => Value == other.Value; 19 | public override bool Equals(object obj) => obj is BattleMonsterId other && Equals(other); 20 | public static bool operator ==(BattleMonsterId left, BattleMonsterId right) => left.Equals(right); 21 | public static bool operator !=(BattleMonsterId left, BattleMonsterId right) => !left.Equals(right); 22 | public override int GetHashCode() => Value; 23 | 24 | public static BattleMonsterId CreateAlly(int id) => new(id, true); 25 | public static BattleMonsterId CreateEnemy(int id) => new(id, false); 26 | } 27 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterPresenterContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity1week202403.Presentation; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class BattleMonsterPresenterContainer 7 | { 8 | private readonly List _monsters = new(); 9 | 10 | public void Add(BattleMonsterPresenter monster) => _monsters.Add(monster); 11 | public IReadOnlyList GetAll() => _monsters; 12 | 13 | public void ClearAndDestroy() 14 | { 15 | _monsters.ForEach(monster => UnityEngine.Object.Destroy(monster.gameObject)); 16 | _monsters.Clear(); 17 | } 18 | 19 | public void RemoveAndDestroy(params BattleMonsterId[] battleMonsterId) 20 | { 21 | foreach (var id in battleMonsterId) 22 | { 23 | var monster = _monsters.Find(presenter => presenter.BattleMonsterId == id); 24 | _monsters.Remove(monster); 25 | UnityEngine.Object.Destroy(monster.gameObject); 26 | } 27 | } 28 | 29 | public BattleMonsterPresenter Get(BattleMonsterId id) 30 | { 31 | return _monsters.Find(presenter => presenter.BattleMonsterId == id); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Monster/BattleMonsterPresenterFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity1week202403.Data; 3 | using Unity1week202403.Presentation; 4 | using Unity1week202403.Structure; 5 | using UnityEngine; 6 | 7 | namespace Unity1week202403.Domain 8 | { 9 | public class BattleMonsterPresenterFactory 10 | { 11 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 12 | private readonly Func _createFunc; 13 | 14 | public BattleMonsterPresenterFactory( 15 | MonsterMasterDataRepository monsterMasterDataRepository, 16 | Func createFunc) 17 | { 18 | _monsterMasterDataRepository = monsterMasterDataRepository; 19 | _createFunc = createFunc; 20 | } 21 | 22 | public BattleMonsterPresenter Create(BattleMonster battleMonster, Vector3 worldPosition) 23 | { 24 | var prefab = _monsterMasterDataRepository.Get(battleMonster.MonsterId).Prefab; 25 | return Create(battleMonster.MonsterId, prefab, worldPosition, battleMonster); 26 | } 27 | 28 | public BattleMonsterPresenter Create(MonsterGenerateSet monsterGenerateSet, BattleMonster battleMonster) 29 | { 30 | return Create( 31 | monsterGenerateSet.MonsterId, 32 | monsterGenerateSet.Prefab, 33 | monsterGenerateSet.Position, 34 | battleMonster); 35 | } 36 | 37 | private BattleMonsterPresenter Create( 38 | MonsterId monsterId, 39 | GameObject prefab, 40 | Vector3 worldPosition, 41 | BattleMonster battleMonster) 42 | { 43 | var monster = _createFunc(prefab, worldPosition); 44 | monster.name = $"Monster_{battleMonster.BattleMonsterId.Value:0000}_{monsterId.Value:000}"; 45 | monster.Initialize(battleMonster); 46 | return monster; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Place/FindPlacedMonsterUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Presentation; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class FindPlacedMonsterUseCase 7 | { 8 | private readonly BattleMonsterContainer _battleMonsterContainer; 9 | 10 | public FindPlacedMonsterUseCase(BattleMonsterContainer battleMonsterContainer) 11 | { 12 | _battleMonsterContainer = battleMonsterContainer; 13 | } 14 | 15 | public bool TryAllyFind(Vector3 worldPosition, out BattleMonster battleMonster) 16 | { 17 | if (Physics.Raycast( 18 | origin: worldPosition + Vector3.up * 100, 19 | direction: Vector3.down, 20 | out var hit, 21 | maxDistance: 100, 22 | layerMask: Const.LayerMaskMonsterCollider)) 23 | { 24 | if (hit.transform.TryGetComponent(out var battleMonsterPresenter)) 25 | { 26 | var monster = _battleMonsterContainer.Get(battleMonsterPresenter.BattleMonsterId); 27 | 28 | if (monster.IsAlly) 29 | { 30 | battleMonster = monster; 31 | return true; 32 | } 33 | } 34 | } 35 | 36 | battleMonster = default; 37 | return false; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Place/JudgeMonsterPlaceableUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Presentation; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class JudgeMonsterPlaceableUseCase : IOnDrawGizmosHandler 8 | { 9 | private const float RaycastDistance = 10; 10 | 11 | private readonly MonsterMasterDataService _monsterMasterDataService; 12 | 13 | private GizmoData _gizmoData; 14 | 15 | public JudgeMonsterPlaceableUseCase(MonsterMasterDataService monsterMasterDataService) 16 | { 17 | _monsterMasterDataService = monsterMasterDataService; 18 | } 19 | 20 | public bool Judge(MonsterId monsterId, Vector3 worldPosition, bool isPlayer) 21 | { 22 | _gizmoData = default; 23 | 24 | if (IsPlaceableArea(worldPosition, isPlayer) == false) 25 | { 26 | return false; 27 | } 28 | 29 | return !IsOverlapByMonster(monsterId, worldPosition, out _gizmoData); 30 | } 31 | 32 | private static bool IsPlaceableArea(Vector3 worldPosition, bool isPlayer) 33 | { 34 | // プレイヤーは左半分側にしか置けない 35 | // 半径25の円がフィールド...22以下に配置可能 36 | if (isPlayer) 37 | { 38 | return worldPosition.x < 0 && new Vector2(worldPosition.x, worldPosition.z).magnitude < 22f; 39 | } 40 | 41 | return 0 < worldPosition.x; 42 | } 43 | 44 | private bool IsOverlapByMonster(MonsterId monsterId, Vector3 worldPosition, out GizmoData gizmoData) 45 | { 46 | var radius = _monsterMasterDataService.GetColliderRadius(monsterId); 47 | var origin = worldPosition + Vector3.up * RaycastDistance; 48 | var downRay = new Ray(origin, Vector3.down); 49 | 50 | var isHit = Physics.SphereCast(downRay, radius, out _, RaycastDistance, Const.LayerMaskMonsterCollider); 51 | gizmoData = new GizmoData 52 | { 53 | Radius = radius, 54 | Ray = downRay, 55 | WorldPosition = worldPosition, 56 | IsOverlap = isHit 57 | }; 58 | 59 | return isHit; 60 | } 61 | 62 | private struct GizmoData 63 | { 64 | public Vector3 WorldPosition; 65 | public float Radius; 66 | public Ray Ray; 67 | public bool IsOverlap; 68 | } 69 | 70 | public void OnDrawGizmos() 71 | { 72 | Gizmos.color = _gizmoData.IsOverlap ? Color.red : Color.green; 73 | Gizmos.DrawWireSphere( 74 | _gizmoData.WorldPosition + Vector3.up * _gizmoData.Radius, 75 | _gizmoData.Radius); 76 | Gizmos.DrawRay(_gizmoData.Ray.origin, _gizmoData.Ray.direction * RaycastDistance); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Result/BattleDefeatCondition.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public static class BattleDefeatCondition 6 | { 7 | public static bool IsFulfilled(BattleMonsterContainer battleMonsterContainer) 8 | { 9 | return battleMonsterContainer.GetAllyBattleMonsters() 10 | .All(monster => monster.IsDead); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Result/BattleResult.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public enum BattleResult 4 | { 5 | None, 6 | Victory, 7 | Defeat, 8 | } 9 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Result/BattleResultCalculator.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class BattleResultCalculator 4 | { 5 | private readonly BattleMonsterContainer _battleMonsterContainer; 6 | 7 | public BattleResultCalculator(BattleMonsterContainer battleMonsterContainer) 8 | { 9 | _battleMonsterContainer = battleMonsterContainer; 10 | } 11 | 12 | public BattleResult Calculate() 13 | { 14 | if (BattleVictoryCondition.IsFulfilled(_battleMonsterContainer)) 15 | { 16 | return BattleResult.Victory; 17 | } 18 | 19 | if (BattleDefeatCondition.IsFulfilled(_battleMonsterContainer)) 20 | { 21 | return BattleResult.Defeat; 22 | } 23 | 24 | return BattleResult.None; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Result/BattleResultNextAction.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public enum BattleResultNextAction 4 | { 5 | Title, 6 | Retry, 7 | NextStage, 8 | } 9 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Result/BattleVictoryCondition.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public static class BattleVictoryCondition 6 | { 7 | public static bool IsFulfilled(BattleMonsterContainer battleMonsterContainer) 8 | { 9 | return battleMonsterContainer.GetEnemyBattleMonsters() 10 | .All(monster => monster.IsDead); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Scripts/Domain/Battle/Time/TimeControlUseCase.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public enum TimeScaleType 7 | { 8 | Slow = 0, 9 | Normal = 1, 10 | Fast = 2, 11 | } 12 | 13 | public class TimeControlUseCase 14 | { 15 | public ReadOnlyReactiveProperty IsPlaying => _isPlaying; 16 | public ReadOnlyReactiveProperty TimeScale => _timeScale; 17 | 18 | private readonly ReactiveProperty _isPlaying = new(true); 19 | private readonly ReactiveProperty _timeScale = new(TimeScaleType.Normal); 20 | 21 | private const float StopTimeScale = 0.0f; 22 | 23 | public void Play() 24 | { 25 | _isPlaying.Value = true; 26 | Time.timeScale = ActualTimeScale(_isPlaying.Value, _timeScale.Value); 27 | } 28 | 29 | public void Stop() 30 | { 31 | _isPlaying.Value = false; 32 | Time.timeScale = StopTimeScale; 33 | } 34 | 35 | public void SwitchPlayAndStop() 36 | { 37 | if (_isPlaying.Value) 38 | Stop(); 39 | else 40 | Play(); 41 | } 42 | 43 | public void SetTimeScale(TimeScaleType timeScaleType) 44 | { 45 | _timeScale.Value = timeScaleType; 46 | Time.timeScale = ActualTimeScale(_isPlaying.Value, timeScaleType); 47 | } 48 | 49 | public void SetDefaultTimeScale() 50 | { 51 | _timeScale.Value = TimeScaleType.Normal; 52 | Time.timeScale = ActualTimeScale(_isPlaying.Value, TimeScaleType.Normal); 53 | } 54 | 55 | private static float ActualTimeScale(bool isPlaying, TimeScaleType timeScaleType) 56 | { 57 | return isPlaying ? ToTimeScaleValue(timeScaleType) : StopTimeScale; 58 | } 59 | 60 | private static float ToTimeScaleValue(TimeScaleType timeScaleType) => timeScaleType switch 61 | { 62 | TimeScaleType.Slow => 0.5f, 63 | TimeScaleType.Normal => 1.0f, 64 | TimeScaleType.Fast => 2.0f, 65 | _ => Time.timeScale 66 | }; 67 | } 68 | } -------------------------------------------------------------------------------- /Scripts/Domain/Capture/BattleCaptureSet.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | using UnityEngine; 3 | 4 | namespace Unity1week202403.Domain.Capture 5 | { 6 | public readonly struct BattleCaptureSet 7 | { 8 | public StageId StageId { get; } 9 | public Texture2D Texture { get; } 10 | 11 | public BattleCaptureSet(StageId stageId, Texture2D texture) 12 | { 13 | StageId = stageId; 14 | Texture = texture; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Domain/Capture/CaptureTextureContainer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | using Object = UnityEngine.Object; 5 | 6 | namespace Unity1week202403.Domain.Capture 7 | { 8 | public class CaptureTextureContainer 9 | { 10 | private readonly Dictionary _textures = new(); 11 | 12 | public CaptureTextureContainer() 13 | { 14 | Debug.Log("Capture Container Created"); 15 | } 16 | 17 | public bool Any() => _textures.Count > 0; 18 | 19 | public void Set(StageId stageId, Texture2D texture) 20 | { 21 | _textures[stageId] = texture; 22 | } 23 | 24 | public void Clear() 25 | { 26 | foreach (var texture in _textures.Values) 27 | { 28 | Object.Destroy(texture); 29 | } 30 | 31 | _textures.Clear(); 32 | } 33 | 34 | public IEnumerable All() 35 | { 36 | foreach (var pair in _textures) 37 | { 38 | yield return new BattleCaptureSet(pair.Key, pair.Value); 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Scripts/Domain/Capture/CaptureUseCase.cs: -------------------------------------------------------------------------------- 1 | using Cysharp.Threading.Tasks; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Domain.Capture 6 | { 7 | public class CaptureUseCase 8 | { 9 | private readonly Camera _camera; 10 | private readonly RenderTexture _renderTexture; 11 | private readonly CaptureTextureContainer _textureContainer; 12 | 13 | public CaptureUseCase( 14 | Camera camera, 15 | RenderTexture renderTexture, 16 | CaptureTextureContainer textureContainer) 17 | { 18 | _camera = camera; 19 | _renderTexture = renderTexture; 20 | _textureContainer = textureContainer; 21 | } 22 | 23 | public async UniTask Capture(StageId stageId) 24 | { 25 | _camera.gameObject.SetActive(true); 26 | _camera.Render(); 27 | await UniTask.DelayFrame(1); 28 | _camera.gameObject.SetActive(false); 29 | 30 | RenderTexture.active = _renderTexture; 31 | var texture = new Texture2D(_renderTexture.width, _renderTexture.height, TextureFormat.RGB24, false); 32 | texture.ReadPixels(new Rect(0, 0, _renderTexture.width, _renderTexture.height), 0, 0); 33 | texture.Apply(); 34 | RenderTexture.active = null; 35 | 36 | _textureContainer.Set(stageId, texture); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Scripts/Domain/Costs/CostStatus.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class CostStatus 8 | { 9 | public Cost Current => _reactiveCost.Value; 10 | public ReadOnlyReactiveProperty ReactiveCurrent => _reactiveCost; 11 | 12 | private readonly ReactiveProperty _reactiveCost = new(); 13 | 14 | public CostStatus(Cost initial) 15 | { 16 | _reactiveCost.Value = initial; 17 | } 18 | 19 | public void Consume(Cost cost) 20 | { 21 | _reactiveCost.Value = new Cost(Mathf.Max(0, Current.Value - cost.Value)); 22 | } 23 | 24 | public void Add(Cost cost) 25 | { 26 | _reactiveCost.Value = new Cost(Current.Value + cost.Value); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Scripts/Domain/Costs/PlayerConsumeCostUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class PlayerConsumeCostUseCase 7 | { 8 | private readonly PlayerStatus _playerStatus; 9 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 10 | 11 | public PlayerConsumeCostUseCase( 12 | PlayerStatus playerStatus, 13 | MonsterMasterDataRepository monsterMasterDataRepository) 14 | { 15 | _playerStatus = playerStatus; 16 | _monsterMasterDataRepository = monsterMasterDataRepository; 17 | } 18 | 19 | public void Consume(MonsterId monsterId) 20 | { 21 | var monster = _monsterMasterDataRepository.Get(monsterId); 22 | _playerStatus.CostStatus.Consume(monster.Cost); 23 | } 24 | 25 | public bool CanConsume(MonsterId monsterId) 26 | { 27 | var monster = _monsterMasterDataRepository.Get(monsterId); 28 | return _playerStatus.CostStatus.Current.Value >= monster.Cost.Value; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Scripts/Domain/Debugger/BattleDebug.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SRDebugger; 3 | using VContainer.Unity; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class BattleDebug : IInitializable, IDisposable 8 | { 9 | private const string CategoryName = "Battle"; 10 | 11 | private readonly DynamicOptionContainer _container = new(); 12 | private readonly BattleMonsterContainer _battleMonsterContainer; 13 | 14 | public BattleDebug(BattleMonsterContainer battleMonsterContainer) 15 | { 16 | _battleMonsterContainer = battleMonsterContainer; 17 | } 18 | 19 | public void Initialize() 20 | { 21 | _container.AddOption(OptionDefinition.FromMethod( 22 | name: "強制勝利", 23 | () => 24 | { 25 | // すべての敵モンスターを倒す 26 | foreach (var enemyBattleMonster in _battleMonsterContainer.GetEnemyBattleMonsters()) 27 | { 28 | enemyBattleMonster.Damaged(enemyBattleMonster.Hp.CurrentValue.Max); 29 | } 30 | }, 31 | category: CategoryName 32 | )); 33 | 34 | _container.AddOption(OptionDefinition.FromMethod( 35 | name: "強制敗北", 36 | () => 37 | { 38 | // すべての味方モンスターを倒す 39 | foreach (var allyBattleMonster in _battleMonsterContainer.GetAllyBattleMonsters()) 40 | { 41 | allyBattleMonster.Damaged(allyBattleMonster.Hp.CurrentValue.Max); 42 | } 43 | }, 44 | category: CategoryName 45 | )); 46 | 47 | SRDebug.Instance.AddOptionContainer(_container); 48 | } 49 | 50 | public void Dispose() 51 | { 52 | SRDebug.Instance?.RemoveOptionContainer(_container); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Scripts/Domain/HelpAutoDisplayUseCase.cs: -------------------------------------------------------------------------------- 1 | using Cysharp.Threading.Tasks; 2 | using Unity1week202403.Presentation; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class HelpAutoDisplayUseCase 7 | { 8 | private readonly HelpPresenter _helpPresenter; 9 | 10 | private bool _isRead; 11 | 12 | public HelpAutoDisplayUseCase(HelpPresenter helpPresenter) 13 | { 14 | _helpPresenter = helpPresenter; 15 | } 16 | 17 | private bool IsRead => _isRead; 18 | 19 | public async UniTask TryShowHelpAsync() 20 | { 21 | if (IsRead) return; 22 | 23 | // 既読 24 | SetRead(); 25 | 26 | await _helpPresenter.ShowAsync(); 27 | } 28 | 29 | private void SetRead() 30 | { 31 | _isRead = true; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Scripts/Domain/Monster/MonsterMasterDataService.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Domain 6 | { 7 | public class MonsterMasterDataService 8 | { 9 | private readonly MonsterMasterDataRepository _monsterMasterDataRepository; 10 | 11 | public MonsterMasterDataService(MonsterMasterDataRepository monsterMasterDataRepository) 12 | { 13 | _monsterMasterDataRepository = monsterMasterDataRepository; 14 | } 15 | 16 | public float GetColliderRadius(MonsterId monsterId) 17 | { 18 | var monsterMasterData = _monsterMasterDataRepository.Get(monsterId); 19 | var capsuleCollider = monsterMasterData.Prefab.GetComponentInChildren(); 20 | return capsuleCollider.radius; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Scripts/Domain/MyMath.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public static class MyMath 6 | { 7 | public static float EaseOutCubic(float x){ 8 | return 1 - Mathf.Pow(1 - x, 3); 9 | } 10 | 11 | public static float EaseOutExpo(float x) 12 | { 13 | return x >= 1f ? 1 : 1 - Mathf.Pow(2, -10 * x); 14 | } 15 | 16 | public static float EaseInBack(float x) 17 | { 18 | const float c1 = 1.70158f; 19 | const float c3 = c1 + 1; 20 | 21 | return c3 * x * x * x - c1 * x * x; 22 | } 23 | 24 | public static float EaseOutBack(float x) 25 | { 26 | const float c1 = 1.70158f; 27 | const float c3 = c1 + 1; 28 | 29 | return 1 + c3 * Mathf.Pow(x - 1, 3) + c1 * Mathf.Pow(x - 1, 2); 30 | } 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /Scripts/Domain/PlayerStatus.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public class PlayerStatus 6 | { 7 | public CostStatus CostStatus { get; } 8 | 9 | public PlayerStatus(Cost initialCost) 10 | { 11 | CostStatus = new CostStatus(initialCost); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Scripts/Domain/Scenes/SceneLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Cysharp.Threading.Tasks; 4 | using R3; 5 | using Unity1week202403.Presentation; 6 | using UnityEngine; 7 | using UnityEngine.SceneManagement; 8 | 9 | namespace Unity1week202403.Domain 10 | { 11 | public class SceneLoader 12 | { 13 | private readonly TransitionPresenter _transitionPresenter; 14 | private readonly ReactiveProperty _isLoading = new(false); 15 | 16 | public SceneLoader(TransitionPresenter transitionPresenter) 17 | { 18 | _transitionPresenter = transitionPresenter; 19 | } 20 | 21 | public async UniTask WaitAsync(CancellationToken cancellationToken = default) 22 | { 23 | // すでにロード中でない場合は即座に終了 24 | if (!_isLoading.Value) 25 | return; 26 | 27 | await _isLoading.Where(isLoading => !isLoading).FirstAsync(cancellationToken: cancellationToken); 28 | } 29 | 30 | 31 | public async UniTask LoadAsync(string sceneName, CancellationToken cancellationToken = default) 32 | { 33 | _isLoading.Value = true; 34 | 35 | await _transitionPresenter.ShowAsync(cancellationToken); 36 | 37 | await SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Single); 38 | 39 | await UniTask.Delay(TimeSpan.FromSeconds(0.1f), cancellationToken: cancellationToken); 40 | 41 | await Resources.UnloadUnusedAssets(); 42 | 43 | await UniTask.Delay(TimeSpan.FromSeconds(0.1f), cancellationToken: cancellationToken); 44 | 45 | await _transitionPresenter.HideAsync(cancellationToken); 46 | 47 | _isLoading.Value = false; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Scripts/Domain/SkillCalculator/BattleMonsterAttackCalculator.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public static class BattleMonsterAttackCalculator 4 | { 5 | public static void Calculate(BattleMonster attacker, BattleMonster target) 6 | { 7 | if (attacker.IsDead || target.IsDead) 8 | { 9 | return; 10 | } 11 | 12 | target.Damaged(attacker.Parameter.AttackPower); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Scripts/Domain/SkillCalculator/BattleMonsterHealCalculator.cs: -------------------------------------------------------------------------------- 1 | namespace Unity1week202403.Domain 2 | { 3 | public class BattleMonsterHealCalculator 4 | { 5 | public static void Calculate(BattleMonster invoker, BattleMonster target, ActiveSkill activeSkill) 6 | { 7 | if (invoker.IsDead || target.IsDead) 8 | { 9 | return; 10 | } 11 | 12 | target.Healed((int)activeSkill.Value); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Scripts/Domain/Stage/GetStageCostUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class GetStageCostUseCase 7 | { 8 | private readonly StageMasterDataRepository _stageMasterDataRepository; 9 | 10 | public GetStageCostUseCase( 11 | StageMasterDataRepository stageMasterDataRepository) 12 | { 13 | _stageMasterDataRepository = stageMasterDataRepository; 14 | } 15 | 16 | public Cost Get(StageId stageId) 17 | { 18 | var stageMasterData = _stageMasterDataRepository.Get(stageId); 19 | 20 | return new Cost(stageMasterData.PlayerCost); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Scripts/Domain/Stage/GetStageInfoUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Data; 3 | using Unity1week202403.Structure; 4 | using UnityEngine; 5 | 6 | namespace Unity1week202403.Domain 7 | { 8 | public class GetStageInfoUseCase 9 | { 10 | private readonly StageMasterDataRepository _stageMasterDataRepository; 11 | 12 | public GetStageInfoUseCase( 13 | StageMasterDataRepository stageMasterDataRepository) 14 | { 15 | _stageMasterDataRepository = stageMasterDataRepository; 16 | } 17 | 18 | public StageInfo Get(StageId stageId) 19 | { 20 | var stageMasterData = _stageMasterDataRepository.Get(stageId); 21 | 22 | var monsterGenerateSets = stageMasterData.StageMonsterData 23 | .Select(monsterData => CreateMonsterGenerateSet(monsterData, monsterData.Position)); 24 | 25 | return new StageInfo(monsterGenerateSets); 26 | } 27 | 28 | private MonsterGenerateSet CreateMonsterGenerateSet(StageMonsterData monsterData, Vector3 position) 29 | { 30 | var monsterMasterData = monsterData.MonsterMasterData; 31 | return new MonsterGenerateSet( 32 | monsterMasterData.Id, 33 | position, 34 | monsterMasterData.Prefab); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Scripts/Domain/Stage/LoadStageSceneUseCase.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Threading; 3 | using Cysharp.Threading.Tasks; 4 | using Unity1week202403.Data; 5 | using Unity1week202403.Extensions; 6 | using Unity1week202403.Structure; 7 | 8 | namespace Unity1week202403.Domain 9 | { 10 | public class LoadStageSceneUseCase 11 | { 12 | private readonly StageMasterDataRepository _stageMasterDataRepository; 13 | private readonly StageSceneRepository _stageSceneRepository; 14 | private readonly StageSceneService _stageSceneService; 15 | 16 | public LoadStageSceneUseCase( 17 | StageMasterDataRepository stageMasterDataRepository, 18 | StageSceneRepository stageSceneRepository, 19 | StageSceneService stageSceneService) 20 | { 21 | _stageMasterDataRepository = stageMasterDataRepository; 22 | _stageSceneRepository = stageSceneRepository; 23 | _stageSceneService = stageSceneService; 24 | } 25 | 26 | public async UniTask LoadAsync(StageId stageId, CancellationToken cancellationToken) 27 | { 28 | var stageMasterData = _stageMasterDataRepository.Get(stageId); 29 | 30 | // ステージシーンが設定されていない場合はランダムに選ぶ 31 | var stageSceneName = stageMasterData.HasStageScene() 32 | ? stageMasterData.StageScene.SceneName 33 | : _stageSceneRepository.Scenes.Shuffle().First().SceneName; 34 | 35 | // 次のシーンがすでに読み込まれている場合は何もしない 36 | if (_stageSceneService.IsLoaded(stageSceneName)) 37 | return; 38 | 39 | // 何かしらのステージシーンが読み込まれている場合はアンロード 40 | if (_stageSceneService.IsLoaded()) 41 | { 42 | await _stageSceneService.UnloadAsync(cancellationToken); 43 | } 44 | 45 | await _stageSceneService.LoadAsync(stageSceneName, cancellationToken); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Scripts/Domain/Stage/NextStageUseCase.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using Unity1week202403.Structure; 3 | 4 | namespace Unity1week202403.Domain 5 | { 6 | public class NextStageUseCase 7 | { 8 | private readonly StageSituation _stageSituation; 9 | private readonly StageMasterDataRepository _stageMasterDataRepository; 10 | 11 | public NextStageUseCase( 12 | StageSituation stageSituation, 13 | StageMasterDataRepository stageMasterDataRepository) 14 | { 15 | _stageSituation = stageSituation; 16 | _stageMasterDataRepository = stageMasterDataRepository; 17 | } 18 | 19 | public bool HasNext() 20 | { 21 | var currentStageId = _stageSituation.Get(); 22 | var nextStageId = new StageId(currentStageId.Value + 1); 23 | return _stageMasterDataRepository.Exists(nextStageId); 24 | } 25 | 26 | public StageId SetNext() 27 | { 28 | var currentStageId = _stageSituation.Get(); 29 | var nextStageId = new StageId(currentStageId.Value + 1); 30 | _stageMasterDataRepository.Exists(nextStageId); 31 | _stageSituation.Set(nextStageId); 32 | return nextStageId; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Scripts/Domain/Stage/StageSituation.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Structure; 2 | 3 | namespace Unity1week202403.Domain 4 | { 5 | public class StageSituation 6 | { 7 | private StageId _stageId; 8 | 9 | public StageSituation(StageId initialStageId) 10 | { 11 | _stageId = initialStageId; 12 | } 13 | 14 | public void Set(StageId stageId) 15 | { 16 | _stageId = stageId; 17 | } 18 | 19 | public StageId Get() => _stageId; 20 | } 21 | } -------------------------------------------------------------------------------- /Scripts/Editor/ButtonSePlayerEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Unity1week202403.Data; 4 | using Unity1week202403.Presentation.UI; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | namespace Unity1week202403.Editor 9 | { 10 | [CustomEditor(typeof(ButtonSePlayer))] 11 | public class ButtonSePlayerEditor : UnityEditor.Editor 12 | { 13 | private static bool _isLocked = true; 14 | 15 | public override void OnInspectorGUI() 16 | { 17 | serializedObject.Update(); 18 | 19 | // iteratorを使って、ButtonSePlayerのフィールドを描画する. 20 | var iterator = serializedObject.GetIterator(); 21 | for (var enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) 22 | { 23 | using var disable = new EditorGUI.DisabledGroupScope("m_Script" == iterator.propertyPath); 24 | EditorGUILayout.PropertyField(iterator, true); 25 | 26 | if (iterator.propertyPath == "_buttonSePreset") 27 | { 28 | if (iterator.objectReferenceValue == null) continue; 29 | var preset = new SerializedObject(iterator.objectReferenceValue); 30 | PresetDrawer(preset); 31 | } 32 | } 33 | 34 | serializedObject.ApplyModifiedProperties(); 35 | } 36 | 37 | private static void PresetDrawer(SerializedObject presetObject) 38 | { 39 | presetObject.Update(); 40 | _isLocked = EditorGUILayout.ToggleLeft("Lock", _isLocked); 41 | 42 | using var indent = new EditorGUI.IndentLevelScope(1); 43 | 44 | var presetIterator = presetObject.GetIterator(); 45 | for (var enterChildren = true; presetIterator.NextVisible(enterChildren); enterChildren = false) 46 | { 47 | if ("m_Script" == presetIterator.propertyPath) continue; 48 | if (presetIterator.propertyPath is "_clickClip" or "_hoverClip") 49 | { 50 | using var horizontal = new EditorGUILayout.HorizontalScope(); 51 | using (new EditorGUI.DisabledGroupScope(_isLocked)) 52 | { 53 | EditorGUILayout.PropertyField(presetIterator, true); 54 | } 55 | using (new EditorGUI.DisabledGroupScope(presetIterator.objectReferenceValue == null)) 56 | { 57 | if (GUILayout.Button("Play", GUILayout.Width(50))) 58 | { 59 | var clip = presetIterator.objectReferenceValue as AudioClip; 60 | PlayClip(clip); 61 | } 62 | } 63 | } 64 | } 65 | 66 | presetObject.ApplyModifiedProperties(); 67 | } 68 | 69 | // エディタ上でのサウンド再生. 70 | private static void PlayClip(AudioClip clip) 71 | { 72 | if (clip == null) return; 73 | 74 | var audioUtil = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.AudioUtil"); 75 | var playClipMethod = audioUtil.GetMethod( 76 | "PlayPreviewClip", 77 | BindingFlags.Static | BindingFlags.Public, 78 | null, 79 | new Type[] { typeof(AudioClip), typeof(int), typeof(bool) }, 80 | null 81 | ); 82 | 83 | playClipMethod.Invoke(null, new object[] { clip, 0, false }); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Scripts/Editor/ButtonSePresetEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Unity1week202403.Data; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | namespace Unity1week202403.Editor 8 | { 9 | [CustomEditor(typeof(ButtonSePreset))] 10 | public class ButtonSePresetEditor : UnityEditor.Editor 11 | { 12 | public override void OnInspectorGUI() 13 | { 14 | serializedObject.Update(); 15 | var buttonSePreset = target as ButtonSePreset; 16 | 17 | using (new EditorGUILayout.HorizontalScope()) 18 | { 19 | var hoverClipProperty = serializedObject.FindProperty("_hoverClip"); 20 | EditorGUILayout.PropertyField(hoverClipProperty); 21 | using (new EditorGUI.DisabledGroupScope(hoverClipProperty.objectReferenceValue == null)) 22 | { 23 | if (GUILayout.Button("Play", GUILayout.Width(50))) 24 | { 25 | PlayClip(buttonSePreset.HoverClip); 26 | } 27 | } 28 | } 29 | 30 | using (new EditorGUILayout.HorizontalScope()) 31 | { 32 | var clickClipProperty = serializedObject.FindProperty("_clickClip"); 33 | EditorGUILayout.PropertyField(clickClipProperty); 34 | using (new EditorGUI.DisabledGroupScope(clickClipProperty.objectReferenceValue == null)) 35 | { 36 | if (GUILayout.Button("Play", GUILayout.Width(50))) 37 | { 38 | PlayClip(buttonSePreset.HoverClip); 39 | } 40 | } 41 | } 42 | 43 | serializedObject.ApplyModifiedProperties(); 44 | } 45 | 46 | // エディタ上でのサウンド再生. 47 | private void PlayClip(AudioClip clip) 48 | { 49 | if (clip == null) return; 50 | 51 | var audioUtil = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.AudioUtil"); 52 | var playClipMethod = audioUtil.GetMethod( 53 | "PlayPreviewClip", 54 | BindingFlags.Static | BindingFlags.Public, 55 | null, 56 | new Type[] { typeof(AudioClip), typeof(int), typeof(bool) }, 57 | null 58 | ); 59 | 60 | playClipMethod.Invoke(null, new object[] { clip, 0, false }); 61 | } 62 | 63 | 64 | // エディタ上でのサウンドを停止する. 65 | private void StopClip(AudioClip clip) 66 | { 67 | if (clip == null) return; 68 | 69 | var unityEditorAssembly = typeof(AudioImporter).Assembly; 70 | var audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil"); 71 | var method = audioUtilClass.GetMethod( 72 | "StopClip", 73 | BindingFlags.Static | BindingFlags.Public, 74 | null, 75 | new Type[] { typeof(AudioClip) }, 76 | null 77 | ); 78 | 79 | method.Invoke(null, new object[] { clip }); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Scripts/Editor/MasterDataAssetProcessor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace Unity1week202403.Editor 4 | { 5 | public class MasterDataAssetProcessor : AssetPostprocessor 6 | { 7 | private static readonly MonsterMasterDataAssetProcess _monsterMasterDataAssetProcess = new(); 8 | private static readonly StageMasterDataAssetProcess _stageMasterDataAssetProcess = new(); 9 | 10 | public static void OnPostprocessAllAssets( 11 | string[] importedAssets, 12 | string[] deletedAssets, 13 | string[] movedAssets, 14 | string[] movedFromAssetPaths) 15 | { 16 | _monsterMasterDataAssetProcess.OnPostprocessAllAssets( 17 | importedAssets, 18 | deletedAssets, 19 | movedAssets, 20 | movedFromAssetPaths); 21 | 22 | _stageMasterDataAssetProcess.OnPostprocessAllAssets( 23 | importedAssets, 24 | deletedAssets, 25 | movedAssets, 26 | movedFromAssetPaths); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Scripts/Editor/MonsterMasterDataAssetProcess.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | using Unity1week202403.Data; 4 | using UnityEditor; 5 | 6 | namespace Unity1week202403.Editor 7 | { 8 | public class MonsterMasterDataAssetProcess 9 | { 10 | private const string FolderPath = "Assets/Application/ScriptableObjects/MasterData/Monster/"; 11 | 12 | private const string DataStorePath = 13 | "Assets/Application/ScriptableObjects/MasterData/DataStoreSource/MonsterMasterDataStoreSource.asset"; 14 | 15 | public void OnPostprocessAllAssets( 16 | string[] importedAssets, 17 | string[] deletedAssets, 18 | string[] movedAssets, 19 | string[] movedFromAssetPaths) 20 | { 21 | var dataStore = AssetDatabase.LoadAssetAtPath(DataStorePath); 22 | Assert.IsNotNull(dataStore); 23 | 24 | var dataStoreSerializedObject = new SerializedObject(dataStore); 25 | dataStoreSerializedObject.Update(); 26 | 27 | var targetImportedAssets = importedAssets 28 | .Where(path => path.StartsWith(FolderPath)) 29 | .ToArray(); 30 | 31 | var targetDeletedAssets = deletedAssets 32 | .Where(path => path.StartsWith(FolderPath)) 33 | .ToArray(); 34 | 35 | var targetMovedAssets = movedAssets 36 | .Where(path => path.StartsWith(FolderPath)) 37 | .ToArray(); 38 | 39 | var targetMovedFromAssetPaths = movedFromAssetPaths 40 | .Where(path => path.StartsWith(FolderPath)) 41 | .ToArray(); 42 | 43 | if (!targetImportedAssets 44 | .Concat(targetDeletedAssets) 45 | .Concat(targetMovedAssets) 46 | .Concat(targetMovedFromAssetPaths) 47 | .Any()) 48 | { 49 | // 何も変更がない場合は何もしない 50 | return; 51 | } 52 | 53 | // 新規で追加されたアセットをデータストアに追加する 54 | var assets = AssetDatabase.FindAssets("t:MonsterMasterData", new[] { FolderPath }) 55 | .Select(AssetDatabase.GUIDToAssetPath) 56 | .Select(AssetDatabase.LoadAssetAtPath) 57 | .ToArray(); 58 | 59 | var monsterMasterDataArray = dataStoreSerializedObject.FindProperty("_data"); 60 | monsterMasterDataArray.ClearArray(); 61 | foreach (var masterData in assets) 62 | { 63 | monsterMasterDataArray.arraySize++; 64 | var arrayElement = monsterMasterDataArray.GetArrayElementAtIndex(monsterMasterDataArray.arraySize - 1); 65 | arrayElement.objectReferenceValue = masterData; 66 | arrayElement.serializedObject.ApplyModifiedProperties(); 67 | } 68 | 69 | dataStore.Validate(); 70 | dataStoreSerializedObject.ApplyModifiedProperties(); 71 | EditorUtility.SetDirty(dataStore); 72 | AssetDatabase.SaveAssets(); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /Scripts/Editor/SceneObjectEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity1week202403.Data; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace Unity1week202403.Editor 7 | { 8 | [CustomPropertyDrawer(typeof(SceneObject))] 9 | public class SceneObjectEditor : PropertyDrawer 10 | { 11 | private const string PropertyName = "_sceneName"; 12 | 13 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 14 | { 15 | var sceneObj = GetSceneObject(property.FindPropertyRelative(PropertyName).stringValue); 16 | var newScene = EditorGUI.ObjectField(position, label, sceneObj, typeof(SceneAsset), false); 17 | if (newScene == null) 18 | { 19 | var prop = property.FindPropertyRelative(PropertyName); 20 | prop.stringValue = ""; 21 | } 22 | else 23 | { 24 | if (newScene.name == property.FindPropertyRelative(PropertyName).stringValue) return; 25 | 26 | var scnObj = GetSceneObject(newScene.name); 27 | if (scnObj == null) 28 | { 29 | Debug.LogWarning("The scene " + newScene.name + 30 | " cannot be used. To use this scene add it to the build settings for the project."); 31 | } 32 | else 33 | { 34 | var prop = property.FindPropertyRelative(PropertyName); 35 | prop.stringValue = newScene.name; 36 | } 37 | } 38 | } 39 | 40 | private SceneAsset GetSceneObject(string sceneObjectName) 41 | { 42 | if (string.IsNullOrEmpty(sceneObjectName)) 43 | return null; 44 | 45 | for (var i = 0; i < EditorBuildSettings.scenes.Length; i++) 46 | { 47 | EditorBuildSettingsScene scene = EditorBuildSettings.scenes[i]; 48 | if (scene.path.IndexOf(sceneObjectName, StringComparison.Ordinal) != -1) 49 | { 50 | return AssetDatabase.LoadAssetAtPath(scene.path, typeof(SceneAsset)) as SceneAsset; 51 | } 52 | } 53 | 54 | Debug.Log("Scene [" + sceneObjectName + 55 | "] cannot be used. Add this scene to the 'Scenes in the Build' in the build settings."); 56 | return null; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Scripts/Editor/StageMasterDataAssetProcess.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | using Unity1week202403.Data; 4 | using UnityEditor; 5 | 6 | namespace Unity1week202403.Editor 7 | { 8 | public class StageMasterDataAssetProcess 9 | { 10 | private const string FolderPath = "Assets/Application/ScriptableObjects/MasterData/Stage/"; 11 | 12 | private const string DataStorePath = 13 | "Assets/Application/ScriptableObjects/MasterData/DataStoreSource/StageMasterDataStoreSource.asset"; 14 | 15 | public void OnPostprocessAllAssets( 16 | string[] importedAssets, 17 | string[] deletedAssets, 18 | string[] movedAssets, 19 | string[] movedFromAssetPaths) 20 | { 21 | var dataStore = AssetDatabase.LoadAssetAtPath(DataStorePath); 22 | Assert.IsNotNull(dataStore); 23 | 24 | var dataStoreSerializedObject = new SerializedObject(dataStore); 25 | dataStoreSerializedObject.Update(); 26 | 27 | var targetImportedAssets = importedAssets 28 | .Where(path => path.StartsWith(FolderPath)) 29 | .ToArray(); 30 | 31 | var targetDeletedAssets = deletedAssets 32 | .Where(path => path.StartsWith(FolderPath)) 33 | .ToArray(); 34 | 35 | var targetMovedAssets = movedAssets 36 | .Where(path => path.StartsWith(FolderPath)) 37 | .ToArray(); 38 | 39 | var targetMovedFromAssetPaths = movedFromAssetPaths 40 | .Where(path => path.StartsWith(FolderPath)) 41 | .ToArray(); 42 | 43 | if (!targetImportedAssets 44 | .Concat(targetDeletedAssets) 45 | .Concat(targetMovedAssets) 46 | .Concat(targetMovedFromAssetPaths) 47 | .Any()) 48 | { 49 | // 何も変更がない場合は何もしない 50 | return; 51 | } 52 | 53 | // 新規で追加されたアセットをデータストアに追加する 54 | var assets = AssetDatabase.FindAssets($"t:{nameof(StageMasterData)}", new[] { FolderPath }) 55 | .Select(AssetDatabase.GUIDToAssetPath) 56 | .Select(AssetDatabase.LoadAssetAtPath) 57 | .ToArray(); 58 | 59 | var monsterMasterDataArray = dataStoreSerializedObject.FindProperty("_data"); 60 | monsterMasterDataArray.ClearArray(); 61 | foreach (var masterData in assets) 62 | { 63 | monsterMasterDataArray.arraySize++; 64 | var arrayElement = monsterMasterDataArray.GetArrayElementAtIndex(monsterMasterDataArray.arraySize - 1); 65 | arrayElement.objectReferenceValue = masterData; 66 | arrayElement.serializedObject.ApplyModifiedProperties(); 67 | } 68 | 69 | dataStore.Validate(); 70 | dataStoreSerializedObject.ApplyModifiedProperties(); 71 | EditorUtility.SetDirty(dataStore); 72 | AssetDatabase.SaveAssets(); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /Scripts/Editor/StageMasterDataEditor.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Data; 2 | using UnityEditor; 3 | 4 | namespace Unity1week202403.Editor 5 | { 6 | [CustomEditor(typeof(StageMasterData))] 7 | public class StageMasterDataEditor : UnityEditor.Editor 8 | { 9 | private SerializedProperty _stageMonsterListProperty; 10 | 11 | private void OnEnable() 12 | { 13 | _stageMonsterListProperty = serializedObject.FindProperty("_stageMonsterList"); 14 | } 15 | 16 | public override void OnInspectorGUI() 17 | { 18 | serializedObject.Update(); 19 | 20 | var iterator = serializedObject.GetIterator(); 21 | for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) 22 | { 23 | using (new EditorGUI.DisabledScope("m_Script" == iterator.propertyPath)) 24 | EditorGUILayout.PropertyField(iterator, true); 25 | 26 | if (iterator.propertyPath == "_stageScene") 27 | { 28 | // SceneObjectのプレビューを表示 29 | var sceneObject = iterator.boxedValue as SceneObject; 30 | if (sceneObject == null || sceneObject.IsEmpty) 31 | { 32 | EditorGUILayout.HelpBox("指定なしの場合はランダムで選定されます。", MessageType.Info); 33 | } 34 | else if (sceneObject is { IsEmpty: false }) 35 | { 36 | // "Scenes/Stage" 以下にあるシーンのみを選択可能とする 37 | var scenePath = $"Assets/Application/Scenes/Stage/{sceneObject.SceneName}.unity"; 38 | var sceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); 39 | if (sceneAsset == null) 40 | { 41 | EditorGUILayout.HelpBox("Stage/以下のシーンではありません。", MessageType.Error); 42 | } 43 | } 44 | } 45 | } 46 | 47 | // Costの合計を描画 48 | var cost = 0; 49 | for (var i = 0; i < _stageMonsterListProperty.arraySize; i++) 50 | { 51 | var element = _stageMonsterListProperty.GetArrayElementAtIndex(i); 52 | var monsterData = element.FindPropertyRelative("_monsterMasterData").objectReferenceValue as MonsterMasterData; 53 | cost += monsterData.Cost.Value; 54 | } 55 | 56 | EditorGUILayout.LabelField("Total Cost", cost.ToString()); 57 | 58 | serializedObject.ApplyModifiedProperties(); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Scripts/Extensions/DisposableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Unity1week202403.Extensions 4 | { 5 | public static class DisposableExtensions 6 | { 7 | public static T AddTo(this T disposable, Presenter controller) where T : IDisposable 8 | { 9 | controller.AddDisposable(disposable); 10 | return disposable; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Scripts/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Unity1week202403.Extensions 5 | { 6 | public static class EnumerableExtensions 7 | { 8 | public static IEnumerable Shuffle(this IEnumerable source) 9 | { 10 | return source.OrderBy(x => System.Guid.NewGuid()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Scripts/Extensions/Presenter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using R3; 3 | 4 | namespace Unity1week202403.Extensions 5 | { 6 | public class Presenter : IDisposable 7 | { 8 | private readonly CompositeDisposable _disposable = new(); 9 | 10 | public void AddDisposable(IDisposable item) 11 | { 12 | _disposable.Add(item); 13 | } 14 | 15 | void IDisposable.Dispose() => _disposable.Dispose(); 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Installer/AudioLifetimeScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Unity1week202403.Data; 3 | using Unity1week202403.Domain; 4 | using Unity1week202403.Presentation; 5 | using UnityEngine; 6 | using VContainer; 7 | using VContainer.Unity; 8 | 9 | namespace Unity1week202403.Installer 10 | { 11 | [Serializable] 12 | public class AudioLifetimeScope : LifetimeScopeBuilder 13 | { 14 | [SerializeField] 15 | private AudioResource _audioResource; 16 | 17 | public override void Configure(IContainerBuilder builder) 18 | { 19 | builder.RegisterInstance(_audioResource); 20 | 21 | builder.Register(Lifetime.Singleton); 22 | builder.Register(Lifetime.Singleton).AsImplementedInterfaces().AsSelf(); 23 | 24 | builder.Register(Lifetime.Singleton); 25 | builder.Register(Lifetime.Singleton); 26 | 27 | builder.RegisterComponentOnNewGameObject(Lifetime.Singleton).DontDestroyOnLoad(); 28 | builder.RegisterComponentOnNewGameObject(Lifetime.Singleton).DontDestroyOnLoad(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Scripts/Installer/EndingLifetimeScope.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Unity1week202403.Domain.Capture; 3 | using Unity1week202403.Presentation; 4 | using Unity1week202403.Structure; 5 | using UnityEngine; 6 | using UnityEngine.Experimental.Rendering; 7 | using VContainer; 8 | using VContainer.Unity; 9 | 10 | namespace Unity1week202403.Installer 11 | { 12 | public class EndingLifetimeScope : LifetimeScope 13 | { 14 | [SerializeField] 15 | private Texture2D _dummyTexture; 16 | 17 | protected override void Configure(IContainerBuilder builder) 18 | { 19 | builder.RegisterComponentInHierarchy(); 20 | builder.RegisterEntryPoint(); 21 | 22 | builder.Register(Lifetime.Scoped); 23 | builder.RegisterComponentInHierarchy(); 24 | 25 | #if UNITY_EDITOR 26 | builder.RegisterBuildCallback(resolver => 27 | { 28 | var container = resolver.Resolve(); 29 | if (container.Any()) return; 30 | 31 | // デバッグ用ダミーデータを生成 32 | foreach (var stageId in Enumerable.Range(1, 15).Select(x => new StageId(x))) 33 | { 34 | var texture2D = new Texture2D(_dummyTexture.width, _dummyTexture.height, GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None); 35 | texture2D.SetPixels(_dummyTexture.GetPixels()); 36 | texture2D.Apply(); 37 | container.Set(stageId, texture2D); 38 | } 39 | }); 40 | #endif 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Scripts/Installer/LifetimeScopeBuilder.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using VContainer; 3 | 4 | namespace Unity1week202403.Installer 5 | { 6 | public abstract class LifetimeScopeBuilder : MonoBehaviour 7 | { 8 | public abstract void Configure(IContainerBuilder builder); 9 | } 10 | } -------------------------------------------------------------------------------- /Scripts/Installer/RootLifetimeScope.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Unity1week202403.Data; 3 | using Unity1week202403.Domain; 4 | using Unity1week202403.Domain.Capture; 5 | using Unity1week202403.Presentation; 6 | using UnityEngine; 7 | using VContainer; 8 | using VContainer.Unity; 9 | 10 | namespace Unity1week202403.Installer 11 | { 12 | public class RootLifetimeScope : LifetimeScope 13 | { 14 | [SerializeField] 15 | private List _lifetimeScopeBuilders; 16 | 17 | [SerializeField] 18 | private TransitionView _transitionViewPrefab; 19 | 20 | [SerializeField] 21 | private StageMasterDataStoreSource _stageMasterDataStoreSource; 22 | 23 | protected override void Configure(IContainerBuilder builder) 24 | { 25 | foreach (var lifetimeScopeBuilder in _lifetimeScopeBuilders) 26 | { 27 | lifetimeScopeBuilder.Configure(builder); 28 | } 29 | 30 | builder.Register(Lifetime.Singleton); 31 | 32 | builder.Register(Lifetime.Singleton); 33 | builder.RegisterBuildCallback(resolver => resolver.Resolve()); 34 | 35 | builder.RegisterEntryPoint(); 36 | 37 | BuildTransition(builder); 38 | BuildStageMasterData(builder); 39 | } 40 | 41 | private void BuildTransition(IContainerBuilder builder) 42 | { 43 | builder.RegisterComponentInNewPrefab(_transitionViewPrefab, Lifetime.Singleton) 44 | .DontDestroyOnLoad(); 45 | builder.RegisterEntryPoint().AsSelf(); 46 | 47 | builder.RegisterBuildCallback(resolver => resolver.Resolve()); 48 | } 49 | 50 | private void BuildStageMasterData(IContainerBuilder builder) 51 | { 52 | builder.Register(Lifetime.Singleton); 53 | builder.RegisterInstance(_stageMasterDataStoreSource); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Scripts/Installer/TitleLifetimeScope.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Presentation; 2 | using UnityEngine; 3 | using VContainer; 4 | using VContainer.Unity; 5 | 6 | namespace Unity1week202403.Installer 7 | { 8 | public class TitleLifetimeScope : LifetimeScope 9 | { 10 | [SerializeField] 11 | private Transform _uiRoot; 12 | 13 | [SerializeField] 14 | private LicenseView _licenseViewPrefab; 15 | 16 | [SerializeField] 17 | private TextAsset _licenseText; 18 | 19 | protected override void Configure(IContainerBuilder builder) 20 | { 21 | builder.RegisterComponentInHierarchy(); 22 | builder.RegisterEntryPoint(); 23 | 24 | builder.RegisterEntryPoint(); 25 | builder.RegisterComponentInHierarchy(); 26 | 27 | BuildLicense(builder); 28 | } 29 | 30 | private void BuildLicense(IContainerBuilder builder) 31 | { 32 | builder.Register(Lifetime.Scoped).WithParameter(_licenseText); 33 | builder.RegisterFactory(_ => { return () => Instantiate(_licenseViewPrefab, _uiRoot); }, 34 | Lifetime.Scoped); 35 | builder.RegisterEntryPoint().AsSelf(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Abnormality/AbnormalityView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Unity1week202403.Data; 5 | using Unity1week202403.Domain; 6 | using UnityEngine; 7 | 8 | namespace Unity1week202403.Presentation 9 | { 10 | public class AbnormalityView : MonoBehaviour 11 | { 12 | [SerializeField] 13 | private Transform _holder; 14 | 15 | [SerializeField] 16 | private List _pairs; 17 | 18 | private readonly Dictionary _abnormalityCache = new(); 19 | 20 | public void UpdateAbnormality(AbnormalityTypeCollection abnormalityTypeCollection) 21 | { 22 | foreach (var abnormalityType in abnormalityTypeCollection.Types) 23 | { 24 | Show(abnormalityType); 25 | } 26 | 27 | foreach (var abnormalityType in _abnormalityCache.Keys.ToArray()) 28 | { 29 | if (!abnormalityTypeCollection.Contains(abnormalityType)) 30 | { 31 | Hide(abnormalityType); 32 | } 33 | } 34 | } 35 | 36 | private void Show(AbnormalityType type) 37 | { 38 | // 既に表示されている場合は何もしない 39 | if (_abnormalityCache.ContainsKey(type)) 40 | return; 41 | 42 | var prefab = GetPrefab(type); 43 | _abnormalityCache.Add(type, Instantiate(prefab, transform)); 44 | } 45 | 46 | private void Hide(AbnormalityType type) 47 | { 48 | if (!_abnormalityCache.ContainsKey(type)) 49 | return; 50 | 51 | Destroy(_abnormalityCache[type]); 52 | _abnormalityCache.Remove(type); 53 | } 54 | 55 | private GameObject GetPrefab(AbnormalityType type) 56 | { 57 | return _pairs.Find(x => x.Type == type).Prefab; 58 | } 59 | 60 | [Serializable] 61 | public class Pair 62 | { 63 | public AbnormalityType Type; 64 | public GameObject Prefab; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/AudioSettingPresenter.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using Unity1week202403.Domain; 3 | using Unity1week202403.Extensions; 4 | using VContainer.Unity; 5 | 6 | namespace Unity1week202403.Presentation 7 | { 8 | public class AudioSettingPresenter : Presenter, IInitializable 9 | { 10 | private readonly AudioSettingView _audioSettingView; 11 | private readonly CreateAudioSettingViewModelUseCase _createAudioSettingViewModelUseCase; 12 | private readonly AudioSettingsService _audioSettingsService; 13 | private readonly AudioPlayer _audioPlayer; 14 | 15 | public AudioSettingPresenter( 16 | AudioSettingView audioSettingView, 17 | CreateAudioSettingViewModelUseCase createAudioSettingViewModelUseCase, 18 | AudioSettingsService audioSettingsService, 19 | AudioPlayer audioPlayer) 20 | { 21 | _audioSettingView = audioSettingView; 22 | _createAudioSettingViewModelUseCase = createAudioSettingViewModelUseCase; 23 | _audioSettingsService = audioSettingsService; 24 | _audioPlayer = audioPlayer; 25 | } 26 | 27 | public void Initialize() 28 | { 29 | var viewModel = _createAudioSettingViewModelUseCase.Create(); 30 | _audioSettingView.ApplyViewModel(viewModel); 31 | 32 | _audioSettingView.OnChangeBgmVolumeAsObservable() 33 | .Subscribe(volume => _audioSettingsService.SetBgmVolume(volume)) 34 | .AddTo(this); 35 | 36 | _audioSettingView.OnChangeSeVolumeAsObservable() 37 | .Subscribe(volume => _audioSettingsService.SetSeVolume(volume)) 38 | .AddTo(this); 39 | 40 | _audioSettingView.OnPointerUpSeVolumeAsObservable() 41 | .Subscribe(_ => _audioPlayer.PlaySe(_audioSettingView.GetSeSampleClip())) 42 | .AddTo(this); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/AudioSettingView.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Presentation 6 | { 7 | public class AudioSettingView : MonoBehaviour 8 | { 9 | [SerializeField] 10 | private BgmSettingView _bgmSettingView; 11 | 12 | [SerializeField] 13 | private SeSettingView _seSettingView; 14 | 15 | public void ApplyViewModel(ViewModel viewModel) 16 | { 17 | if (viewModel == null) 18 | { 19 | gameObject.SetActive(false); 20 | return; 21 | } 22 | 23 | _bgmSettingView.SetVolume(viewModel.BgmVolume); 24 | _seSettingView.SetVolume(viewModel.SeVolume); 25 | } 26 | 27 | public void SetBgmVolume(AudioVolume volume) => _bgmSettingView.SetVolume(volume); 28 | 29 | public void SetSfxVolume(AudioVolume volume) => _seSettingView.SetVolume(volume); 30 | 31 | public Observable OnChangeBgmVolumeAsObservable() => _bgmSettingView 32 | .OnChangeVolumeAsObservable() 33 | .Select(volume => new AudioVolume(volume)); 34 | 35 | public Observable OnChangeSeVolumeAsObservable() => _seSettingView 36 | .OnChangeVolumeAsObservable() 37 | .Select(volume => new AudioVolume(volume)); 38 | 39 | public Observable OnPointerUpSeVolumeAsObservable() => _seSettingView.OnPointerUpAsObservable(); 40 | 41 | public AudioClip GetSeSampleClip() => _seSettingView.SampleClip; 42 | 43 | public class ViewModel 44 | { 45 | public AudioVolume BgmVolume { get; } 46 | public AudioVolume SeVolume { get; } 47 | 48 | public ViewModel(AudioVolume bgmVolume, AudioVolume seVolume) 49 | { 50 | BgmVolume = bgmVolume; 51 | SeVolume = seVolume; 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/BgmPlayer.cs: -------------------------------------------------------------------------------- 1 | using Cysharp.Threading.Tasks; 2 | using DG.Tweening; 3 | using UnityEngine; 4 | 5 | namespace Unity1week202403.Presentation 6 | { 7 | [RequireComponent(typeof(AudioSource))] 8 | public class BgmPlayer : MonoBehaviour 9 | { 10 | private AudioSource _audioSource; 11 | 12 | private float _volume; 13 | 14 | private void Awake() 15 | { 16 | _audioSource = GetComponent(); 17 | _audioSource.playOnAwake = false; 18 | } 19 | 20 | public void Play(AudioClip audioClip, bool isLoop) 21 | { 22 | SetVolume(_volume); 23 | _audioSource.clip = audioClip; 24 | _audioSource.loop = isLoop; 25 | _audioSource.Play(); 26 | } 27 | 28 | public async UniTask StopAsync(float fadeoutTime = 0) 29 | { 30 | if (fadeoutTime > 0f) 31 | { 32 | await _audioSource 33 | .DOFade(0, fadeoutTime) 34 | .Play(); 35 | } 36 | 37 | _audioSource.Stop(); 38 | } 39 | 40 | public void SetVolume(float volume) 41 | { 42 | _volume = volume; 43 | _audioSource.volume = volume; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/BgmSettingView.cs: -------------------------------------------------------------------------------- 1 | using R3; 2 | using Unity1week202403.Structure; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | namespace Unity1week202403.Presentation 7 | { 8 | public class BgmSettingView : MonoBehaviour 9 | { 10 | [SerializeField] 11 | private Slider _slider; 12 | 13 | public void SetVolume(AudioVolume volume) => _slider.value = volume.Value; 14 | 15 | public Observable OnChangeVolumeAsObservable() => _slider.OnValueChangedAsObservable(); 16 | } 17 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/SePlayer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Unity1week202403.Presentation 4 | { 5 | [RequireComponent(typeof(AudioSource))] 6 | public class SePlayer : MonoBehaviour 7 | { 8 | private AudioSource _audioSource; 9 | 10 | private void Awake() 11 | { 12 | _audioSource = GetComponent(); 13 | _audioSource.playOnAwake = false; 14 | _audioSource.loop = false; 15 | } 16 | 17 | public void PlayOneShot(AudioClip audioClip) 18 | { 19 | _audioSource.PlayOneShot(audioClip); 20 | } 21 | 22 | public void SetVolume(float volume) 23 | { 24 | _audioSource.volume = volume; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Scripts/Presentation/Audio/SePlayerForButton.cs: -------------------------------------------------------------------------------- 1 | using Unity1week202403.Domain; 2 | using UnityEngine; 3 | using UnityEngine.Assertions; 4 | using UnityEngine.EventSystems; 5 | using UnityEngine.UI; 6 | using VContainer; 7 | using VContainer.Unity; 8 | 9 | namespace Unity1week202403.Presentation 10 | { 11 | public class SePlayerForButton : MonoBehaviour, IPointerClickHandler 12 | { 13 | [SerializeField] 14 | private Button _button; 15 | 16 | [SerializeField] 17 | private string _onClickSeKey; 18 | 19 | [Inject] 20 | private readonly AudioPlayer _audioPlayer; 21 | 22 | private void Start() 23 | { 24 | var lifetimeScope = LifetimeScope.Find(); 25 | lifetimeScope.Container.Inject(this); 26 | } 27 | 28 | public void OnPointerClick(PointerEventData eventData) 29 | { 30 | if (!_button.interactable) return; 31 | 32 | if (!string.IsNullOrEmpty(_onClickSeKey)) 33 | { 34 | _audioPlayer?.PlaySe(_onClickSeKey); 35 | } 36 | } 37 | 38 | private void OnValidate() 39 | { 40 | if (_button == null) 41 | { 42 | _button = GetComponent