necroview: камера под интерфейсом; режим free - выйти из тела
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
606f9c3816
commit
87fad62c62
+96
-2
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using HarmonyLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Scripting;
|
using UnityEngine.Scripting;
|
||||||
|
|
||||||
@@ -29,6 +30,61 @@ namespace NecromancerTome
|
|||||||
static Quaternion _lockCam;
|
static Quaternion _lockCam;
|
||||||
static bool _mouseBroken;
|
static bool _mouseBroken;
|
||||||
|
|
||||||
|
/// <summary>«Выйти из тела» (16.10: «временно мог выйти из тела, когда попрошу? Чтобы мог ходить вокруг тела и
|
||||||
|
/// осматривать»): камера летает свободно - WASD, мышь, пробел/Ctrl - выше/ниже, Shift - быстрее; тело стоит
|
||||||
|
/// (PlayerMoveController.Update пропускается, как при одержимости), поза рук замерла. Выход - End или necroview off.</summary>
|
||||||
|
public static bool Free;
|
||||||
|
static Vector3 _freePos;
|
||||||
|
static float _freeYaw, _freePitch;
|
||||||
|
const float FlySpeed = 1.5f;
|
||||||
|
|
||||||
|
public static string StartFree()
|
||||||
|
{
|
||||||
|
string r = Start(0f, 0f, 0.6f);
|
||||||
|
Transform pc = HandPose.Camera();
|
||||||
|
if (!On || pc == null)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
Free = true;
|
||||||
|
_freePos = pc.position;
|
||||||
|
Vector3 e = pc.eulerAngles;
|
||||||
|
_freeYaw = e.y;
|
||||||
|
_freePitch = e.x > 180f ? e.x - 360f : e.x;
|
||||||
|
return "вне тела: WASD, мышь, пробел/Ctrl - выше/ниже, Shift - быстрее, End - вернуться";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateFree(float _dt)
|
||||||
|
{
|
||||||
|
PlayerMoveController pmc = PlayerMoveController.Instance;
|
||||||
|
Vector2 sens = pmc != null ? pmc.mouseLookSensitivity : Vector2.one * 5f;
|
||||||
|
if (!_mouseBroken)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_freeYaw += Input.GetAxis("Mouse X") * sens.x;
|
||||||
|
_freePitch = Mathf.Clamp(_freePitch - Input.GetAxis("Mouse Y") * sens.y, -89f, 89f);
|
||||||
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
_mouseBroken = true;
|
||||||
|
Debug.LogWarning("[NecromancerTome] necroview: мышь не читается (" + e.Message + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Quaternion rot = Quaternion.Euler(_freePitch, _freeYaw, 0f);
|
||||||
|
Vector3 move = Vector3.zero;
|
||||||
|
if (Input.GetKey(KeyCode.W)) move += Vector3.forward;
|
||||||
|
if (Input.GetKey(KeyCode.S)) move += Vector3.back;
|
||||||
|
if (Input.GetKey(KeyCode.A)) move += Vector3.left;
|
||||||
|
if (Input.GetKey(KeyCode.D)) move += Vector3.right;
|
||||||
|
Vector3 world = rot * move;
|
||||||
|
if (Input.GetKey(KeyCode.Space)) world += Vector3.up;
|
||||||
|
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.C)) world += Vector3.down;
|
||||||
|
float speed = FlySpeed * (Input.GetKey(KeyCode.LeftShift) ? 4f : 1f);
|
||||||
|
_freePos += world * speed * _dt;
|
||||||
|
_cam.transform.SetPositionAndRotation(_freePos, rot);
|
||||||
|
}
|
||||||
|
|
||||||
public static string Start(float _yaw, float _pitch, float _dist)
|
public static string Start(float _yaw, float _pitch, float _dist)
|
||||||
{
|
{
|
||||||
Transform pc = HandPose.Camera();
|
Transform pc = HandPose.Camera();
|
||||||
@@ -50,7 +106,16 @@ namespace NecromancerTome
|
|||||||
_cam = go.AddComponent<Camera>();
|
_cam = go.AddComponent<Camera>();
|
||||||
}
|
}
|
||||||
_cam.CopyFrom(pl.playerCamera);
|
_cam.CopyFrom(pl.playerCamera);
|
||||||
_cam.depth = pl.playerCamera.depth + 50f;
|
// Сразу над камерой игрока, но ПОД камерами интерфейса (16.10: с +50 рисовала поверх меню - «мне из игры не выйти даже»).
|
||||||
|
float above = float.MaxValue;
|
||||||
|
foreach (Camera c in Camera.allCameras)
|
||||||
|
{
|
||||||
|
if (c != _cam && c.depth > pl.playerCamera.depth && c.depth < above)
|
||||||
|
{
|
||||||
|
above = c.depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_cam.depth = above < float.MaxValue ? (pl.playerCamera.depth + above) * 0.5f : pl.playerCamera.depth + 1f;
|
||||||
_cam.nearClipPlane = 0.01f;
|
_cam.nearClipPlane = 0.01f;
|
||||||
_cam.gameObject.SetActive(true);
|
_cam.gameObject.SetActive(true);
|
||||||
HandPose.HoldStill = true;
|
HandPose.HoldStill = true;
|
||||||
@@ -63,6 +128,7 @@ namespace NecromancerTome
|
|||||||
public static void Stop()
|
public static void Stop()
|
||||||
{
|
{
|
||||||
On = false;
|
On = false;
|
||||||
|
Free = false;
|
||||||
HandPose.HoldStill = false;
|
HandPose.HoldStill = false;
|
||||||
if (_cam != null)
|
if (_cam != null)
|
||||||
{
|
{
|
||||||
@@ -85,6 +151,16 @@ namespace NecromancerTome
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float dt = Time.unscaledDeltaTime;
|
float dt = Time.unscaledDeltaTime;
|
||||||
|
if (Free)
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(KeyCode.End))
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateFree(dt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
EntityPlayerLocal pl = GameManager.Instance?.World?.GetPrimaryPlayer();
|
EntityPlayerLocal pl = GameManager.Instance?.World?.GetPrimaryPlayer();
|
||||||
if (Mouse && pl != null && !_mouseBroken)
|
if (Mouse && pl != null && !_mouseBroken)
|
||||||
{
|
{
|
||||||
@@ -128,7 +204,7 @@ namespace NecromancerTome
|
|||||||
public class ConsoleCmdNecroView : ConsoleCmdAbstract
|
public class ConsoleCmdNecroView : ConsoleCmdAbstract
|
||||||
{
|
{
|
||||||
public override string[] getCommands() => new[] { "necroview" };
|
public override string[] getCommands() => new[] { "necroview" };
|
||||||
public override string getDescription() => "NecromancerTome: осмотр рук со стороны - on [вокруг высота расстояние]|off|set вокруг высота расстояние|mouse [off]|show; мышь или цифровой блок 4/6 8/2 +/- 5";
|
public override string getDescription() => "NecromancerTome: осмотр рук со стороны - on [вокруг высота расстояние]|off|set вокруг высота расстояние|free (выйти из тела, End - назад)|mouse [off]|show; мышь или цифровой блок 4/6 8/2 +/- 5";
|
||||||
|
|
||||||
static bool Num(List<string> _p, int _i, out float _v)
|
static bool Num(List<string> _p, int _i, out float _v)
|
||||||
{
|
{
|
||||||
@@ -159,6 +235,9 @@ namespace NecromancerTome
|
|||||||
NecroView.Pitch = p2;
|
NecroView.Pitch = p2;
|
||||||
NecroView.Dist = d2;
|
NecroView.Dist = d2;
|
||||||
break;
|
break;
|
||||||
|
case "free":
|
||||||
|
Out(NecroView.StartFree());
|
||||||
|
return;
|
||||||
case "mouse":
|
case "mouse":
|
||||||
NecroView.Mouse = !(_params.Count > 1 && _params[1] == "off");
|
NecroView.Mouse = !(_params.Count > 1 && _params[1] == "off");
|
||||||
Out("мышь " + (NecroView.Mouse ? "облетает руки" : "крутит персонажа, облёт - цифровой блок"));
|
Out("мышь " + (NecroView.Mouse ? "облетает руки" : "крутит персонажа, облёт - цифровой блок"));
|
||||||
@@ -172,4 +251,19 @@ namespace NecromancerTome
|
|||||||
Out(NecroView.On ? "вокруг " + NecroView.F(NecroView.Yaw) + ", высота " + NecroView.F(NecroView.Pitch) + ", расстояние " + NecroView.F(NecroView.Dist) : "осмотр выключен");
|
Out(NecroView.On ? "вокруг " + NecroView.F(NecroView.Yaw) + ", высота " + NecroView.F(NecroView.Pitch) + ", расстояние " + NecroView.F(NecroView.Dist) : "осмотр выключен");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Вне тела (NecroView.Free) тело не ходит и не крутится - как при одержимости.</summary>
|
||||||
|
[HarmonyPatch(typeof(PlayerMoveController), nameof(PlayerMoveController.Update))]
|
||||||
|
public static class Patch_PlayerMoveController_Update_NecroView
|
||||||
|
{
|
||||||
|
public static bool Prefix(PlayerMoveController __instance)
|
||||||
|
{
|
||||||
|
if (!NecroView.Free)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
__instance.stopMoving();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user