[ComponentEditorProps(category: "GameScripted/Character", description: "Erlaubt automatisches Laufen und Gehen")] class SCR_AutorunComponentClass: ScriptComponentClass { } class SCR_AutorunComponent: ScriptComponent { protected bool m_bIsAutoSprintEnabled = false; protected bool m_bIsAutoWalkEnabled = false; protected bool m_bWaitForKeyRelease = false; protected SCR_CharacterControllerComponent m_CharacterController; protected InputManager m_InputManager; protected void CheckForExistingInput(bool isEnabled) { if (isEnabled && m_InputManager.GetActionValue("CharacterForward") > 0.5) m_bWaitForKeyRelease = true; else m_bWaitForKeyRelease = false; } protected void OnAutorunPressed() { bool wasAutowalking = m_bIsAutoWalkEnabled; // Prüfen, ob wir vorher schon gegangen sind m_bIsAutoSprintEnabled = !m_bIsAutoSprintEnabled; if (m_bIsAutoSprintEnabled) m_bIsAutoWalkEnabled = false; // Sicherung nur aktivieren, wenn wir nicht direkt aus dem Autowalk kommen if (!wasAutowalking) CheckForExistingInput(m_bIsAutoSprintEnabled); else m_bWaitForKeyRelease = false; // Sauberer Übergang } protected void OnAutowalkPressed() { bool wasAutorunning = m_bIsAutoSprintEnabled; // Prüfen, ob wir vorher schon gerannt sind m_bIsAutoWalkEnabled = !m_bIsAutoWalkEnabled; if (m_bIsAutoWalkEnabled) m_bIsAutoSprintEnabled = false; if (!wasAutorunning) CheckForExistingInput(m_bIsAutoWalkEnabled); else m_bWaitForKeyRelease = false; } protected void OnLifeStateChangedCallback() { m_bIsAutoSprintEnabled = false; m_bIsAutoWalkEnabled = false; } protected void OnControlledByPlayerCallback(IEntity owner, bool controlled) { m_bIsAutoSprintEnabled = false; m_bIsAutoWalkEnabled = false; } protected void OnPrepareControlsCallback(IEntity owner, ActionManager am, float dt, bool player) { if (!m_bIsAutoSprintEnabled && !m_bIsAutoWalkEnabled) return; float forwardInput = m_InputManager.GetActionValue("CharacterForward"); float rightInput = m_InputManager.GetActionValue("CharacterRight"); if (m_bWaitForKeyRelease && forwardInput < 0.5) { m_bWaitForKeyRelease = false; } if (!m_InputManager.IsContextActive("CharacterMovementContext") || am.GetActionTriggered("GadgetMap") || Math.AbsFloat(rightInput) >= 0.75 || (!m_bWaitForKeyRelease && Math.AbsFloat(forwardInput) >= 0.75)) { m_bIsAutoSprintEnabled = false; m_bIsAutoWalkEnabled = false; return; } // Bewegung immer erzwingen m_InputManager.SetActionValue("CharacterForward", 1.0); // Explizit sagen: Sprint AN oder Sprint AUS if (m_bIsAutoSprintEnabled) m_InputManager.SetActionValue("CharacterSprint", 1.0); else m_InputManager.SetActionValue("CharacterSprint", 0.0); // Verhindert, dass der Sprint stecken bleibt! } override void OnPostInit(IEntity owner) { m_CharacterController = SCR_CharacterControllerComponent.Cast(owner.FindComponent(SCR_CharacterControllerComponent)); if (!m_CharacterController) return; m_InputManager = GetGame().GetInputManager(); m_CharacterController.m_OnPrepareControls.Insert(OnPrepareControlsCallback); m_InputManager.AddActionListener("SCR_Autorun", EActionTrigger.DOWN, OnAutorunPressed); m_InputManager.AddActionListener("SCR_Autowalk", EActionTrigger.DOWN, OnAutowalkPressed); } }