using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ThirdPersonMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("第三人称相机mod")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a4ba00dda8158de92c3c4f8e568fd467b16de89d")]
[assembly: AssemblyProduct("ThirdPersonMod")]
[assembly: AssemblyTitle("ThirdPersonMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace ThirdPersonMod
{
[BepInPlugin("camera.patcher.mod", "ThirdPersonMod", "1.0.0")]
public class CameraPlugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<float> Sensitivity;
internal static ConfigEntry<float> CamDist;
internal static ConfigEntry<float> OffsetX;
internal static ConfigEntry<float> OffsetY;
internal static ConfigEntry<float> ConvergeDist;
internal static ConfigEntry<float> RayOriginPush;
private void Awake()
{
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Sensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "鼠标灵敏度", 0.12f, "每像素鼠标位移对应的转向速度");
CamDist = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "相机距离", 1.4f, "第三人称相机与角色的距离(米)");
OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "水平偏移", -0.6f, "相机向左偏移量,越负人物越靠屏幕右侧");
OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("相机", "垂直偏移", 0.4f, "相机向上偏移量,越大人物越靠屏幕下方");
ConvergeDist = ((BaseUnityPlugin)this).Config.Bind<float>("瞄准", "汇聚距离", 40f, "准星线汇聚到视轴的距离(米),一般不用改");
RayOriginPush = ((BaseUnityPlugin)this).Config.Bind<float>("瞄准", "射线校正", 0.3f, "拾取手感微调:捡近处物品差一点点就加大");
new Harmony("camera.patcher.mod").PatchAll();
RenderPipelineManager.beginCameraRendering += delegate
{
PatchThirdPerson.EnsureBodyVisible();
};
Log.LogInfo((object)"[ThirdPersonMod] 加载完成,B键切换第一/第三人称");
}
}
public static class PluginInfo
{
public const string GUID = "camera.patcher.mod";
public const string Name = "ThirdPersonMod";
public const string Version = "1.0.0";
}
[HarmonyPatch]
public static class PatchThirdPerson
{
public class CamState
{
public bool thirdPerson;
public float yaw;
public float pitch = 12f;
public float dist;
}
private static Type _cameraType;
private static FieldInfo _followField;
private static MethodBase _target;
private static readonly Dictionary<Component, CamState> _states = new Dictionary<Component, CamState>();
private static int? _origMask;
private static Transform _cachedRoot;
private static Renderer[] _cachedRenderers;
private static readonly Dictionary<Renderer, ShadowCastingMode> _origShadowModes = new Dictionary<Renderer, ShadowCastingMode>();
public static CamState CurrentState { get; private set; }
public static Transform CurrentFollow { get; private set; }
public static Vector3 EyeOffset { get; private set; } = Vector3.up * 1.55f;
public static Type FindCameraType()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
Type[] types;
try
{
types = assembly.GetTypes();
}
catch
{
continue;
}
Type[] array = types;
foreach (Type type in array)
{
if (type.Name == "ExampleCharacterCamera")
{
return type;
}
}
}
return null;
}
private static bool Prepare()
{
_cameraType = FindCameraType();
if (_cameraType == null)
{
return false;
}
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fields = _cameraType.GetFields(bindingAttr);
foreach (FieldInfo fieldInfo in fields)
{
if (!(fieldInfo.FieldType != typeof(Transform)))
{
if (fieldInfo.Name.Contains("Follow"))
{
_followField = fieldInfo;
break;
}
if (_followField == null)
{
_followField = fieldInfo;
}
}
}
_target = _cameraType.GetMethod("UpdateWithInput", bindingAttr) ?? _cameraType.GetMethod("Update", bindingAttr) ?? _cameraType.GetMethod("LateUpdate", bindingAttr);
return _target != null;
}
private static MethodBase TargetMethod()
{
return _target;
}
public static void EnsureBodyVisible()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Invalid comparison between Unknown and I4
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
CamState currentState = CurrentState;
Transform currentFollow = CurrentFollow;
if (currentState == null || (Object)(object)currentFollow == (Object)null || !currentState.thirdPerson)
{
return;
}
Transform root = currentFollow.root;
if (_cachedRenderers == null || (Object)(object)_cachedRoot != (Object)(object)root)
{
_cachedRoot = root;
_cachedRenderers = ((Component)root).GetComponentsInChildren<Renderer>(true);
}
Renderer[] cachedRenderers = _cachedRenderers;
foreach (Renderer val in cachedRenderers)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
if (!_origShadowModes.TryGetValue(val, out var _))
{
_origShadowModes[val] = val.shadowCastingMode;
}
if ((int)val.shadowCastingMode != 1)
{
val.shadowCastingMode = (ShadowCastingMode)1;
}
SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
if (val2 != null && !((Component)val2).gameObject.activeInHierarchy)
{
((Component)val2).gameObject.SetActive(true);
Transform parent = ((Component)val2).transform.parent;
while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root && !((Component)parent).gameObject.activeInHierarchy)
{
((Component)parent).gameObject.SetActive(true);
parent = parent.parent;
}
}
}
}
private static string GetPath(Transform t)
{
string text = ((Object)t).name;
while ((Object)(object)t.parent != (Object)null)
{
t = t.parent;
text = ((Object)t).name + "/" + text;
}
return text;
}
private static void Postfix(Component __instance)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0214: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
//IL_030a: Unknown result type (might be due to invalid IL or missing references)
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_031b: Unknown result type (might be due to invalid IL or missing references)
//IL_031d: Unknown result type (might be due to invalid IL or missing references)
//IL_0322: Unknown result type (might be due to invalid IL or missing references)
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0349: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0358: Unknown result type (might be due to invalid IL or missing references)
//IL_035a: Unknown result type (might be due to invalid IL or missing references)
//IL_035e: Unknown result type (might be due to invalid IL or missing references)
//IL_0363: Unknown result type (might be due to invalid IL or missing references)
//IL_0368: Unknown result type (might be due to invalid IL or missing references)
//IL_036a: Unknown result type (might be due to invalid IL or missing references)
//IL_036f: Unknown result type (might be due to invalid IL or missing references)
//IL_0371: Unknown result type (might be due to invalid IL or missing references)
//IL_0373: Unknown result type (might be due to invalid IL or missing references)
//IL_0375: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0380: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0397: Unknown result type (might be due to invalid IL or missing references)
//IL_039c: Unknown result type (might be due to invalid IL or missing references)
//IL_0408: Unknown result type (might be due to invalid IL or missing references)
//IL_040a: Unknown result type (might be due to invalid IL or missing references)
//IL_040e: Unknown result type (might be due to invalid IL or missing references)
//IL_0413: Unknown result type (might be due to invalid IL or missing references)
//IL_0418: Unknown result type (might be due to invalid IL or missing references)
//IL_041a: Unknown result type (might be due to invalid IL or missing references)
//IL_0426: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
if (_followField == null)
{
return;
}
Mouse current = Mouse.current;
Keyboard current2 = Keyboard.current;
if (current == null || current2 == null || (int)Cursor.lockState != 1)
{
return;
}
object? value = _followField.GetValue(__instance);
Transform val = (Transform)((value is Transform) ? value : null);
if ((Object)(object)val == (Object)null)
{
return;
}
if (!_states.TryGetValue(__instance, out var value2))
{
value2 = new CamState
{
yaw = __instance.transform.eulerAngles.y,
dist = CameraPlugin.CamDist.Value
};
_states[__instance] = value2;
CameraPlugin.Log.LogInfo((object)("[ThirdPersonMod] 已接管相机(B键切换),锚定: " + ((Object)val).name));
}
CurrentState = value2;
CurrentFollow = val;
Camera component = __instance.GetComponent<Camera>();
if ((Object)(object)component != (Object)null && !_origMask.HasValue)
{
_origMask = component.cullingMask;
}
if (((ButtonControl)current2.bKey).wasPressedThisFrame)
{
value2.thirdPerson = !value2.thirdPerson;
CameraPlugin.Log.LogInfo((object)(value2.thirdPerson ? "[ThirdPersonMod] 第三人称" : "[ThirdPersonMod] 第一人称"));
if (value2.thirdPerson)
{
Vector3 eulerAngles = __instance.transform.eulerAngles;
value2.yaw = eulerAngles.y;
value2.pitch = ((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x);
}
}
Renderer[] cachedRenderers;
if (!value2.thirdPerson)
{
if ((Object)(object)component != (Object)null && _origMask.HasValue)
{
component.cullingMask = _origMask.Value;
}
EyeOffset = __instance.transform.position - val.position;
if (_cachedRenderers == null)
{
return;
}
cachedRenderers = _cachedRenderers;
foreach (Renderer val2 in cachedRenderers)
{
if ((Object)(object)val2 != (Object)null && _origShadowModes.TryGetValue(val2, out var value3))
{
val2.shadowCastingMode = value3;
}
}
return;
}
Vector2 val3 = ((InputControl<Vector2>)(object)((Pointer)current).delta).ReadValue();
value2.yaw += val3.x * CameraPlugin.Sensitivity.Value;
value2.pitch = Mathf.Clamp(value2.pitch - val3.y * CameraPlugin.Sensitivity.Value, -35f, 70f);
value2.dist = CameraPlugin.CamDist.Value;
int num = 1 << ((Component)val).gameObject.layer;
cachedRenderers = ((Component)val).GetComponentsInChildren<Renderer>(true);
foreach (Renderer val4 in cachedRenderers)
{
num |= 1 << ((Component)val4).gameObject.layer;
}
if ((Object)(object)component != (Object)null)
{
component.cullingMask = (_origMask ?? component.cullingMask) | num;
}
Transform transform = __instance.transform;
Quaternion val5 = Quaternion.Euler(value2.pitch, value2.yaw, 0f);
Vector3 val6 = val.position + EyeOffset;
Vector3 val7 = val5 * Vector3.back;
Vector3 val8 = val5 * new Vector3(CameraPlugin.OffsetX.Value, CameraPlugin.OffsetY.Value, 0f);
float num2 = value2.dist;
Vector3 val9 = val6 + val7 * num2 + val8;
Vector3 val10 = val9 - val6;
RaycastHit[] array = Physics.RaycastAll(val6, ((Vector3)(ref val10)).normalized, num2);
for (int i = 0; i < array.Length; i++)
{
RaycastHit val11 = array[i];
if (!((RaycastHit)(ref val11)).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref val11)).collider).transform == (Object)(object)val) && !((Component)((RaycastHit)(ref val11)).collider).transform.IsChildOf(val))
{
num2 = Mathf.Min(num2, ((RaycastHit)(ref val11)).distance);
}
}
num2 = Mathf.Max(num2 - 0.05f, 0.25f);
transform.position = val6 + val7 * num2 + val8;
transform.rotation = val5;
EnsureBodyVisible();
}
}
[HarmonyPatch(typeof(PlayerInteraction), "InteractionRay")]
public static class PatchInteractionRay
{
private static bool _moved;
private static Vector3 _pos;
private static Quaternion _rot;
private static Camera _gameCam;
private static Camera GetGameCamera()
{
if ((Object)(object)_gameCam != (Object)null)
{
return _gameCam;
}
PlayerInteraction val = Object.FindObjectOfType<PlayerInteraction>();
if ((Object)(object)val != (Object)null)
{
object? obj = typeof(PlayerInteraction).GetField("mainCamera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val);
_gameCam = (Camera)((obj is Camera) ? obj : null);
}
if ((Object)(object)_gameCam == (Object)null)
{
_gameCam = Camera.main;
}
return _gameCam;
}
private static void Prefix()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
PatchThirdPerson.CamState currentState = PatchThirdPerson.CurrentState;
Transform currentFollow = PatchThirdPerson.CurrentFollow;
if (currentState != null && !((Object)(object)currentFollow == (Object)null) && currentState.thirdPerson)
{
Camera gameCamera = GetGameCamera();
if (!((Object)(object)gameCamera == (Object)null))
{
_pos = ((Component)gameCamera).transform.position;
_rot = ((Component)gameCamera).transform.rotation;
Quaternion val = Quaternion.Euler(currentState.pitch, currentState.yaw, 0f);
Vector3 val2 = currentFollow.position + PatchThirdPerson.EyeOffset;
Vector3 val3 = val2 + val * Vector3.forward * CameraPlugin.ConvergeDist.Value - _pos;
Vector3 normalized = ((Vector3)(ref val3)).normalized;
float num = Vector3.Distance(_pos, val2) + CameraPlugin.RayOriginPush.Value;
((Component)gameCamera).transform.SetPositionAndRotation(_pos + normalized * num, Quaternion.LookRotation(normalized));
_moved = true;
}
}
}
private static void Postfix()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (_moved)
{
Camera gameCamera = GetGameCamera();
if ((Object)(object)gameCamera != (Object)null)
{
((Component)gameCamera).transform.SetPositionAndRotation(_pos, _rot);
}
_moved = false;
}
}
}
}