Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0bc810c
ゾンビアセット追加
reigithub Jul 14, 2026
3a20b41
サービス初期化タイミング
reigithub Jul 14, 2026
73ac632
サービス初期化タイミング
reigithub Jul 14, 2026
1d7f2d0
ゾンビアセット仮セットアップ
reigithub Jul 14, 2026
be7cbf9
ModelAssetNameでロード
reigithub Jul 14, 2026
1f814d8
仮エネミー
reigithub Jul 14, 2026
02c9b01
MessageBroker登録をゲーム毎に構築
reigithub Jul 14, 2026
61d710d
HorrorSignals
reigithub Jul 14, 2026
245f1b4
射撃ダメージ視覚化
reigithub Jul 14, 2026
aa22abd
rename: HorrorSignals.Combat.Damaged
reigithub Jul 14, 2026
042321b
ゾンビのけぞりアニメ
reigithub Jul 14, 2026
b0eb25e
ゾンビマスタ調整
reigithub Jul 14, 2026
a144f69
HorrorEnemyController
reigithub Jul 14, 2026
90a27c4
ナビメッシュ設定
reigithub Jul 14, 2026
c07b0f8
移動アニメーション移行を平滑化
reigithub Jul 15, 2026
2c8ca06
ライト角度調整
reigithub Jul 15, 2026
0bb018c
Player.EquipをVector2に修正
reigithub Jul 15, 2026
f81b7e9
発砲ノイズ不具合修正
reigithub Jul 15, 2026
b3dfd0f
HorrorPauseResult
reigithub Jul 15, 2026
f257b79
InternalsVisibleTo
reigithub Jul 15, 2026
e622334
InputSystemService
reigithub Jul 15, 2026
236b514
SurvivorNetwork
reigithub Jul 15, 2026
3d67d92
public static -> internal static
reigithub Jul 15, 2026
33e3988
UnityMCPアプデ
reigithub Jul 15, 2026
7033871
HorrorPlayerMaster追加
reigithub Jul 15, 2026
9446272
プレイヤー足音実装
reigithub Jul 16, 2026
e036559
エディタ編集時エラー修正
reigithub Jul 16, 2026
2036073
LoadByCurrentSlotAsync
reigithub Jul 16, 2026
a29766d
saveMode
reigithub Jul 16, 2026
5634b70
ポーズ画面からリスタート/ロードゲーム
reigithub Jul 16, 2026
5dc0cb8
HorrorGameOverDialog
reigithub Jul 16, 2026
fc227dd
プレイヤーHPバー
reigithub Jul 16, 2026
f3ed23e
プレイヤーHP実装追加
reigithub Jul 17, 2026
5b99d83
プレイヤーDead通知
reigithub Jul 17, 2026
e3e15cc
AddTo(this)
reigithub Jul 17, 2026
3740186
入力ブロックカウント
reigithub Jul 17, 2026
d211027
update engine: Unity6000.3.20f1
reigithub Jul 17, 2026
29c07b8
update ci: Unity6000.3.20f1
reigithub Jul 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker/unity-ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
# 設定方法: .env ファイルで UNITY_MODULE を変更

# ビルド引数でプラットフォームを指定可能
ARG UNITY_VERSION=6000.3.8f1
ARG UNITY_VERSION=6000.3.20f1
ARG UNITY_MODULE=windows-mono
ARG IMAGE_VERSION=3

Expand Down
8 changes: 4 additions & 4 deletions docker/unity-ci/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ services:
context: .
dockerfile: Dockerfile
args:
UNITY_VERSION: ${UNITY_VERSION:-6000.3.8f1}
UNITY_VERSION: ${UNITY_VERSION:-6000.3.20f1}
UNITY_MODULE: ${UNITY_MODULE:-windows-mono}
IMAGE_VERSION: ${IMAGE_VERSION:-3}
image: unity-ci-windows-mono:${UNITY_VERSION:-6000.3.8f1}
image: unity-ci-windows-mono:${UNITY_VERSION:-6000.3.20f1}
container_name: unity-ci-windows-mono
restart: unless-stopped

