Update
This commit is contained in:
8
.idea/.idea.HALLUCINATE/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.HALLUCINATE/.idea/indexLayout.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/.idea.HALLUCINATE/.idea/projectSettingsUpdater.xml
generated
Normal file
8
.idea/.idea.HALLUCINATE/.idea/projectSettingsUpdater.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="singleClickDiffPreview" value="1" />
|
||||
<option name="unhandledExceptionsIgnoreList" value="1" />
|
||||
<option name="vcsConfiguration" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/.idea.HALLUCINATE/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.HALLUCINATE/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
156
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
Normal file
156
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="f9183c68-daf0-43b8-be4c-fad79983f91b" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scove/Optimiization.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scove/Optimiization.unity" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scove/Player Movement.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scove/Player Movement.unity" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scove/Player_Movement_Description.txt" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scove/Player_Movement_Description.txt.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/AutoPlayerStateMachine.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/AutoPlayerStateMachine.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/JobsMovementManager.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/JobsMovementManager.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/MassiveSpawner.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/MassiveSpawner.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/PerformanceHUD.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/PerformanceHUD.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/StressTestSpawner.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Optimization/StressTestSpawner.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/ParkourController.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/ParkourController.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerController.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerController.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/SpineProxy.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/SpineProxy.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Settings/Project Setting/FolderIcons.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Settings/Project Setting/FolderIcons.asset" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="EmbeddingIndexingInfo">
|
||||
<option name="cachedIndexableFilesCount" value="9" />
|
||||
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="McpProjectServerCommands">
|
||||
<commands />
|
||||
<urls />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 4
|
||||
}</component>
|
||||
<component name="ProjectId" id="3BU6ZYP0raS9lWcA2Qy4TxVBVes" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||
"git-widget-placeholder": "master",
|
||||
"junie.onboarding.icon.badge.shown": "true",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"to.speed.mode.migration.done": "true",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RunManager" selected="Attach to Unity Editor.Attach to Unity Editor">
|
||||
<configuration name="Start Unity" type="RunUnityExe" factoryName="Unity Executable">
|
||||
<option name="EXE_PATH" value="C:\Program Files\Unity\Hub\Editor\6000.3.10f1\Editor\Unity.exe" />
|
||||
<option name="PROGRAM_PARAMETERS" value="-projectPath E:\Learning_Progress\Projects\HALLUCINATE -debugCodeOptimization" />
|
||||
<option name="WORKING_DIRECTORY" value="E:\Learning_Progress\Projects\HALLUCINATE" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="ENV_FILE_PATHS" value="" />
|
||||
<option name="REDIRECT_INPUT_PATH" value="" />
|
||||
<option name="MIXED_MODE_DEBUG" value="0" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Unit Tests (batch mode)" type="RunUnityExe" factoryName="Unity Executable">
|
||||
<option name="EXE_PATH" value="C:\Program Files\Unity\Hub\Editor\6000.3.10f1\Editor\Unity.exe" />
|
||||
<option name="PROGRAM_PARAMETERS" value="-runTests -batchmode -projectPath E:\Learning_Progress\Projects\HALLUCINATE -testResults Logs/results.xml -logFile Logs/Editor.log -testPlatform EditMode -debugCodeOptimization" />
|
||||
<option name="WORKING_DIRECTORY" value="E:\Learning_Progress\Projects\HALLUCINATE" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="ENV_FILE_PATHS" value="" />
|
||||
<option name="REDIRECT_INPUT_PATH" value="" />
|
||||
<option name="MIXED_MODE_DEBUG" value="0" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Attach to Unity Editor" type="UNITY_DEBUG_RUN_CONFIGURATION" factoryName="Unity Debug" show_console_on_std_err="false" show_console_on_std_out="false" port="50000" address="localhost" useMixedMode="false">
|
||||
<option name="allowRunningInParallel" value="false" />
|
||||
<option name="listenPortForConnections" value="false" />
|
||||
<option name="pid" />
|
||||
<option name="projectPathOnTarget" />
|
||||
<option name="runtimes">
|
||||
<list />
|
||||
</option>
|
||||
<option name="selectedOptions">
|
||||
<list />
|
||||
</option>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Attach to" type="UnityDevicePlayer" factoryName="UnityAttachToDevicePlayer">
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="f9183c68-daf0-43b8-be4c-fad79983f91b" name="Changes" comment="" />
|
||||
<created>1774531360140</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1774531360140</updated>
|
||||
<workItem from="1774531363039" duration="637000" />
|
||||
<workItem from="1774584797007" duration="56000" />
|
||||
<workItem from="1774584869078" duration="309000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="UnityProjectConfiguration" hasMinimizedUI="true" />
|
||||
<component name="UnityProjectDiscoverer">
|
||||
<option name="hasUnityReference" value="true" />
|
||||
<option name="unityProject" value="true" />
|
||||
<option name="unityProjectFolder" value="true" />
|
||||
</component>
|
||||
<component name="UnityUnitTestConfiguration" currentTestLauncher="Both" />
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<breakpoints>
|
||||
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
|
||||
<properties exception="System.OperationCanceledException" breakIfHandledByOtherCode="false" displayValue="System.OperationCanceledException" />
|
||||
<option name="timeStamp" value="1" />
|
||||
</breakpoint>
|
||||
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
|
||||
<properties exception="System.Threading.Tasks.TaskCanceledException" breakIfHandledByOtherCode="false" displayValue="System.Threading.Tasks.TaskCanceledException" />
|
||||
<option name="timeStamp" value="2" />
|
||||
</breakpoint>
|
||||
<breakpoint enabled="true" type="DotNet_Exception_Breakpoints">
|
||||
<properties exception="System.Threading.ThreadAbortException" breakIfHandledByOtherCode="false" displayValue="System.Threading.ThreadAbortException" />
|
||||
<option name="timeStamp" value="3" />
|
||||
</breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
</project>
|
||||
@@ -411,7 +411,7 @@ MeshRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: c6f1ec2975124834fbfdb5437314d9df, type: 2}
|
||||
- {fileID: 2100000, guid: b0a84576fc378a24cbb3bfc7be45a02e, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
@@ -588,7 +588,7 @@ MeshRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: f78dd419a717d2744a4d18615c4b199c, type: 2}
|
||||
- {fileID: 2100000, guid: e2e2684e969402049b87d7f81417c603, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
|
||||
@@ -642,7 +642,7 @@ MeshRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: f78dd419a717d2744a4d18615c4b199c, type: 2}
|
||||
- {fileID: 2100000, guid: e2e2684e969402049b87d7f81417c603, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
@@ -759,7 +759,7 @@ MeshRenderer:
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 29d8aeef71b97864a9ad6317a4738f26, type: 2}
|
||||
- {fileID: 2100000, guid: d7e691e02b41b9a47b417cc138d6f1bc, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# PROJECT CONTEXT & ARCHITECTURE
|
||||
- Engine: Unity 6.3
|
||||
- Genre: 3D Third-Person Action Game (TPS)
|
||||
- Input: Unity New Input System (using InputReader script)
|
||||
- Pattern: Hierarchical State Machine (HSM) / State Pattern
|
||||
- Coding Rules: Strictly English for all variables, methods, classes, and comments. Use CharacterController for movement. Handle rotation using Quaternion.Slerp.
|
||||
|
||||
# 1. INPUT READER (InputReader.cs)
|
||||
Inherits: MonoBehaviour
|
||||
Properties:
|
||||
- Vector2 MoveInput (from WASD/Left Stick)
|
||||
- bool IsSprintHeld (from Left Shift - continuous hold)
|
||||
Events (Actions):
|
||||
- event Action OnJumpEvent (Space bar pressed)
|
||||
- event Action OnDodgeEvent (Right Mouse Button - RMB pressed)
|
||||
- event Action OnCrouchEvent (C key pressed)
|
||||
|
||||
# 2. ANIMATOR SETUP REQUIREMENTS
|
||||
Parameters:
|
||||
- "Speed" (Float): Grounded movement (0.0 = Idle, 0.5 = Walk, 1.0 = Run).
|
||||
- "IsCrouching" (Bool): Toggle crouch mode.
|
||||
- "CrouchSpeed" (Float): Crouch movement (0.0 = Idle, 0.5 = Sneak, 1.0 = Walk).
|
||||
- Triggers: "Dash", "Jump", "Fall", "AirDash", "Thrust", "Dodge".
|
||||
|
||||
# 3. STATE MACHINE CORE (PlayerStateMachine.cs)
|
||||
Inherits: MonoBehaviour
|
||||
RequireComponents: CharacterController, InputReader, Animator
|
||||
Variables:
|
||||
- float WalkSpeed = 3f, RunSpeed = 6f, DashForce = 10f, SneakSpeed = 1.5f
|
||||
- float JumpForce = 5f, Gravity = -9.81f, ThrustDownwardForce = -20f
|
||||
- float VelocityY (tracks vertical speed)
|
||||
- PlayerBaseState currentState
|
||||
Methods:
|
||||
- SwitchState(PlayerBaseState newState): calls currentState.Exit(), updates state, calls currentState.Enter().
|
||||
- Update(): calls currentState.Tick(Time.deltaTime).
|
||||
- FixedUpdate(): calls currentState.PhysicsTick(Time.fixedDeltaTime).
|
||||
|
||||
# 4. BASE STATE (PlayerBaseState.cs)
|
||||
Abstract class. Constructor takes (PlayerStateMachine stateMachine).
|
||||
Abstract Methods: Enter(), Tick(float deltaTime), PhysicsTick(float fixedDeltaTime), Exit().
|
||||
|
||||
# 5. DETAILED STATE LOGICS
|
||||
|
||||
## PlayerIdleState
|
||||
- Enter: Subscribe to OnJumpEvent, OnDodgeEvent, OnCrouchEvent.
|
||||
- Tick: SmoothDamp "Speed" to 0.0. If MoveInput != Vector2.zero -> SwitchState(PlayerMoveState).
|
||||
- Exit: Unsubscribe events.
|
||||
|
||||
## PlayerMoveState
|
||||
- Enter: Subscribe to events (Jump, Dodge, Crouch).
|
||||
- Tick:
|
||||
- If MoveInput == Vector2.zero -> SwitchState(PlayerIdleState).
|
||||
- If IsSprintHeld == true -> SwitchState(PlayerDashState).
|
||||
- Move using CharacterController (MoveInput * WalkSpeed).
|
||||
- Slerp rotation towards MoveInput direction.
|
||||
- SmoothDamp "Speed" to 0.5.
|
||||
- Exit: Unsubscribe events.
|
||||
|
||||
## PlayerDashState
|
||||
- Variables: timer = 0.25s, dashDirection (Vector3).
|
||||
- Enter: Set dashDirection to MoveInput (or transform.forward if 0). Snap rotation to dashDirection. SetTrigger("Dash").
|
||||
- Tick:
|
||||
- Move at DashForce along dashDirection (no gravity applied).
|
||||
- timer -= deltaTime.
|
||||
- If timer <= 0:
|
||||
- If IsSprintHeld AND MoveInput != 0 -> SwitchState(PlayerRunState).
|
||||
- If MoveInput != 0 -> SwitchState(PlayerMoveState).
|
||||
- Else -> SwitchState(PlayerIdleState).
|
||||
|
||||
## PlayerRunState
|
||||
- Enter: Subscribe to events (Jump, Dodge, Crouch).
|
||||
- Tick:
|
||||
- If MoveInput == 0 -> SwitchState(PlayerIdleState).
|
||||
- If IsSprintHeld == false -> SwitchState(PlayerMoveState).
|
||||
- Move using CharacterController (MoveInput * RunSpeed). Slerp rotation.
|
||||
- SmoothDamp "Speed" to 1.0.
|
||||
- Exit: Unsubscribe events.
|
||||
|
||||
## PlayerJumpState
|
||||
- Enter: SetTrigger("Jump"). VelocityY = JumpForce.
|
||||
- Tick:
|
||||
- Apply Gravity (VelocityY += Gravity * deltaTime).
|
||||
- Apply horizontal Air Control (MoveInput * WalkSpeed).
|
||||
- Move using CharacterController (Horizontal + Vertical).
|
||||
- If VelocityY <= 0 -> SwitchState(PlayerFallState).
|
||||
|
||||
## PlayerFallState
|
||||
- Enter: SetTrigger("Fall"). Subscribe to OnDodgeEvent (maps to Thrust here).
|
||||
- Tick:
|
||||
- Apply Gravity. Apply horizontal Air Control. Move via Controller.
|
||||
- If IsSprintHeld -> SwitchState(PlayerAirDashState).
|
||||
- If isGrounded -> Set VelocityY = -2f. SwitchState(Idle or Move based on input).
|
||||
- Thrust Event Trigger: SwitchState(PlayerThrustState).
|
||||
- Exit: Unsubscribe OnDodgeEvent.
|
||||
|
||||
## PlayerAirDashState
|
||||
- Variables: timer = 0.2s, dashDir.
|
||||
- Enter: SetTrigger("AirDash"). VelocityY = 0f. Set dashDir based on MoveInput.
|
||||
- Tick:
|
||||
- Move horizontally at DashForce (VelocityY stays 0).
|
||||
- timer -= deltaTime. If timer <= 0 -> SwitchState(PlayerFallState).
|
||||
|
||||
## PlayerThrustState
|
||||
- Enter: SetTrigger("Thrust"). VelocityY = ThrustDownwardForce.
|
||||
- Tick:
|
||||
- VelocityY += (Gravity * 2) * deltaTime. Move purely downwards (no horizontal).
|
||||
- If isGrounded -> Set VelocityY = -2f. SwitchState(PlayerIdleState).
|
||||
|
||||
## PlayerCrouchState
|
||||
- Enter: SetBool("IsCrouching", true). Subscribe to OnCrouchEvent (Toggle), OnDodgeEvent.
|
||||
- Tick:
|
||||
- If MoveInput == 0: "CrouchSpeed" = 0.0.
|
||||
- If MoveInput != 0 AND IsSprintHeld: Move at SneakSpeed. "CrouchSpeed" = 0.5.
|
||||
- If MoveInput != 0 AND !IsSprintHeld: Move at WalkSpeed. "CrouchSpeed" = 1.0.
|
||||
- Apply Movement and Slerp rotation.
|
||||
- Toggle Event Trigger (C key): SwitchState(Idle or Move).
|
||||
- Dodge Event Trigger (LMB): SwitchState(PlayerDodgeState).
|
||||
- Exit: SetBool("IsCrouching", false). Unsubscribe events.
|
||||
|
||||
## PlayerDodgeState
|
||||
- Variables: timer = 0.4s, dodgeDir.
|
||||
- Enter: SetTrigger("Dodge"). Set dodgeDir based on MoveInput (Left/Right/Back/Forward). Snap rotation.
|
||||
- Tick:
|
||||
- Move at (DashForce * 0.8) along dodgeDir.
|
||||
- timer -= deltaTime.
|
||||
- If timer <= 0 -> SwitchState(Idle or Move based on MoveInput).
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0237005d5b554958bc3a87b1cec34c9e
|
||||
timeCreated: 1773378307
|
||||
@@ -1,49 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
/// <summary>
|
||||
/// A version of PlayerStateMachine that simulates constant forward or backward input.
|
||||
/// </summary>
|
||||
public class AutoPlayerStateMachine : PlayerStateMachine
|
||||
{
|
||||
[Header("Auto Pilot Settings")]
|
||||
public bool alwaysMoveForward = true;
|
||||
public bool alwaysRun = true;
|
||||
public bool isRed = false; // New property to differentiate movement direction
|
||||
|
||||
private class FakeInputReader : InputReader
|
||||
{
|
||||
public Vector2 ForcedMove { get; set; }
|
||||
public bool ForcedSprint { get; set; }
|
||||
|
||||
public override Vector2 MoveInput => ForcedMove;
|
||||
public override bool IsSprintHeld => ForcedSprint;
|
||||
}
|
||||
|
||||
private FakeInputReader fakeInput;
|
||||
|
||||
public override InputReader Input => fakeInput;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
fakeInput = gameObject.AddComponent<FakeInputReader>();
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
if (fakeInput != null)
|
||||
{
|
||||
// Logic updated: isRed moves backward (Vector2.down), others move forward (Vector2.up)
|
||||
fakeInput.ForcedMove = (isRed)
|
||||
? (alwaysMoveForward ? Vector2.down : Vector2.zero)
|
||||
: (alwaysMoveForward ? Vector2.up : Vector2.zero);
|
||||
|
||||
fakeInput.ForcedSprint = alwaysRun;
|
||||
}
|
||||
|
||||
base.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbe8532b2e328a249bf61ae957c92486
|
||||
@@ -1,129 +0,0 @@
|
||||
using UnityEngine;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using UnityEngine.Jobs;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Elbyss.Optimization
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages 10,000+ objects using C# Job System and Burst Compiler.
|
||||
/// This avoids the overhead of 10,000 individual Update() calls.
|
||||
/// </summary>
|
||||
public class JobsMovementManager : MonoBehaviour
|
||||
{
|
||||
[Header("Spawn Settings")]
|
||||
public GameObject prefab;
|
||||
public int objectCount = 10000;
|
||||
public float spacing = 1.5f;
|
||||
|
||||
[Header("Movement Settings")]
|
||||
public float speed = 5f;
|
||||
|
||||
private TransformAccessArray transformAccessArray;
|
||||
private NativeArray<Vector3> directions;
|
||||
private bool isInitialized = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Optional: Start automatically or via Context Menu
|
||||
// Setup(objectCount);
|
||||
}
|
||||
|
||||
[ContextMenu("Setup 10k Objects")]
|
||||
public void InitialSetup()
|
||||
{
|
||||
Setup(objectCount);
|
||||
}
|
||||
|
||||
public void Setup(int count)
|
||||
{
|
||||
if (isInitialized) Cleanup();
|
||||
|
||||
objectCount = count;
|
||||
Transform[] transforms = new Transform[objectCount];
|
||||
directions = new NativeArray<Vector3>(objectCount, Allocator.Persistent);
|
||||
|
||||
int rowSize = Mathf.CeilToInt(Mathf.Sqrt(objectCount));
|
||||
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
float x = (i % rowSize) * spacing;
|
||||
float z = (i / rowSize) * spacing;
|
||||
Vector3 pos = transform.position + new Vector3(x, 0, z);
|
||||
|
||||
GameObject go = Instantiate(prefab, pos, Quaternion.identity, this.transform);
|
||||
transforms[i] = go.transform;
|
||||
|
||||
// Set alternating directions
|
||||
directions[i] = (i % 2 == 0) ? Vector3.forward : Vector3.back;
|
||||
|
||||
// CRITICAL OPTIMIZATION: Disable components that are too heavy for 10k objects
|
||||
if (go.TryGetComponent<Animator>(out var anim)) anim.enabled = false;
|
||||
if (go.TryGetComponent<CharacterController>(out var cc)) cc.enabled = false;
|
||||
|
||||
// Disable all other custom scripts
|
||||
MonoBehaviour[] scripts = go.GetComponents<MonoBehaviour>();
|
||||
foreach (var s in scripts)
|
||||
{
|
||||
if (s != this) s.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
transformAccessArray = new TransformAccessArray(transforms);
|
||||
isInitialized = true;
|
||||
Debug.Log($"Initialized {objectCount} objects with Job System.");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
// Create the movement job
|
||||
var job = new MovementJob
|
||||
{
|
||||
DeltaTime = Time.deltaTime,
|
||||
Speed = speed,
|
||||
Directions = directions
|
||||
};
|
||||
|
||||
// Schedule the job to run in parallel on all available CPU cores
|
||||
// transformAccessArray allows the job to modify Transform data directly
|
||||
JobHandle handle = job.Schedule(transformAccessArray);
|
||||
|
||||
// This ensures the job is finished before the frame ends
|
||||
// In a real scenario, you might want to call Complete() in LateUpdate or next frame
|
||||
// but for simple movement, scheduling and completing in Update is fine.
|
||||
handle.Complete();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
if (isInitialized)
|
||||
{
|
||||
if (transformAccessArray.isCreated) transformAccessArray.Dispose();
|
||||
if (directions.IsCreated) directions.Dispose();
|
||||
isInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile] // This attribute tells the Burst compiler to optimize this job into machine code
|
||||
struct MovementJob : IJobParallelForTransform
|
||||
{
|
||||
public float DeltaTime;
|
||||
public float Speed;
|
||||
[ReadOnly] public NativeArray<Vector3> Directions;
|
||||
|
||||
public void Execute(int index, TransformAccess transform)
|
||||
{
|
||||
// Directly modify the transform position in parallel
|
||||
transform.position += Directions[index] * Speed * DeltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41899df442467714dbee462ae451773a
|
||||
@@ -1,153 +0,0 @@
|
||||
// using GPUInstancerPro;
|
||||
// using Unity.Burst;
|
||||
// using Unity.Collections;
|
||||
// using Unity.Jobs;
|
||||
// using Unity.Mathematics;
|
||||
// using UnityEngine;
|
||||
//
|
||||
// namespace Elbyss.Optimization
|
||||
// {
|
||||
// public class MassiveSpawner : MonoBehaviour
|
||||
// {
|
||||
// [Header("Spawn Settings")]
|
||||
// public GameObject prefab;
|
||||
// public GPUIProfile profile;
|
||||
// public int instanceCount = 100000;
|
||||
// public float spacing = 1.5f;
|
||||
//
|
||||
// [Header("Update Settings")]
|
||||
// public bool runUpdate = true;
|
||||
// public float movementSpeed = 1.0f;
|
||||
// public float amplitude = 2.0f;
|
||||
//
|
||||
// private int _rendererKey;
|
||||
// private NativeArray<Matrix4x4> _matrices;
|
||||
// private JobHandle _jobHandle;
|
||||
// private bool _isInitialized;
|
||||
//
|
||||
// private void OnEnable()
|
||||
// {
|
||||
// Initialize();
|
||||
// }
|
||||
//
|
||||
// private void OnDisable()
|
||||
// {
|
||||
// Dispose();
|
||||
// }
|
||||
//
|
||||
// private void OnValidate()
|
||||
// {
|
||||
// if (Application.isPlaying && _isInitialized)
|
||||
// {
|
||||
// // Re-initialize if count changes during play (optional, but good for testing)
|
||||
// Initialize();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void Initialize()
|
||||
// {
|
||||
// Dispose();
|
||||
// if (prefab == null) return;
|
||||
//
|
||||
// if (GPUICoreAPI.RegisterRenderer(this, prefab, profile, out _rendererKey))
|
||||
// {
|
||||
// _matrices = new NativeArray<Matrix4x4>(instanceCount, Allocator.Persistent);
|
||||
//
|
||||
// // Initial generation
|
||||
// GenerateMatrices(0);
|
||||
// _jobHandle.Complete();
|
||||
// GPUICoreAPI.SetTransformBufferData(_rendererKey, _matrices);
|
||||
//
|
||||
// _isInitialized = true;
|
||||
// Debug.Log($"[MassiveSpawner] Registered {instanceCount} instances with key {_rendererKey}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogError("[MassiveSpawner] Failed to register renderer!");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void Update()
|
||||
// {
|
||||
// if (!_isInitialized || _rendererKey == 0) return;
|
||||
//
|
||||
// if (runUpdate)
|
||||
// {
|
||||
// // Complete previous frame's work if any
|
||||
// _jobHandle.Complete();
|
||||
//
|
||||
// // Apply updated matrices to GPUI
|
||||
// GPUICoreAPI.SetTransformBufferData(_rendererKey, _matrices);
|
||||
//
|
||||
// // Schedule next frame's work
|
||||
// GenerateMatrices(Time.time);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void GenerateMatrices(float time)
|
||||
// {
|
||||
// int side = Mathf.CeilToInt(Mathf.Sqrt(instanceCount));
|
||||
//
|
||||
// var job = new MatrixUpdateJob
|
||||
// {
|
||||
// matrices = _matrices,
|
||||
// side = side,
|
||||
// spacing = spacing,
|
||||
// time = time,
|
||||
// speed = movementSpeed,
|
||||
// amplitude = amplitude,
|
||||
// origin = transform.position
|
||||
// };
|
||||
//
|
||||
// _jobHandle = job.Schedule(instanceCount, 64);
|
||||
// }
|
||||
//
|
||||
// public void Dispose()
|
||||
// {
|
||||
// _jobHandle.Complete();
|
||||
// if (_rendererKey != 0)
|
||||
// {
|
||||
// GPUICoreAPI.DisposeRenderer(_rendererKey);
|
||||
// _rendererKey = 0;
|
||||
// }
|
||||
//
|
||||
// if (_matrices.IsCreated)
|
||||
// {
|
||||
// _matrices.Dispose();
|
||||
// }
|
||||
// _isInitialized = false;
|
||||
// }
|
||||
//
|
||||
// [BurstCompile]
|
||||
// struct MatrixUpdateJob : IJobParallelFor
|
||||
// {
|
||||
// public NativeArray<Matrix4x4> matrices;
|
||||
// public int side;
|
||||
// public float spacing;
|
||||
// public float time;
|
||||
// public float speed;
|
||||
// public float amplitude;
|
||||
// public Vector3 origin;
|
||||
//
|
||||
// public void Execute(int index)
|
||||
// {
|
||||
// int x = index % side;
|
||||
// int z = index / side;
|
||||
//
|
||||
// float xPos = x * spacing;
|
||||
// float zPos = z * spacing;
|
||||
//
|
||||
// // Add some animation to prove it's updating
|
||||
// float yPos = math.sin(time * speed + (xPos + zPos) * 0.1f) * amplitude;
|
||||
//
|
||||
// Vector3 pos = origin + new Vector3(xPos, yPos, zPos);
|
||||
//
|
||||
// // Simple rotation based on time
|
||||
// float angle = (time * speed * 10f + index) % 360f;
|
||||
// Quaternion rot = Quaternion.Euler(0, angle, 0);
|
||||
//
|
||||
// matrices[index] = Matrix4x4.TRS(pos, rot, Vector3.one);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50831f537cbccac4c9bf4067b6b158c7
|
||||
@@ -1,34 +0,0 @@
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
|
||||
namespace Elbyss.Optimization
|
||||
{
|
||||
public class PerformanceHUD : MonoBehaviour
|
||||
{
|
||||
private float deltaTime = 0.0f;
|
||||
private string displayFormat = "{0:0.0} ms ({1:0.} fps)";
|
||||
|
||||
private void Update()
|
||||
{
|
||||
deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
int w = Screen.width, h = Screen.height;
|
||||
|
||||
GUIStyle style = new GUIStyle();
|
||||
|
||||
Rect rect = new Rect(10, 10, w, h * 2 / 100);
|
||||
style.alignment = TextAnchor.UpperLeft;
|
||||
style.fontSize = h * 2 / 50;
|
||||
style.normal.textColor = new Color(0.0f, 1.0f, 0.5f, 1.0f);
|
||||
|
||||
float msec = deltaTime * 1000.0f;
|
||||
float fps = 1.0f / deltaTime;
|
||||
string text = string.Format(displayFormat, msec, fps);
|
||||
|
||||
GUI.Label(rect, text, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c9a374a3ab089d41a6784b1ffad3b6f
|
||||
@@ -1,85 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using OnlyScove.Scripts;
|
||||
|
||||
namespace Elbyss.Optimization
|
||||
{
|
||||
public class StressTestSpawner : MonoBehaviour
|
||||
{
|
||||
[Header("Spawn Settings")]
|
||||
public GameObject prefabToSpawn;
|
||||
public int spawnLimit = 1000;
|
||||
public int spawnsPerFrame = 10;
|
||||
public float spacing = 2.0f;
|
||||
|
||||
[Header("Testing Mode")]
|
||||
public bool useAutoStateMachine = true;
|
||||
|
||||
[Header("Optimization Options")]
|
||||
public bool stripHeavyComponents = false;
|
||||
|
||||
private List<GameObject> spawnedObjects = new List<GameObject>();
|
||||
private int currentSpawnCount = 0;
|
||||
private bool isSpawning = false;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (isSpawning && currentSpawnCount < spawnLimit)
|
||||
{
|
||||
for (int i = 0; i < spawnsPerFrame && currentSpawnCount < spawnLimit; i++)
|
||||
{
|
||||
SpawnObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Start Stress Test")]
|
||||
public void StartStressTest() => isSpawning = true;
|
||||
|
||||
[ContextMenu("Clear All")]
|
||||
public void ClearAll()
|
||||
{
|
||||
foreach (var obj in spawnedObjects) if (obj != null) Destroy(obj);
|
||||
spawnedObjects.Clear();
|
||||
currentSpawnCount = 0;
|
||||
isSpawning = false;
|
||||
}
|
||||
|
||||
private void SpawnObject()
|
||||
{
|
||||
if (prefabToSpawn == null) return;
|
||||
|
||||
int rowSize = Mathf.CeilToInt(Mathf.Sqrt(spawnLimit));
|
||||
float x = (currentSpawnCount % rowSize) * spacing;
|
||||
float z = (currentSpawnCount / rowSize) * spacing;
|
||||
Vector3 spawnPos = transform.position + new Vector3(x, 0, z);
|
||||
|
||||
GameObject newObj = Instantiate(prefabToSpawn, spawnPos, transform.rotation);
|
||||
|
||||
if (useAutoStateMachine)
|
||||
{
|
||||
var realInput = newObj.GetComponent<InputReader>();
|
||||
if (realInput != null) realInput.enabled = false;
|
||||
|
||||
var originalSM = newObj.GetComponent<PlayerStateMachine>();
|
||||
if (originalSM != null)
|
||||
{
|
||||
DestroyImmediate(originalSM);
|
||||
var autoSM = newObj.AddComponent<AutoPlayerStateMachine>();
|
||||
autoSM.alwaysMoveForward = true;
|
||||
autoSM.alwaysRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (stripHeavyComponents)
|
||||
{
|
||||
if (newObj.TryGetComponent<Animator>(out var anim)) anim.enabled = false;
|
||||
if (newObj.TryGetComponent<CharacterController>(out var cc)) cc.enabled = false;
|
||||
if (newObj.TryGetComponent<PlayerStateMachine>(out var sm)) sm.enabled = false;
|
||||
}
|
||||
|
||||
spawnedObjects.Add(newObj);
|
||||
currentSpawnCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a7c5ef310b7f354685dc6706be2d530
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
public class ParkourController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private InputReader inputReader;
|
||||
EnvironmentScanner environmentScanner;
|
||||
Animator animator;
|
||||
PlayerController playerController;
|
||||
|
||||
bool inAction;
|
||||
private void Awake()
|
||||
{
|
||||
inputReader = GetComponent<InputReader>();
|
||||
environmentScanner = GetComponent<EnvironmentScanner>();
|
||||
animator = GetComponent<Animator>();
|
||||
playerController = GetComponent<PlayerController>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
inputReader.OnJumpEvent += HandleParkour;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
inputReader.OnJumpEvent -= HandleParkour;
|
||||
}
|
||||
|
||||
private void HandleParkour()
|
||||
{
|
||||
var hitData = environmentScanner.ObstacleCheck();
|
||||
|
||||
if (hitData.forwardHitFound)
|
||||
{
|
||||
StartCoroutine(DoParkourAction());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator DoParkourAction()
|
||||
{
|
||||
inAction = true;
|
||||
playerController.SetControl(false);
|
||||
|
||||
animator.CrossFade("Step Up", 0.1f);
|
||||
yield return null;
|
||||
|
||||
var animationState = animator.GetNextAnimatorStateInfo(0);
|
||||
|
||||
yield return new WaitForSeconds(animationState.length);
|
||||
|
||||
playerController.SetControl(true);
|
||||
inAction = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0407ea3fbe445ac43b4f1ca3077ce283
|
||||
@@ -1,134 +0,0 @@
|
||||
using System;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
public class PlayerController : MonoBehaviour
|
||||
{
|
||||
private static readonly int MoveAmount = Animator.StringToHash("moveAmount");
|
||||
|
||||
[SerializeField] private InputReader inputReader;
|
||||
[SerializeField] private float rotationSpeed = 500f;
|
||||
[SerializeField] private float moveSpeed = 10f;
|
||||
[SerializeField] private float jumpHeight = 2f;
|
||||
[SerializeField] private float animationDamping = 0.2f;
|
||||
[SerializeField] private float groundCheckRadius = 0.2f;
|
||||
[SerializeField] private Vector3 groundCheckOffset;
|
||||
[SerializeField] private LayerMask groundMask;
|
||||
|
||||
CameraController cameraController;
|
||||
Animator animator;
|
||||
private CharacterController characterController;
|
||||
|
||||
Quaternion targetRotation;
|
||||
private float horizontal;
|
||||
private float vertical;
|
||||
bool isGrounded;
|
||||
private bool wasGrounded;
|
||||
private bool hasControl = true;
|
||||
private float ySpeed;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Camera.main != null) cameraController = Camera.main.GetComponent<CameraController>();
|
||||
animator = GetComponent<Animator>();
|
||||
characterController = GetComponent<CharacterController>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
inputReader.OnJumpEvent += HandleJump;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
inputReader.OnJumpEvent -= HandleJump;
|
||||
}
|
||||
|
||||
private void HandleJump()
|
||||
{
|
||||
if (isGrounded && hasControl)
|
||||
{
|
||||
// Công thức tính vận tốc nhảy: v = sqrt(h * -2 * g)
|
||||
ySpeed = Mathf.Sqrt(jumpHeight * -2f * Physics.gravity.y);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
horizontal = inputReader.MoveInput.x;
|
||||
vertical = inputReader.MoveInput.y;
|
||||
float moveAmount = Mathf.Clamp01(Math.Abs(horizontal) + Math.Abs(vertical));
|
||||
|
||||
var moveInput = (new Vector3(horizontal, 0, vertical)).normalized;
|
||||
|
||||
var moveDirection = cameraController.PlanarRotation * moveInput;
|
||||
|
||||
if (!hasControl)
|
||||
return;
|
||||
|
||||
wasGrounded = isGrounded;
|
||||
GroundCheck();
|
||||
|
||||
// Phát hiện tiếp đất (Landing)
|
||||
if (isGrounded && !wasGrounded && ySpeed < -1f)
|
||||
{
|
||||
// Rung camera khi tiếp đất mạnh
|
||||
if (cameraController != null)
|
||||
{
|
||||
cameraController.Shake(0.2f, 0.15f);
|
||||
}
|
||||
}
|
||||
|
||||
if (isGrounded && ySpeed < 0)
|
||||
{
|
||||
ySpeed = -2f; // Giữ nhân vật dính xuống mặt đất
|
||||
}
|
||||
else
|
||||
{
|
||||
ySpeed += Physics.gravity.y * Time.deltaTime;
|
||||
}
|
||||
|
||||
var velocity = moveDirection * moveSpeed;
|
||||
velocity.y = ySpeed;
|
||||
|
||||
characterController.Move(velocity * Time.deltaTime);
|
||||
|
||||
if (moveAmount > 0)
|
||||
{
|
||||
targetRotation = Quaternion.LookRotation(moveDirection);
|
||||
|
||||
}
|
||||
|
||||
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
|
||||
Time.deltaTime * rotationSpeed);
|
||||
|
||||
animator.SetFloat(MoveAmount, moveAmount, animationDamping, Time.deltaTime);
|
||||
}
|
||||
|
||||
void GroundCheck()
|
||||
{
|
||||
isGrounded =
|
||||
Physics.CheckSphere(transform.TransformPoint(groundCheckOffset), groundCheckRadius, groundMask);
|
||||
}
|
||||
|
||||
public void SetControl(bool control)
|
||||
{
|
||||
this.hasControl = control;
|
||||
characterController.enabled = hasControl;
|
||||
|
||||
if (!hasControl)
|
||||
{
|
||||
animator.SetFloat(MoveAmount, 0f);
|
||||
targetRotation = transform.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = new Color(0, 1, 0, 0.5f);
|
||||
Gizmos.DrawSphere(transform.TransformPoint(groundCheckOffset), groundCheckRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd897e8bcaabdc8408bb6aaf7c037537
|
||||
@@ -1,65 +0,0 @@
|
||||
// -- SPINE PROXY 1.0 | Kevin Iglesias --
|
||||
// This script ensures correct animation display when mixing upper and lower body animations using Unity Avatar Masks.
|
||||
// Attach this script to the 'B-spineProxy' transform, which is a sibling of the 'B-hips' bone.
|
||||
// In the 'originalSpine' field, assign the 'B-spine' bone (child of 'B-hips' and parent of 'B-chest').
|
||||
// By default it will automatically find the 'B-spine' and assign it to the 'originalSpine' field (OnValidate).
|
||||
// When using a different character rig, manually assign the corresponding spine bone to the 'originalSpine' field and recreate
|
||||
// 'Rig > B-root > B-spine' structure in your character hierarchy with empty GameObjects.
|
||||
|
||||
// More information: https://www.keviniglesias.com/spine-proxy.html
|
||||
// Contact Support: support@keviniglesias.com
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace KevinIglesias
|
||||
{
|
||||
public class SpineProxy : MonoBehaviour
|
||||
{
|
||||
//Assign 'B-spine' (or equivalent) here:
|
||||
[SerializeField] private Transform originalSpine;
|
||||
|
||||
private Quaternion rotationOffset = Quaternion.identity;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//Attempting to find the original spine bone.
|
||||
void OnValidate()
|
||||
{
|
||||
if(originalSpine == null)
|
||||
{
|
||||
Transform parent = transform.parent;
|
||||
if(parent != null)
|
||||
{
|
||||
Transform hips = parent.Find("B-hips");
|
||||
if(hips != null)
|
||||
{
|
||||
Transform spine = hips.Find("B-spine");
|
||||
if(spine != null)
|
||||
{
|
||||
originalSpine = spine;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Match correct orientation on different character rigs
|
||||
void Awake()
|
||||
{
|
||||
if(originalSpine != null)
|
||||
{//originalSpine.rotation must be the default rotation in your character T-pose when this happens:
|
||||
rotationOffset = Quaternion.Inverse(transform.rotation) * originalSpine.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy rotations from spine proxy bone to the original spine bone.
|
||||
void LateUpdate()
|
||||
{
|
||||
if(originalSpine == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
originalSpine.rotation = transform.rotation * rotationOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 682245d9ac89ba4409aa3a92f17f5c6c
|
||||
@@ -60,10 +60,10 @@ MonoBehaviour:
|
||||
- folder: {fileID: 102900000, guid: 8c41df02b38b2ee40b792b146c0493f2, type: 3}
|
||||
folderIcon: {fileID: 2800000, guid: 9687b8a9002844d4b8ece997ce390043, type: 3}
|
||||
overlayIcon: {fileID: 0}
|
||||
- folder: {fileID: 102900000, guid: f2f1b47c5ca0ce34d8a018d4bf5a91d8, type: 3}
|
||||
- folder: {fileID: 102900000, guid: 4e6e9b4a0c2e35242b749c3b025c2b6d, type: 3}
|
||||
folderIcon: {fileID: 2800000, guid: 45c44e19279856a4084f599ece9e9f38, type: 3}
|
||||
overlayIcon: {fileID: 0}
|
||||
- folder: {fileID: 102900000, guid: 36bac883f43f8284d865986ec721bf93, type: 3}
|
||||
- folder: {fileID: 102900000, guid: e4342b7ac2b8c524bbfd5ed650d13a32, type: 3}
|
||||
folderIcon: {fileID: 2800000, guid: e73175098a6e2ea4db2ac2e6530f2b19, type: 3}
|
||||
overlayIcon: {fileID: 0}
|
||||
- folder: {fileID: 102900000, guid: b7be1da6c24fb324cb1b67eb7a5e6426, type: 3}
|
||||
|
||||
121
ProjectSettings/SceneTemplateSettings.json
Normal file
121
ProjectSettings/SceneTemplateSettings.json
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"templatePinStates": [],
|
||||
"dependencyTypeInfos": [
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.AnimationClip",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.Animations.AnimatorController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.AnimatorOverrideController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.Audio.AudioMixerController",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.ComputeShader",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Cubemap",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.GameObject",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.LightingDataAsset",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.LightingSettings",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Material",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.MonoScript",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.PhysicsMaterial",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.PhysicsMaterial2D",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.PostProcessing.PostProcessResources",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Rendering.VolumeProfile",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEditor.SceneAsset",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Shader",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.ShaderVariantCollection",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Texture",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Texture2D",
|
||||
"defaultInstantiationMode": 0
|
||||
},
|
||||
{
|
||||
"userAdded": false,
|
||||
"type": "UnityEngine.Timeline.TimelineAsset",
|
||||
"defaultInstantiationMode": 0
|
||||
}
|
||||
],
|
||||
"defaultDependencyTypeInfo": {
|
||||
"userAdded": false,
|
||||
"type": "<default_scene_template_dependencies>",
|
||||
"defaultInstantiationMode": 1
|
||||
},
|
||||
"newSceneOverride": 0
|
||||
}
|
||||
Reference in New Issue
Block a user