Expand Down Expand Up @@ -102,10 +102,10 @@ services:
context: .
dockerfile: Dockerfile
args:
UNITY_VERSION: ${UNITY_VERSION:-6000.3.8f1}
UNITY_VERSION: ${UNITY_VERSION:-6000.3.20f1}
UNITY_MODULE: linux-il2cpp
IMAGE_VERSION: ${IMAGE_VERSION:-3}
image: unity-ci-linux-il2cpp:${UNITY_VERSION:-6000.3.8f1}
image: unity-ci-linux-il2cpp:${UNITY_VERSION:-6000.3.20f1}
container_name: unity-ci-linux-il2cpp
restart: unless-stopped

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 6dc4cf4496348884d8ee27743ae38562
m_Address: HorrorZombie
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: b1611d7d32b3037468188d2f5c8ff025
m_Address: HorrorEnemy
m_ReadOnly: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ MonoBehaviour:
m_GroupName: HorrorScenes
m_GUID: 1e0ce9587ad9ff24b901b56d8bb3da6f
m_SerializeEntries:
- m_GUID: 094364c160b114e4dba809befc69171a
m_Address: HorrorGameOverDialog
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 25545f51a6c8d10439ed6f34f00651b3
m_Address: HorrorEquipmentShortcutDialog
m_ReadOnly: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,33 @@ public class HorrorAmmoViewTests

[Test]
public void ResolveDisplayMode_NoWeapon_IsNone()
=> Assert.That(HorrorAmmoView.ResolveDisplayMode(false, 4), Is.EqualTo(HorrorAmmoView.DisplayMode.None));
=> Assert.That(HorrorAmmoView.ResolveViewMode(false, 4), Is.EqualTo(HorrorAmmoViewMode.Hidden));

[Test]
public void ResolveDisplayMode_WeaponWithAmmoItem_IsMagazineAndReserve()
=> Assert.That(HorrorAmmoView.ResolveDisplayMode(true, 4), Is.EqualTo(HorrorAmmoView.DisplayMode.MagazineAndReserve));
=> Assert.That(HorrorAmmoView.ResolveViewMode(true, 4), Is.EqualTo(HorrorAmmoViewMode.MagazineAndReserve));

[Test]
public void ResolveDisplayMode_WeaponWithoutAmmoItem_IsCountOnly()
=> Assert.That(HorrorAmmoView.ResolveDisplayMode(true, 0), Is.EqualTo(HorrorAmmoView.DisplayMode.CountOnly));
=> Assert.That(HorrorAmmoView.ResolveViewMode(true, 0), Is.EqualTo(HorrorAmmoViewMode.CountOnly));

// 目標アルファ:None は常に 0。表示維持中または保持時間内は 1、保持時間超過で 0。

[Test]
public void CalculateTargetAlpha_None_IsZeroEvenIfKeepVisible()
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoView.DisplayMode.None, true, 0f, 2f), Is.EqualTo(0f));
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoViewMode.Hidden, true, 0f, 2f), Is.EqualTo(0f));

[Test]
public void CalculateTargetAlpha_KeepVisible_IsOne()
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoView.DisplayMode.CountOnly, true, 999f, 2f), Is.EqualTo(1f));
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoViewMode.CountOnly, true, 999f, 2f), Is.EqualTo(1f));

[Test]
public void CalculateTargetAlpha_WithinHoldDuration_IsOne()
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoView.DisplayMode.CountOnly, false, 1f, 2f), Is.EqualTo(1f));
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoViewMode.CountOnly, false, 1f, 2f), Is.EqualTo(1f));

[Test]
public void CalculateTargetAlpha_PastHoldDuration_IsZero()
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoView.DisplayMode.CountOnly, false, 2f, 2f), Is.EqualTo(0f));
=> Assert.That(HorrorAmmoView.CalculateTargetAlpha(HorrorAmmoViewMode.CountOnly, false, 2f, 2f), Is.EqualTo(0f));

// 弾倉側文字色:MagazineAndReserve かつ満タンのみ強調色。それ以外(CountOnly を含む)は通常色。

Expand All @@ -47,19 +47,19 @@ public void CalculateTargetAlpha_PastHoldDuration_IsZero()

[Test]
public void CalculateMagazineColor_FullMagazine_IsFull()
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoView.DisplayMode.MagazineAndReserve, 10, 10, Full, Normal), Is.EqualTo(Full));
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoViewMode.MagazineAndReserve, 10, 10, Full, Normal), Is.EqualTo(Full));

[Test]
public void CalculateMagazineColor_NotFullMagazine_IsNormal()
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoView.DisplayMode.MagazineAndReserve, 5, 10, Full, Normal), Is.EqualTo(Normal));
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoViewMode.MagazineAndReserve, 5, 10, Full, Normal), Is.EqualTo(Normal));

[Test]
public void CalculateMagazineColor_ZeroMagazineSize_IsNormal()
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoView.DisplayMode.MagazineAndReserve, 0, 0, Full, Normal), Is.EqualTo(Normal));
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoViewMode.MagazineAndReserve, 0, 0, Full, Normal), Is.EqualTo(Normal));

[Test]
public void CalculateMagazineColor_CountOnly_IsAlwaysNormal()
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoView.DisplayMode.CountOnly, 10, 10, Full, Normal), Is.EqualTo(Normal));
=> Assert.That(HorrorAmmoView.CalculateMagazineColor(HorrorAmmoViewMode.CountOnly, 10, 10, Full, Normal), Is.EqualTo(Normal));

// 予備側文字色:0 以下は警告色、正数は通常色。

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Game.Horror.Player;
using NUnit.Framework;
using UnityEngine;

namespace Game.Tests.MVC.Horror
{
[TestFixture]
public class HorrorDamageViewTests
{
// スクリーン位置算出:WorldToScreenPoint の結果と上昇オフセットから表示位置を導く。
// screenPoint.z < 0(カメラ背後)のみ非表示(false)とする。

[Test]
public void TryCalculateScreenPosition_BehindCamera_ReturnsFalse()
=> Assert.That(HorrorDamageView.TryCalculateScreenPosition(new Vector3(100f, 200f, -0.1f), 0f, out _), Is.False);

[Test]
public void TryCalculateScreenPosition_AtZeroDepth_ReturnsTrue()
=> Assert.That(HorrorDamageView.TryCalculateScreenPosition(new Vector3(100f, 200f, 0f), 0f, out _), Is.True);

[Test]
public void TryCalculateScreenPosition_WithRiseOffset_AddsToY()
{
HorrorDamageView.TryCalculateScreenPosition(new Vector3(100f, 200f, 10f), 60f, out var position);
Assert.That(position.y, Is.EqualTo(260f));
}

[Test]
public void TryCalculateScreenPosition_ZeroRiseOffset_KeepsXAndY()
{
HorrorDamageView.TryCalculateScreenPosition(new Vector3(100f, 200f, 10f), 0f, out var position);
Assert.That(position.x, Is.EqualTo(100f));
Assert.That(position.y, Is.EqualTo(200f));
}

[Test]
public void TryCalculateScreenPosition_AlwaysReturnsZeroDepth()
{
HorrorDamageView.TryCalculateScreenPosition(new Vector3(100f, 200f, 10f), 60f, out var position);
Assert.That(position.z, Is.EqualTo(0f));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Game.Horror.Enemy;
using NUnit.Framework;
using UnityEngine;

namespace Game.Tests.MVC.Horror
{
[TestFixture]
public class HorrorEnemyControllerTests
{
// アニメーター Speed 平滑化:指数補間(1-exp(-response・dt))で target へ追従する。
// 目標一致・dt=0 は不動、途中値はオーバーシュートなし、反復適用で収束し、dt に依らず結果が一致する。

[Test]
public void CalculateSmoothedAnimSpeed_TargetReached_ReturnsTarget()
=> Assert.That(HorrorEnemyController.CalculateSmoothedAnimSpeed(0.5f, 0.5f, 8f, 1f / 60f), Is.EqualTo(0.5f).Within(1e-4f));

[Test]
public void CalculateSmoothedAnimSpeed_ZeroDeltaTime_ReturnsCurrent()
=> Assert.That(HorrorEnemyController.CalculateSmoothedAnimSpeed(0.3f, 0.8f, 8f, 0f), Is.EqualTo(0.3f).Within(1e-4f));

[Test]
public void CalculateSmoothedAnimSpeed_RisingStep_StaysWithinRange()
{
var result = HorrorEnemyController.CalculateSmoothedAnimSpeed(0f, 0.5f, 8f, 1f / 60f);
Assert.That(result, Is.InRange(0f, 0.5f));
}

[Test]
public void CalculateSmoothedAnimSpeed_RepeatedApplication_ConvergesToTarget()
{
var current = 0f;
const float target = 0.5f;
for (var i = 0; i < 60; i++)
current = HorrorEnemyController.CalculateSmoothedAnimSpeed(current, target, 8f, 1f / 60f);

Assert.That(target - current, Is.LessThan(0.01f));
}

[Test]
public void CalculateSmoothedAnimSpeed_FrameRateIndependent_MatchesAcrossStepSizes()
{
var oneStep = HorrorEnemyController.CalculateSmoothedAnimSpeed(0f, 1f, 8f, 0.2f);
var twoStep = HorrorEnemyController.CalculateSmoothedAnimSpeed(0f, 1f, 8f, 0.1f);
twoStep = HorrorEnemyController.CalculateSmoothedAnimSpeed(twoStep, 1f, 8f, 0.1f);

Assert.That(twoStep, Is.EqualTo(oneStep).Within(1e-4f));
}

[Test]
public void CalculateSmoothedAnimSpeed_Decaying_StaysWithinRangeAndConverges()
{
var result = HorrorEnemyController.CalculateSmoothedAnimSpeed(0.5f, 0f, 8f, 1f / 60f);
Assert.That(result, Is.InRange(0f, 0.5f));

var current = 0.5f;
const float target = 0f;
for (var i = 0; i < 60; i++)
current = HorrorEnemyController.CalculateSmoothedAnimSpeed(current, target, 8f, 1f / 60f);

Assert.That(current - target, Is.LessThan(0.01f));
}

// 視認喪失中の追跡先:LKP(最終目撃位置)を優先し、未視認(zero センチネル)なら聴覚位置へフォールバック。

[Test]
public void ResolveLostSightDestination_WithLastKnown_ReturnsLastKnown()
=> Assert.That(
HorrorEnemyController.ResolveLostSightDestination(new Vector3(5f, 0f, 5f), new Vector3(9f, 0f, 9f)),
Is.EqualTo(new Vector3(5f, 0f, 5f)));

[Test]
public void ResolveLostSightDestination_ZeroLastKnown_ReturnsLastHeard()
=> Assert.That(
HorrorEnemyController.ResolveLostSightDestination(Vector3.zero, new Vector3(9f, 0f, 9f)),
Is.EqualTo(new Vector3(9f, 0f, 9f)));
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Game.Horror.Enemy;
using NUnit.Framework;
using UnityEngine;

namespace Game.Tests.MVC.Horror
{
[TestFixture]
public class HorrorEnemyPerceptionTests
{
// 視野錐判定:Dot と cos 閾値の比較(>=)。正面・視野縁の等号境界・視野外・真後ろを検証する。
// 境界値は独立オラクルとして Mathf.Cos/Sin(angle * Deg2Rad) から toTarget を構築し、
// Dot(forward, toTarget) が cosHalfAngle とビット一致するようにして境界の >= を確実に検証する。

[Test]
public void IsInSightCone_DirectlyAhead_ReturnsTrue()
{
var forward = Vector3.forward;
var cosHalfAngle = Mathf.Cos(60f * Mathf.Deg2Rad);
Assert.That(HorrorEnemyPerception.IsInSightCone(forward, forward, cosHalfAngle), Is.True);
}

[Test]
public void IsInSightCone_AtConeEdgeBoundary_ReturnsTrue()
{
const float halfAngle = 45f;
var cosHalfAngle = Mathf.Cos(halfAngle * Mathf.Deg2Rad);
var sinHalfAngle = Mathf.Sin(halfAngle * Mathf.Deg2Rad);
var forward = Vector3.forward;

// forward=(0,0,1) との Dot が cosHalfAngle とビット一致するよう構築した境界方向
var toTargetAtEdge = new Vector3(sinHalfAngle, 0f, cosHalfAngle);

Assert.That(HorrorEnemyPerception.IsInSightCone(forward, toTargetAtEdge, cosHalfAngle), Is.True);
}

[Test]
public void IsInSightCone_OutsideCone_ReturnsFalse()
{
var forward = Vector3.forward;
var toTargetSide = Vector3.right; // forward との Dot = 0(真横)
var cosHalfAngle = Mathf.Cos(45f * Mathf.Deg2Rad); // 約 0.707 > 0
Assert.That(HorrorEnemyPerception.IsInSightCone(forward, toTargetSide, cosHalfAngle), Is.False);
}

[Test]
public void IsInSightCone_DirectlyBehind_ReturnsFalse()
{
var forward = Vector3.forward;
var toTargetBehind = Vector3.back; // Dot = -1
var cosHalfAngle = Mathf.Cos(60f * Mathf.Deg2Rad);
Assert.That(HorrorEnemyPerception.IsInSightCone(forward, toTargetBehind, cosHalfAngle), Is.False);
}

// 警戒度ゲージ更新:視認中は近いほど速く充填(distance01=0 で 2x、=1 で 1x)、非視認は減衰、
// 0〜1 にクランプ、dt=0 では不動。

[Test]
public void UpdateAwareness_HasSightAtClosestDistance_FillsAtDoubleRate()
{
var result = HorrorEnemyPerception.UpdateAwareness(0f, true, 0f, 0.1f, 0.05f, 1f);
Assert.That(result, Is.EqualTo(0.2f).Within(1e-4f));
}

[Test]
public void UpdateAwareness_HasSightAtFarthestDistance_FillsAtBaseRate()
{
var result = HorrorEnemyPerception.UpdateAwareness(0f, true, 1f, 0.1f, 0.05f, 1f);
Assert.That(result, Is.EqualTo(0.1f).Within(1e-4f));
}

[Test]
public void UpdateAwareness_NoSight_Decays()
{
var result = HorrorEnemyPerception.UpdateAwareness(0.5f, false, 0f, 0.1f, 0.2f, 1f);
Assert.That(result, Is.EqualTo(0.3f).Within(1e-4f));
}

[Test]
public void UpdateAwareness_ClampsToUnitRange()
{
var upperClamped = HorrorEnemyPerception.UpdateAwareness(0.95f, true, 0f, 1f, 0f, 1f);
Assert.That(upperClamped, Is.EqualTo(1f));

var lowerClamped = HorrorEnemyPerception.UpdateAwareness(0.05f, false, 0f, 0f, 1f, 1f);
Assert.That(lowerClamped, Is.EqualTo(0f));
}

[Test]
public void UpdateAwareness_ZeroDeltaTime_IsUnchanged()
{
var result = HorrorEnemyPerception.UpdateAwareness(0.5f, true, 0f, 0.1f, 0.05f, 0f);
Assert.That(result, Is.EqualTo(0.5f).Within(1e-4f));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading